Emotion 8
Emotion 8 expands on an already great feature set while nearly doubling performance numbers and removing the need for a babel plugin.
In this release we’ve done some great things such as rewriting the core, removing the need for babel and adding source map support. We’re going to go over the these highlights and more in this article. For all those tiny details check out the changelog.
New Core
Rewritten by Mitchell Hamilton, the core is now powered by stylis.js. This gives us the freedom to support runtime based style merging and prefixing without the need for a babel plugin. Adding stylis.js did increase the size of our bundle, but the emotion package is still only ~5kb gzipped. The increased performance and flexibility makes the size increase a no brainer.
Source Maps
We added the ability to turn on source maps! Enabling them allows developers to navigate directly to the location of their style definitions.
Development environment only.
The Babel Plugin Is No Longer Required
It is highly recommended, but optional.
The following features are enabled when using the babel plugin.
- `styled.div` syntax
styled('div')
will work without the plugin - Minification
Any leading/trailing space between properties in yourcss
andstyled
blocks is removed. This can reduce the size of your final bundle. /*#__PURE__*/
flag injection
Uglifyjs will use these special comments to mark yourcss
andstyled
as candidates for dead code elimination.- Static Extraction
Static extraction can only work with the babel plugin. - Source Maps
When enabled, source-maps allow you to navigate directly to the location of your styles in Javascript files. - css prop
The css prop is just a shortcut for calling thecss
function and appending the result to theclassName
prop. We do this all at compile time.
Babel plugin installation documentation
Performance
We’ve nearly doubled the performance of styled
components compared to version 7! Benchmarks are run on every build to ensure there are no performance regressions.
We use a forked version of the benchmarks created by Nicolas Gallagher for react-native-web.
Theming
emotion-theming
is available on npm as of version 8. We forked styled-component’s theming components and built theming directly into react-emotion
. The major takeaway here is that wrapping styled
components in withTheme
is no longer required. If you are currently using the theming
library it will continue to work while you migrate.
Composes Is No Longer Supported (Breaking Change)
The behavior is nearly the same, just remove the composes property and put a semi colon between each expression. This means you can no longer apply arbitrary class names to a styled
component.
const Link = styled.a`
composes: ${css`color: blue;`} ${css`display: flex;`};
`
Would need to be updated to
const Link = styled.a`
${css`color: blue;`};
${css`display: flex;`};
`
There is a codemod that does this for you.
withComponent
This is a great feature from styled-components. In order to make the switch easier for users we added the API.
const View = styled.div`
color: darkorchid;
}const Link = View.withComponent('a')
Configurable Imports
If you are using ES Module imports the emotion babel plugin can handle two types of import renaming.
Dynamic
import something, { css as emotion } from ‘react-emotion’;const classes = emotion`
color: red;
`export default something.div`
background: blue;
`
Babel Opts
The emotion babel plugin can also handle using babel options to handle
processing via the importedNames
key. This is useful for targeting
a prop other than css
for processing.
{
“plugins”: [
[“emotion”, { “importedNames”: { “css”: “emotion” }}]
]
}
This can be incredibly useful if you want to migrate to emotion in stages. For instance, when coming from styled-components, emotion
can be used instead of styled
to avoid conflicts. Similarly, emotion
could be used instead of css
when coming from glamor.
configurable import documentation
Component As Selector Removed (Breaking Change)
The following is no longer supported.
const Link = styled.a`
${css`color: blue;`};
${css`display: flex;`};
`const View = styled.div`
${Link} {
color: darkorchid;
}
}
Support for this feature requires the babel plugin. It also drastically complicated the emotion codebase for minimal return. Read more here.
Import Shortcuts Removed (Breaking Change)
In order to ensure that there is only one instance of the emotion
stylesheet at any given time we have removed the emotion/react
, emotion/babel
, and emotion/server
shortcuts. You must install react-emotion
, babel-plugin-emotion
, and emotion-server
respectively.
Note that react-emotion
exports all of emotion
so you can import css
and friends from react-emotion
.
import styled, {
css,
sheet,
injectGlobal,
keyframes,
fontFace
} from 'react-emotion'