Does it support css source maps like https://github.com/zeit/styled-jsx ?
Yes, it should. If you have source maps set up however you use css today then it will work.
Do you have an example?
If you are using webpack then the css loader docs handle this quite well. https://github.com/webpack-contrib/css-loader
I have updated the example to use sourcemaps in dev and prod. (https://github.com/tkh44/emotion/blob/master/example/webpack.config.js#L19)
Looking at your question though, source maps may mean something different to us. I couldn't find anything about it on their readme.
Well yes it's something different - I am not talking about styles from .css files but about styles from.jsxstyles.
It basically shows you the line in the jsx file a css file is coming from:

More details can be seen here: https://github.com/zeit/styled-jsx/pull/34
Ahh I see now. @threepointone this is a cool idea for glam, no?
I'm down for this, open to PRs
@sidorares do you have time to copy your solution to this project?
@jantimon I'll have a look over weekend!
bump!
This sounds like a great idea - didn't know any css-in-js (styled-jsx) supports it ^^
I think we have all the pieces now to do this now that we pass the AST path into our parser. This should give us a way to tell postcss which lines and columns the node is actually on in the js file.
cc @mitchellhamilton
I'll try to write down here what needs to be added:
1) capture expression loc somewhere here and pass it to parseCSS as extra parameter
https://github.com/tkh44/emotion/blob/844b44903da71e982fcf5014c1d7be3619474f54/src/babel.js#L50
2) PostCSS parser tracks it's own line and column starting from 1:1 in node.start and node.end
we probably need to pass custom stringifier to node at https://github.com/tkh44/emotion/blob/844b44903da71e982fcf5014c1d7be3619474f54/src/parser.js#L71 ( node.toString accepts stringifier as a parameter ) Stringifier should build sourcemap
3) Append inline sourcemap to resulting css ( I'm using https://github.com/thlorenz/convert-source-map for this:
const generator = new SourceMapGenerator({
file: filename,
sourceRoot: state.file.opts.sourceRoot
})
generator.setSourceContent(filename, state.file.code)
//...
const css = [node.toString(new Stringifier(generator))
convert.fromObject(generator)
.toComment({multiline: true}),
`/*@ sourceURL=${filename} */`].join('\n')
I've played around with this before and I think we could do it for extracted CSS (assuming css-loader and stuff accept source maps) but I'm not sure how we could do it for dynamic CSS since from what I found browsers only look at the last source map in the file/element so we would have to insert a style element per css call.
do you mean webpack css-loader?
webpack css-loader accepts source maps: https://github.com/tkh44/emotion/blob/567c83245af6c70d3a6e8985b15ef7015f4c44e0/example/webpack.config.js#L37-L49
for dynamic parts of emotion:
const avatarStyle = css` composes: ${imageBase}; border: 1px solid #7519E5Internally emotion will append these css classes to the generated one. avatarStyle from above > would generate a class name like css-imageBase-12345 css-avatarStyle-12345 This allows for some really powerful composition that really shines with styled.
In this case the source map of css-imageBase-12345 should point to the javascript declaration of imageBase and css-avatarStyle-12345 should point to avatarStyle
for dynamic parts in terms of webpack:
webpack already supports dynamically updating css source maps but you might be right that we would have to inject multiple style elements if sourceMaps are enabled
What I meant about css-loader accepting source maps is a source map being in the imported css and css-loader using it, I'm assuming that's supported but this isn't the main problem.
To the composes bit, we don't append classes anymore, instead we merge the styles themselves.
The main problem with this isn't generating the source maps, that should be easy, the hard part is inserting them because we would have to insert a new style element for each rule which would be expensive(I know it would only be in dev). The other problem is that we would have to add a way to insert the source maps into the css calls that can be easily disabled and not have an effect in production. I personally don't think source maps would be worth it for the added complexity.
I know this task is quite challenging and it took other projects (e.g. sass) quite some time to get this done but it has become the standard for css tooling and I personally would not want to go back to the past where we had no source maps.
You can easily merge multiple css sources using PostCss.
PostCss will handle all source maps for you automatically.
Sure you can that this technology is to hard to develop and maintain for you in your project.
That's a totally valid conclusion but hopefully you will make it work some how :)
@mitchellhamilton i've always wanted source maps for everything, especially in production. That would only work when they can be saved to external .map files and have the original source included, though. I usually deploy all source maps to production and restrict access to them to my own/companies ip address range and the ip addresses provided by the error logging SaaS of choice so they can work with sourcemapped stacktraces. to the normal user, the only thing that is added to the download is a sourcemap comment that points to a file not accessible by him. Emotion is great as-is, but adding sourcemap support at least for static styles would be icing on the cake :)
Most helpful comment
Well yes it's something different - I am not talking about styles from
.cssfiles but about styles from.jsxstyles.It basically shows you the line in the jsx file a css file is coming from:
More details can be seen here: https://github.com/zeit/styled-jsx/pull/34