styled-components / babel-plugin-styled-components

Improve the debugging experience and add server-side rendering support to styled-components
MIT License
1.08k stars 141 forks source link

Add source map support? #14

Open mxstbr opened 7 years ago

mxstbr commented 7 years ago

We should add support for source mapping, similar to https://github.com/zeit/styled-jsx/pull/34/files

What do you think, is that feasible?

vdanchenkov commented 7 years ago

@mxstbr Looks really interesting. I definitely would like to have an easy way to jump to component definition right from the style on elements panel. But I have no experience with source maps and will have no time for it in this year.

mxstbr commented 7 years ago

No worries, me neither πŸ˜‰ let's put that on the backlog, maybe once we officially launch this a sourcemap expert jumps into the conversation!

edorivai commented 7 years ago

Are there any updates, or plans on this?

mxstbr commented 7 years ago

Feel free to go ahead and implement this @edorivai, nobody's working on it at the minute I don't think!

edorivai commented 7 years ago

Hey @mxstbr, we were considering switching to styled-components, and source map support was one of the questions of the team. We decided not to switch, but might use it in new projects/features. When we do I might take this issue on, but right now I don't have the time :disappointed:.

tz5514 commented 7 years ago

Really hope this feature can be implemented....with source map supporting, styled-components will be almost perfectly.

ImanMh commented 7 years ago

I want to switch one of the biggest Food Delivery startups in Iran to styled components but not having source maps is the reason I'm hesitating. Could you give me an update about the status of this feature or a rough estimate of it's release date?

mxstbr commented 7 years ago

You can calculate the release date with a simple formula:

release date
= time when a person starts working on this feature
+ time it takes that person to finish this feature

So I guess you better get going? πŸ˜‰ (that's a snarky way of saying nobody's working on this right now because we all have full-time jobs but we'd love to have it so if you want to contribute to the ecosystem that's a great start and will make tons of peoples lives better!)

ImanMh commented 7 years ago

First I need to make sure it's on the road map. Sure I would like to work on it but first I need to know how to do this since I never wrote a source map maker for any project. If you have information about where this info can be found please let me know.

mxstbr commented 7 years ago

See here for some starter pointers: https://github.com/styled-components/styled-components/issues/827#issue-231139547

Definitely on the roadmap, again we'd love to have this!

kitten commented 7 years ago

Preprocessing will change btw (part of the babel plugin might not make it into v3). so don't focus on that too much :)

But if you did, that'd also be helpful since I don't know much about source mapping either ^^ thanks

quantizor commented 7 years ago

@tkh44 recently did this for emotion if a potential contributor needs some inspiration: https://github.com/emotion-js/emotion/pull/320

lumio commented 7 years ago

Is anyone already working on that? Otherwise I might look into that the next few weeks

kitten commented 7 years ago

@lumio Hiya, no one is working on it yet afaik, so it’s be great if you can lend us a hand πŸ˜€

mxstbr commented 7 years ago

@lumio yes please!! :tada:

selrond commented 6 years ago

@lumio have you come up with something?

lumio commented 6 years ago

@selrond sadly not - I haven't had enough time to actually dig into this

yiochen commented 6 years ago

I looked into this issue a bit, here is some food for thought:

disclaimer: I have never worked with source map before, correct me if you found anything wrong.

The idea of source map is very simple. it maps line and column numbers of the generated content into the line and column numbers of the original source content. Source map is not a character by character mapping. It only maps the interesting part of the source. For JavaScript, identifiers are some interesting information, like variable names, function names. for example

// original
function count() {}

// generated
function c() {}

Source map will map the position of c to the position of count. But there isn't much value to map the comments.

For styled-component, the source content is our js file, and the generated content are the <style> tags in the html.

In the context of CSS, we are probably not going to set breakpoints or step through CSS code. What we want is just the ability to go from devtool style tab to the JavaScript source file that generates this style.

screen shot 2018-09-29 at 2 16 21 pm

So the only mapping we need is just the mapping from the beginning of the <style> tag to where the styled-component is defined (this is also what emotion does).

Some other CSS source maps, like sass source map, provide mapping for each CSS property. I think it will be hard for CSS in js, due to how dynamically we can change our generated CSS in runtime.

To add a reference to a source map, we just need to add a comment in the style tag:

screen shot 2018-09-29 at 2 26 13 pm

In the screenshot above, the base 64 encoded string contains the information for the mapping, the source file name, and the source content, etc.

The source map can also be externalized into a separated file xxx.map, which browser will load only when we open the devtool.

This source map comment is all it takes for browsers to figure out what the mapping is, and what the original content is.

The problem I have is the source content. the inline comment needs to embed the whole js file (otherwise how would we show the original source in devtool). Because we normally don't ship the original JavaScript source to the client side. Instead of embedding the whole source content in the source map, the source map spec allows specifying a URL for browsers to load the original source. But this requires additional setup for users, to serve their original JavaScript in the server.

The original source is just the JavaScript, and we probably already have them embedded in the js source map when we uglify our js files. It would be nice if we could reuse the source content from other source maps, but I haven't found a way to do that.

Another issue is, normally the generated file is static. If we have a minified js file, it is not going to change when we run it. But the content of <style> tag will change (and this is the power of styled-component). This means, our line/column mappings might get outdated once our style changes.

I think emotion solved this problem by splitting each class into separated <style> tags, and for each <style> tag, add an inline sourcemap content. The mapping always maps the first line, the first column of style block to the JS file, so it doesn't matter how we change it. But if we define 5 components in one js file, the same file content is duplicated 5 times in the source map. That's a lot of duplicated data sent down client's wire. This might be the reason they don't want people using source map in production https://emotion.sh/docs/source-maps

I personally really hope we can provide source map in production. There are some options I think worth looking into:

  1. Is there a way to share source content in multiple source maps?
  2. Maybe we can dynamically generate source maps on the fly? does that means we need to ship source-map package to the client?
  3. We don't have to provide the original source content in the source map. We can totally fake it, maybe in the source map, we embed original content as For the code that generated this style, take a look at XXX.js line XXX sourcemap

Let me know what you all think. I am happy to dig deeper into it.

Edit: a simple CSS source map demo to play with: https://codesandbox.io/s/github/yiochen/source-map-test/tree/master/

mxstbr commented 6 years ago

I think development-only would be a great first step for a lot of people, and then we can work on making them work in production!

yiochen commented 6 years ago

Sounds good. I will take a stab at implementing a development only solution.

mxstbr commented 6 years ago

Awesome @yiochen! Let us know if you get stuck anywhere and need our help

selrond commented 6 years ago

@yiochen how's it going?

yiochen commented 6 years ago

It is going well. I am making progress slowly since I only have time to work on it during weekends. For the two parts of work, 1. Adding support of sourcemap comment in styled-components repo is mostly done. 2. Make babel plugin add sourcemap comment. This one is working in progress.

jmocana2 commented 5 years ago

Hi @yiochen,

You finally got to develop the source map. It becomes very heavy to have to constantly use the vscode search engine to find a styled component.

paul-vd commented 4 years ago

Bump, any news on the progress here?

quantizor commented 4 years ago

Not at the moment, I think things will have to be redone a bit for v5 since a lot of the library code was rewritten

On Tue, Feb 4, 2020 at 4:05 PM Paul van Dyk notifications@github.com wrote:

Bump, any news on the progress here?

β€” You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/styled-components/babel-plugin-styled-components/issues/14?email_source=notifications&email_token=AAELFVRHQKEK6DTREHXVE73RBHKDBA5CNFSM4CZ7UPMKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKZF3PY#issuecomment-582114751, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAELFVXKALHUYXXS5CT4BQDRBHKDBANCNFSM4CZ7UPMA .

zbeyens commented 4 years ago

It would be great so I can use Devsync (a chrome extension to edit CSS) that needs sourcemaps to work.

selrond commented 4 years ago

@yiochen if needed, I could help you probably. Ping me if so