-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a babel-macro #2032
Add a babel-macro #2032
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't have time to review right now but thanks so much for picking this up! I'll defer to @probablup for an actual code review, I'd love to land this in v4 to be compatible with create-react-app v2!
Let's add a test case to verify that all helpers exported by |
I've added a test for that here : styled-components/src/macro/test/macro.test.js Lines 64 to 70 in 7992c61
|
With the current implementation, that's the way it works : import styled, { css, keyframes, injectGlobal, ThemeProvider } from 'styled-components/macro'
// do things with imports
css`...`
keyframes`...`
injectGlobal`...`
styled.div`...`
<ThemeProvider /> It will get transpiled to something like this (just focusing on what the macro does, not the other babel plugins) : import _styled, {
css as _css,
keyframes as _keyframes,
injectGlobal as _injectGlobal,
ThemeProvider as _ThemeProvider
} from 'styled-components'
_css()
_keyframes()
// lighter precompiled versions
_injectGlobal`...`
// not modified because babel-plugin-styled-components keeps it like this
_styled.div.withConfig({ displayName: '' })()
// adds withConfig (displayName, ...) and use the lighter version
<_ThemeProvider />
// kept like this, just moved the import from styled-components/macro to styled-components
|
@probablyup |
I added just enough flow types for If someone knows Flow, I'd love some advice on the flow types in this PR 😬 Otherwise, I think the PR is ready for review 😀 |
@lucleray could you provide me with a testing guide? I don't use CRA so not sure how to go about making sure this works (and continues to work) |
I created an example repo here : https://github.com/lucleray/cra-styled-components First, you need to set it up.
Once this is set up, you can test if the macro does the right thing. I added two styled components in Run cra :
Then you can check that the code is correctly transpiled :
I look for the main chunk ( var StyledDiv = styled_components__WEBPACK_IMPORTED_MODULE_5__["default"].div.withConfig({
displayName: "App__StyledDiv",
componentId: "sc-19hhnfk-0"
})(["background:red;padding:5px;margin-top:1em;border-radius:5px;"]); Similarly, I search for var StyledNoMacroDiv = styled_components__WEBPACK_IMPORTED_MODULE_6__["default"].div(_templateObject()); |
The example repo was quite easy to setup :
And this is all you need to do to start using CRA + styled-components once this macro will be added to styled-components 🔥 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The base of this also needs to be switched to "develop"
src/macro/index.js
Outdated
import templateLiteral from 'babel-plugin-styled-components/lib/visitors/templateLiterals/index' | ||
import pureAnnotation from 'babel-plugin-styled-components/lib/visitors/pure' | ||
|
||
const taggedTemplateImports = ['css', 'keyframes', 'injectGlobal', 'default'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to add createGlobalStyle
and injectGlobal
is no longer a thing in v4 so it can be removed
src/macro/index.js
Outdated
'keyframes', | ||
'injectGlobal', | ||
'isStyledComponent', | ||
'consolidateStreamedStyles', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is removed
src/macro/index.js
Outdated
// merge config into the state | ||
const stateWithOpts = { ...state, opts: config } | ||
// run babel-plugin-styled-components appropriate visitors | ||
minify(t)(templatePath, stateWithOpts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to reuse the setup from the babel plugin wholesale instead of having to recompose all of these? I can't see us maintaining this properly if it isn't more automatic. It's also a bit more complicated as of 1.8 since we're handling call expressions too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a good idea 😀
@strayiker @mxstbr Waiting for @probablyup's answer : |
Yes it should be a peer dep
…On Fri, Oct 5, 2018 at 6:14 AM Luc ***@***.***> wrote:
@strayiker <https://github.com/strayiker> @mxstbr
<https://github.com/mxstbr>
Ok! I'll keep the code here.
Waiting for @probablyup <https://github.com/probablyup>'s answer :
#2032 (comment)
<#2032 (comment)>
: "should babel-plugin-styled-components dependency be a peerDependency or
a dependency ?" 🙂
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2032 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAiy1n1jYF_qLkaDKO7sgag7-5W_cZ4Aks5uhzD1gaJpZM4W9Z1O>
.
|
What is the reason for that ? Emotion is listing it as a dependency : https://github.com/emotion-js/emotion/blob/f8e795fe77d601b718ea4da4a906f820599c20a5/packages/css/package.json#L12 |
So it dedupes properly if another third party library adds it
…On Fri, Oct 5, 2018 at 9:53 PM Luc ***@***.***> wrote:
@probablyup <https://github.com/probablyup>
Yes it should be a peer dep
What is the reason for that ?
Emotion is listing it as a dependency :
https://github.com/emotion-js/emotion/blob/f8e795fe77d601b718ea4da4a906f820599c20a5/packages/css/package.json#L12
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2032 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAiy1jHZuPh0wS3_6k-qM-lzeJunHUeKks5uiAz7gaJpZM4W9Z1O>
.
|
@probablyup I'm still not sure the dedup is more important than the ease of use/simplicity though 🤔 |
It won't be obvious for create-react-app users that they have to In fact, this might be a compelling reason to move the macro to the Babel plugin instead after all (sorry 🙈). Imagine the docs as it is right now:
It's pretty unobvious that you need to install the plugin alongside before being able to use the macro mode. Contrast with this explanation:
That's more obvious, if a bit more typing in the import statement. Not sure what's better or worse, what do you think? |
IMO, the best way experience for users is to just install styled-components and import it through the macro and it works :
You don't need to install One of the reason for babel-plugin-macros to exist as a replacement of babel plugins is (listed in this article) :
When you need to install babel-plugin-styled-components as a user :
Also, other libraries are doing the same :
To sum up, this is what I think is best for users :
|
I see, good thinking. I think adding it as a dep is really the best UX. @probablyup let's put it as a dep with a really lenient version, maybe |
Speaking of this, what will happen if they don't? Will it still work? Work but silently not apply transforms? Throw some error? Is there any error / linting rule one can enable to ensure the macro is consistently imported in CRA instead of the "normal" import? Can we document this if it's not already? |
Just like it does today it will work as normally, just without any Babel transforms.
See my reply further up,
|
Yes, this is true with the current implementation, unless there is a file with 2 imports like this : import styled from 'styled-components'
import styled2 from 'styled-components/macro'
// ... In that case, both styled imports will be transformed. This is because of the current implementation. When The implementation is like this because we want the macro to be as close to the babel plugin as possible and easy to maintain when the babel plugin is updated. If we wanted to just transform locally, the macro should be aware of styled-components' API and that would be hard to maintain. For example, if it is used like this : import styled from 'styled-components'
import styled2 from 'styled-components/macro'
styled2.div`background: red;` If we want to only transform locally, we need to go up twice the tree to apply the transformation to the thing that matters to styled components, the
But this is specific to the default import, so we need to do the same for the other imports (css, keyframes, ...). So we start to implement styled-components' API in the macro itself. That's why the current implementation just pass the whole file to babel plugin and doesn't do things locally. AFAIK, I can't find a real use case for importing both |
Yeah that's totally fine. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add the Babel plugin back to deps and ship this?! @probablyup
I wish there was a way to have the macro applied automatically without having to specify a different import path... |
Maybe in the docs for this we should also recommend setting up aliasing so "styled-components" -> "styled-components/macro" |
|
Alright it's going in! Thanks for all the amazing work here @lucleray! |
Thank you so much for helping us improve styled-components! Based on our Community Guidelines every person that has a PR of any kind merged is offered an invitation to the styled-components organization—that is you right now! Should you accept, you'll get write access to the main repository. (and a fancy |
Thanks for the work on this PR.
It's not aliasing, but rules:
no-restricted-imports:
- error
- paths:
- name: 'styled-components'
message: 'Please import from styled-components/macro.'
patterns:
- '!styled-components/macro' I find it more explicit and intended than aliasing, however I'd be interested in knowing how you would implement aliasing. Using resolve.alias? |
Happy to see this merged 😀 @gilbsgilbs |
Definitely. It was rather a suggestion for the documentation. I was saying that I prefer having ESLint rules rather than aliasing which I find too implicit and "magic" (even though I'd be interested in knowing how aliasing could work here). I'm sure we'll all forget to import from the macro at some point and it would be unnoticeable otherwise. |
Since #1256 seems to be not active anymore, I created a new PR to add babel-macro to styled-components.
babel-plugin-styled-components
styled-components/macro
babel-plugin-styled-components