# babel-plugin-emotion
> Babel plugin for the minification and optimization of emotion styles.
`babel-plugin-emotion` is highly recommended, but not required in version 8 and
above of `emotion`.
## Features
Feature/Syntax |
Native |
Babel Plugin Required |
Notes |
css`` |
✅ |
|
|
css(...) |
✅ |
|
Generally used for object styles. |
components as selectors |
|
✅ |
Allows an emotion component to be used as a CSS selector. |
Minification |
|
✅ |
Any leading/trailing space between properties in your css and styled blocks is removed. This can reduce the size of your final bundle. |
Dead Code Elimination |
|
✅ |
Uglifyjs will use the injected /*#__PURE__*/ flag comments to mark your css and styled blocks as candidates for dead code elimination. |
Source Maps |
|
✅ |
When enabled, navigate directly to the style declaration in your javascript file. |
Contextual Class Names |
|
✅ |
Generated class names include the name of the variable or component they were defined in. |
## Example
**In**
```javascript
const myStyles = css`
font-size: 20px;
@media (min-width: 420px) {
color: blue;
${css`
width: 96px;
height: 96px;
`};
line-height: 26px;
}
background: green;
${{ backgroundColor: 'hotpink' }};
`
```
**Out**
```javascript
const myStyles = /* #__PURE__ */ css(
'font-size:20px;@media(min-width:420px){color:blue;',
/* #__PURE__ */ css('width:96px;height:96px;'),
';line-height:26px;}background:green;',
{ backgroundColor: 'hotpink' },
';'
)
```
## Installation
```bash
yarn add --dev babel-plugin-emotion
```
or if you prefer npm
```bash
npm install --save-dev babel-plugin-emotion
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
Without options:
```json
{
"plugins": ["emotion"]
}
```
With options:
_Defaults Shown_
```js
{
"plugins": [
[
"emotion",
{
// sourceMap is on by default but source maps are dead code eliminated in production
"sourceMap": true,
"autoLabel": process.env.NODE_ENV !== 'production',
"labelFormat": "[local]",
"cssPropOptimization": true
}
]
]
}
```
Recommended Setup
**.babelrc**
```json
{
"plugins": ["emotion"]
}
```
### Via CLI
```bash
babel --plugins babel-plugin-emotion script.js
```
### Via Node API
```javascript
require('@babel/core').transform('code', {
plugins: ['babel-plugin-emotion']
})
```
## Options
### `sourceMap`
`boolean`, defaults to `true`.
This option enables the following:
- Injected source maps for use in browser dev tools
[**Documentation**](https://emotion.sh/docs/source-maps)
> Note:
>
> Source maps are on by default in babel-plugin-emotion but they will be removed in production builds
### `autoLabel`
`boolean`, defaults to `process.env.NODE_ENV !== 'production'`.
This option enables the following:
- Automatically adds the `label` property to styles so that class names
generated by `css` or `styled` include the name of the variable the result is
assigned to.
- Please note that non word characters in the variable will be removed
(Eg. `iconStyles$1` will become `iconStyles1`) because `$` is not valid
[CSS ClassName Selector](https://stackoverflow.com/questions/448981/which-characters-are-valid-in-css-class-names-selectors#449000)
#### css
**In**
```javascript
const brownStyles = css({ color: 'brown' })
```
**Out**
```javascript
const brownStyles = /*#__PURE__*/ css({ color: 'brown' }, 'label:brownStyles;')
```
`brownStyles`'s value would be `css-1q8eu9e-brownStyles`
### `labelFormat`
`string`, defaults to `"[local]"`.
This option only works when `autoLabel` is set to `true`. It allows you to
define the format of the resulting `label`. The format is defined via string where
variable parts are enclosed in square brackets `[]`.
For example `labelFormat: "my-classname--[local]"`, where `[local]` will be replaced
with the name of the variable the result is assigned to.
Allowed values:
- `[local]` - the name of the variable the result of the `css` or `styled` expression is assigned to.
- `[filename]` - name of the file (without extension) where `css` or `styled` expression is located.
- `[dirname]` - name of the directory containing the file where `css` or `styled` expression is located.
This format only affects the label property of the expression, meaning that the `css` prefix and hash will
be prepended automatically.
#### css
**In**
```javascript
// BrownView.js
// autoLabel: true
// labelFormat: '[filename]--[local]'
const brownStyles = css({ color: 'brown' })
```
**Out**
```javascript
const brownStyles = /*#__PURE__*/ css(
{ color: 'brown' },
'label:BrownView--brownStyles;'
)
```
`BrownView--brownStyles`'s value would be `css-hash-BrownView--brownStyles`
#### styled
**In**
```javascript
const H1 = styled.h1({
borderRadius: '50%',
transition: 'transform 400ms ease-in-out',
boxSizing: 'border-box',
display: 'flex',
':hover': {
transform: 'scale(1.2)'
}
})
```
**Out**
```javascript
const H1 = /*#__PURE__*/ styled('h1', {
label: 'H1'
})({
borderRadius: '50%',
transition: 'transform 400ms ease-in-out',
boxSizing: 'border-box',
display: 'flex',
':hover': {
transform: 'scale(1.2)'
}
})
```
`H1`'s class name attribute would be `css-hash-H1`
### `instances`
`Array`, defaults to
```jsx
;['emotion']
```
This option allows `babel-plugin-emotion` to know which imports to treat as
emotion imports and transform as such. This option is **only** required if you
use a custom instance of emotion created with `create-emotion` or you're
importing emotion from somewhere other than the paths above. Relative paths are
resolved relative to `process.cwd()`(the current working directory).
[**Documentation**](https://emotion.sh/docs/instances)
### `cssPropOptimization`
`boolean`, defaults to `true` if an import from `@emotion/core` is found in a file.
This option assumes that you are using something to make `@emotion/core`'s `jsx` function work for all jsx. If you are not doing so and you do not want such optimizations to occur, disable this option.
## Babel Macros
Instead of using `babel-plugin-emotion`, you can use emotion with [`babel-plugin-macros`](https://github.com/kentcdodds/babel-plugin-macros). Add `babel-plugin-macros` to your babel config (which is included in Create React App 2.0) and use the imports/packages shown below.
```jsx
import styled from 'react-emotion/macro'
import { css, keyframes, injectGlobal, flush, hydrate } from 'emotion/macro'
import css from '@emotion/css/macro'
import styled from '@emotion/styled/macro'
```