e.g.
import emotion from 'emotion/react'; // instead of import styled
const Thing = emotion.div`
color: red;
`;
It'd be nice if the plugin detected whatever the default export was being called and handled it.
This is supported in the babel macro. I personally don't think we should do this in the regular babel plugin because it would mean it wouldn't be possible to use other styled runtimes like emotion-vue and it would make the playground on the website much more difficult.
It's very confusing. At the very least, a warning message would be helpful,
because otherwise it looks like a random garbage error during compilation.
I think a warning could be a good idea. @tkh44 What do you think?
To be clear though, I do strongly think that the babel plugin should detect the left side of the import and not make assumptions about its naming. Even if there's a warning, it's an unexpected behavior that is not difficult to assuage.
I'd even be willing to try and do it myself if you want.
Short term: I want to put some kind of warning.
I've been thinking about this a while. I want to make the whole thing customizable from the babel options.
[
'emotion/babel',
{
styledName: 'emotion',
cssName: 'c',
extractStatic: false
}
]
Something like that. What do you think @mitchellhamilton? This should be fairly simple to do, but I may be missing something.
@tkh44 I totally agree with making it customizable, probably something more like this though.
```js
[
'emotion/babel',
{
imports: {
css: 'c',
styled: 'emotion'
},
extractStatic: false
}
]
What's the benefit of making it a config instead of autodetecting it in the code?
Autodetecting would mean we would be forced to make assumptions about the way people are loading the runtime and what runtime they're using.
Hmm, I get what you're saying but if I make a variable named "emotion" that isn't an import, it'd get caught by the simple config right?
If you're using it in the way that styled can be used(as a tagged template literal or with the object syntax like glamorous) then yes but if you don't use it like that then nothing will be changed.
Just to expand on what I just said, only the last example in this will be touched by the babel plugin
const styled = 'something'
console.log(styled)
function styled () {
alert('something')
}
styled()
```jsx
function styled (...args) {
// do stuff
}
const SomeComponent = styled.div
display: flex;
You could steal this code from our stylelint processor:
Basically, we keep track of import/requires. (note that we're manually parsing since it's a stylelint processor, for a babel plugin you wouldn't need the whole traverse() thing)
By default, everything that says styled.x or styled(x) etc with a tagged template literal gets touched, but if you do something like import bla from 'styled-components' we'll check for bla.x rather than styled.x. On top of that we have an importName option landing soon which will allow you to target e.g. "emotion" as the library name being imported so import emotion from 'emotion' will also work.
Hope that makes sense!
Closed via #290
Most helpful comment
You could steal this code from our stylelint processor:
https://github.com/styled-components/stylelint-processor-styled-components/blob/2685933742d4f250f61ab15ca270001bf6ab87f8/src/parsers/index.js#L23-L43
Basically, we keep track of
import/requires. (note that we're manually parsing since it's a stylelint processor, for a babel plugin you wouldn't need the wholetraverse()thing)By default, everything that says
styled.xorstyled(x)etc with a tagged template literal gets touched, but if you do something likeimport bla from 'styled-components'we'll check forbla.xrather thanstyled.x. On top of that we have animportNameoption landing soon which will allow you to target e.g."emotion"as the library name being imported soimport emotion from 'emotion'will also work.Hope that makes sense!