You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							347 lines
						
					
					
						
							8.0 KiB
						
					
					
				
			
		
		
	
	
							347 lines
						
					
					
						
							8.0 KiB
						
					
					
				| # @emotion/babel-plugin
 | |
| 
 | |
| > Babel plugin for the minification and optimization of emotion styles.
 | |
| 
 | |
| `@emotion/babel-plugin` is highly recommended, but not required in version 8 and
 | |
| above of Emotion.
 | |
| 
 | |
| ## Features
 | |
| 
 | |
| <table>
 | |
|   <thead>
 | |
|     <tr>
 | |
|       <th>Feature/Syntax</th>
 | |
|       <th>Native</th>
 | |
|       <th>Babel Plugin Required</th>
 | |
|       <th>Notes</th>
 | |
|     </tr>
 | |
|   </thead>
 | |
|   <tbody>
 | |
|     <tr>
 | |
|       <td><code>css``</code></td>
 | |
|       <td align="center">✅</td>
 | |
|       <td align="center"></td>
 | |
|       <td></td>
 | |
|     </tr>
 | |
|     <tr>
 | |
|       <td><code>css(...)</code></td>
 | |
|       <td align="center">✅</td>
 | |
|       <td align="center"></td>
 | |
|       <td>Generally used for object styles.</td>
 | |
|     </tr>
 | |
|     <tr>
 | |
|       <td>components as selectors</td>
 | |
|       <td align="center"></td>
 | |
|       <td align="center">✅</td>
 | |
|       <td>Allows an emotion component to be <a href="https://emotion.sh/docs/styled#targeting-another-emotion-component">used as a CSS selector</a>.</td>
 | |
|     </tr>
 | |
|     <tr>
 | |
|       <td>Minification</td>
 | |
|       <td align="center"></td>
 | |
|       <td align="center">✅</td>
 | |
|       <td>Any leading/trailing space between properties in your <code>css</code> and <code>styled</code> blocks is removed. This can reduce the size of your final bundle.</td>
 | |
|     </tr>
 | |
|     <tr>
 | |
|       <td>Dead Code Elimination</td>
 | |
|       <td align="center"></td>
 | |
|       <td align="center">✅</td>
 | |
|       <td>Uglifyjs will use the injected <code>/*#__PURE__*/</code> flag comments to mark your <code>css</code> and <code>styled</code> blocks as candidates for dead code elimination.</td>
 | |
|     </tr>
 | |
|     <tr>
 | |
|       <td>Source Maps</td>
 | |
|       <td align="center"></td>
 | |
|       <td align="center">✅</td>
 | |
|       <td>When enabled, navigate directly to the style declaration in your javascript file.</td>
 | |
|     </tr>
 | |
|     <tr>
 | |
|       <td>Contextual Class Names</td>
 | |
|       <td align="center"></td>
 | |
|       <td align="center">✅</td>
 | |
|       <td>Generated class names include the name of the variable or component they were defined in.</td>
 | |
|     </tr>
 | |
|   </tbody>
 | |
| </table>
 | |
| 
 | |
| ## 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 @emotion/babel-plugin
 | |
| ```
 | |
| 
 | |
| or if you prefer npm
 | |
| 
 | |
| ```bash
 | |
| npm install --save-dev @emotion/babel-plugin
 | |
| ```
 | |
| 
 | |
| ## 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": "dev-only",
 | |
|         "labelFormat": "[local]",
 | |
|         "cssPropOptimization": true
 | |
|       }
 | |
|     ]
 | |
|   ]
 | |
| }
 | |
| ```
 | |
| 
 | |
| Recommended Setup
 | |
| 
 | |
| **.babelrc**
 | |
| 
 | |
| ```json
 | |
| {
 | |
|   "plugins": ["@emotion"]
 | |
| }
 | |
| ```
 | |
| 
 | |
| ### Via CLI
 | |
| 
 | |
| ```bash
 | |
| babel --plugins @emotion/babel-plugin script.js
 | |
| ```
 | |
| 
 | |
| ### Via Node API
 | |
| 
 | |
| ```javascript
 | |
| require('@babel/core').transform('code', {
 | |
|   plugins: ['@emotion/babel-plugin']
 | |
| })
 | |
| ```
 | |
| 
 | |
| ## 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 @emotion/babel-plugin but they will be removed in production builds
 | |
| 
 | |
| ### `autoLabel`
 | |
| 
 | |
| `'dev-only' | 'always' | 'never'`, defaults to `dev-only`.
 | |
| 
 | |
| 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)
 | |
| 
 | |
| Each possible value for this option produces different output code:
 | |
| 
 | |
| - with `dev-only` we optimize the production code, so there are no labels added there, but at the same time we keep labels for development environments,
 | |
| - with `always` we always add labels when possible,
 | |
| - with `never` we disable this entirely and no labels are added.
 | |
| 
 | |
| #### 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 `'dev-only'` or `'always'`. 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: 'dev-only'
 | |
| // 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`
 | |
| 
 | |
| ### `cssPropOptimization`
 | |
| 
 | |
| `boolean`, defaults to `true`.
 | |
| 
 | |
| This option assumes that you are using something to make `@emotion/react`'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.
 | |
| 
 | |
| ### `importMap`
 | |
| 
 | |
| This option allows you to tell @emotion/babel-plugin what imports it should look at to determine what it should transform so if you re-export Emotion's exports, you can still use the Babel transforms
 | |
| 
 | |
| An example file:
 | |
| 
 | |
| ```js
 | |
| import { anotherExport } from 'my-package';
 | |
| import { someExport, thisIsTheJsxExport } from 'some-package';
 | |
| ```
 | |
| 
 | |
| An example config:
 | |
| 
 | |
| ```json
 | |
| {
 | |
|   "my-package": {
 | |
|     "anotherExport": {
 | |
|       "canonicalImport": ["@emotion/styled", "default"],
 | |
|       "styledBaseImport": ["my-package/base", "anotherExport"]
 | |
|     }
 | |
|   },
 | |
|   "some-package": {
 | |
|     "someExport": {
 | |
|       "canonicalImport": ["@emotion/react", "css"]
 | |
|     },
 | |
|     "thisIsTheJsxExport": {
 | |
|       "canonicalImport": ["@emotion/react", "jsx"]
 | |
|     }
 | |
|   }
 | |
| }
 | |
| ```
 | |
| 
 | |
| ## Babel Macros
 | |
| 
 | |
| Instead of using `@emotion/babel-plugin`, 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 {
 | |
|   css,
 | |
|   keyframes,
 | |
|   injectGlobal,
 | |
|   flush,
 | |
|   hydrate
 | |
| } from '@emotion/css/macro'
 | |
| import { jsx, css, Global, keyframes } from '@emotion/react/macro'
 | |
| import styled from '@emotion/styled/macro'
 | |
| ```
 |