Skip to content

Implement the plugin as a babel macro #142

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

Merged
merged 35 commits into from
Jul 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
6cba2f9
Move theming into its own file
emmatown Jul 11, 2017
78f8ec8
Initial work on babel macro
emmatown Jul 13, 2017
4969aa1
Move styled macro to src/react
emmatown Jul 13, 2017
01da260
Make styled tagged template literals work
emmatown Jul 13, 2017
f0b769b
Add requires to runtime
emmatown Jul 13, 2017
9375a7b
tagged template literals actually work
emmatown Jul 13, 2017
20ee02d
Merge branch 'master' into babel-macro
Jul 14, 2017
228f589
stuff
emmatown Jul 14, 2017
12fc4cf
Styled objects
emmatown Jul 14, 2017
a124a9f
Change object styled macro
emmatown Jul 14, 2017
bf40a29
Fix styled object
emmatown Jul 14, 2017
892cfdd
Abstract away fontFace and injectGlobal
emmatown Jul 14, 2017
c34ce8c
Add fontFace and injectGlobal
emmatown Jul 14, 2017
b53e882
Add css macro
emmatown Jul 14, 2017
d8cabae
Add keyframes and refactor
emmatown Jul 14, 2017
1837905
macro imports and vue
emmatown Jul 14, 2017
07e5890
Fix import
emmatown Jul 14, 2017
2f9cfaa
Add docs
emmatown Jul 14, 2017
91ea952
Update docs
emmatown Jul 14, 2017
73bca01
Add tests and stuff, just committing so I can go to another branch
emmatown Jul 14, 2017
7bd1e29
Merge branch 'master' into babel-macro
emmatown Jul 15, 2017
5b1fb78
stuff
emmatown Jul 15, 2017
ac7e12f
Update babel-macros
emmatown Jul 15, 2017
1417368
Update docs
emmatown Jul 15, 2017
51b8b22
Update docs
emmatown Jul 15, 2017
981d8d3
Use ES imports to import runtime in macro and update tests
emmatown Jul 15, 2017
82c8181
Fix tests and throw an error if styled is imported with commonjs
emmatown Jul 15, 2017
eeb401d
Add test for multiple imports
emmatown Jul 15, 2017
6541f4b
Update snapshot
emmatown Jul 15, 2017
511aa1b
Prettier
emmatown Jul 15, 2017
e0f8431
Merge branch 'master' into babel-macro
emmatown Jul 16, 2017
57531ce
Merge branch 'master' into babel-macro
Jul 16, 2017
9b9f6ef
Export all exports that do not need to be transformed from the macros
emmatown Jul 16, 2017
544a9c4
Merge branch 'babel-macro' of https://github.com/mitchellhamilton/emo…
emmatown Jul 16, 2017
dac1dca
Update snapshots
emmatown Jul 16, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ minimizes the runtime cost of css-in-js dramatically by parsing your styles with
- [vue styled](https://github.com/tkh44/emotion/tree/master/docs/vue-styled.md)

- [Usage with CSS Modules](https://github.com/tkh44/emotion/tree/master/docs/css-modules.md)
- [Usage with babel-macros](https://github.com/tkh44/emotion/tree/master/docs/babel-macros.md)
11 changes: 11 additions & 0 deletions docs/babel-macros.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Usage with babel-macros

Instead of using the emotion's babel plugin, you can use emotion with [`babel-macros`](https://github.com/kentcdodds/babel-macros). Add `babel-macros` to your babel config and import whatever you want from emotion but add `/macro` to the end. The macro is currently the same as inline mode. Currently every API except for the css prop is supported by the macro.

```jsx
import styled from 'emotion/react/macro'
import { css, keyframes, fontFace, injectGlobal, flush, hydrate } from 'emotion/macro'
import vueStyled from 'emotion/vue/macro'
```

For some context, check out this [issue](https://github.com/facebookincubator/create-react-app/issues/2730).
1 change: 1 addition & 0 deletions macro.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./lib/macro')
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
"lib",
"react",
"server.js",
"vue.js",
"dist/DO-NOT-USE.min.js"
"vue",
"dist/DO-NOT-USE.min.js",
"macro.js"
],
"scripts": {
"build": "babel src -d lib",
Expand Down Expand Up @@ -44,6 +45,7 @@
"babel-core": "^6.24.1",
"babel-eslint": "^7.2.3",
"babel-jest": "^20.0.3",
"babel-macros": "^0.5.2",
"babel-preset-env": "^1.5.1",
"babel-preset-flow": "^6.23.0",
"babel-preset-react": "^6.24.1",
Expand Down
1 change: 1 addition & 0 deletions react/macro.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../lib/react/macro')
51 changes: 51 additions & 0 deletions src/babel-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { keys } from './utils'
import forEach from '@arr/foreach'

export function getIdentifierName (path, t) {
const parent = path.findParent(p => p.isVariableDeclarator())
return parent && t.isIdentifier(parent.node.id) ? parent.node.id.name : ''
}

export function getRuntimeImportPath (path, t) {
const binding = path.scope.getBinding(path.node.name)
if (!t.isImportDeclaration(binding.path.parentPath)) {
throw binding.path.buildCodeFrameError(
'the emotion macro must be imported with es modules'
)
}
const importPath = binding.path.parentPath.node.source.value
return importPath.match(/(.*)\/macro/)[1]
}

export function buildMacroRuntimeNode (path, state, importName, t) {
const runtimeImportPath = getRuntimeImportPath(path, t)
if (state.emotionImports === undefined) state.emotionImports = {}
if (state.emotionImports[runtimeImportPath] === undefined) { state.emotionImports[runtimeImportPath] = {} }
if (state.emotionImports[runtimeImportPath][importName] === undefined) {
state.emotionImports[runtimeImportPath][
importName
] = path.scope.generateUidIdentifier(path.node.name)
}
return state.emotionImports[runtimeImportPath][importName]
}

export function addRuntimeImports (state, t) {
if (state.emotionImports === undefined) return
forEach(keys(state.emotionImports), importPath => {
const importSpecifiers = []
forEach(keys(state.emotionImports[importPath]), importName => {
const identifier = state.emotionImports[importPath][importName]
if (importName === 'default') {
importSpecifiers.push(t.importDefaultSpecifier(identifier))
} else {
importSpecifiers.push(
t.importSpecifier(identifier, t.identifier(importName))
)
}
})
state.file.path.node.body.unshift(
t.importDeclaration(importSpecifiers, t.stringLiteral(importPath))
)
})
state.emotionImports = undefined
}
Loading