babel-plugin-emotion
Advanced tools
Comparing version 8.0.9 to 8.0.10
@@ -15,3 +15,3 @@ 'use strict'; | ||
function getIdentifierName(path, t) { | ||
function getDeclaratorName(path, t) { | ||
var parent = path.findParent(function (p) { | ||
@@ -23,2 +23,15 @@ return p.isVariableDeclarator(); | ||
function getIdentifierName(path, t) { | ||
var classParent = path.findParent(function (p) { | ||
return t.isClass(p); | ||
}); | ||
if (classParent && classParent.node.id) { | ||
return t.isIdentifier(classParent.node.id) ? classParent.node.id.name : ''; | ||
} else if (classParent && classParent.node.superClass && classParent.node.superClass.name) { | ||
return getDeclaratorName(path, t) + '(' + classParent.node.superClass.name + ')'; | ||
} | ||
return getDeclaratorName(path, t); | ||
} | ||
function getRuntimeImportPath(path, t) { | ||
@@ -25,0 +38,0 @@ var binding = path.scope.getBinding(path.node.name); |
@@ -77,3 +77,3 @@ 'use strict'; | ||
if (!state.cssPropIdentifier) { | ||
state.cssPropIdentifier = path.hub.file.addImport('emotion', 'css'); | ||
state.cssPropIdentifier = (0, _helperModuleImports.addNamed)(path, 'css', 'emotion'); | ||
} | ||
@@ -88,3 +88,3 @@ return state.cssPropIdentifier; | ||
if (!state.cssPropMergeIdentifier) { | ||
state.cssPropMergeIdentifier = path.hub.file.addImport('emotion', 'merge'); | ||
state.cssPropMergeIdentifier = (0, _helperModuleImports.addNamed)(path, 'merge', 'emotion'); | ||
} | ||
@@ -101,2 +101,4 @@ return state.cssPropMergeIdentifier; | ||
var _helperModuleImports = require('@babel/helper-module-imports'); | ||
var _sourceMap = require('./source-map'); |
119
lib/index.js
@@ -25,15 +25,96 @@ 'use strict'; | ||
state.importedNames = _extends({}, defaultImportedNames, state.opts.importedNames); | ||
state.file.metadata.modules.imports.forEach(function (_ref) { | ||
var source = _ref.source, | ||
imported = _ref.imported, | ||
specifiers = _ref.specifiers; | ||
var imports = []; | ||
var isModule = false; | ||
for (var _iterator = path.node.body, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { | ||
var _ref; | ||
if (_isArray) { | ||
if (_i >= _iterator.length) break; | ||
_ref = _iterator[_i++]; | ||
} else { | ||
_i = _iterator.next(); | ||
if (_i.done) break; | ||
_ref = _i.value; | ||
} | ||
var node = _ref; | ||
if (t.isModuleDeclaration(node)) { | ||
isModule = true; | ||
break; | ||
} | ||
} | ||
if (isModule) { | ||
path.traverse({ | ||
ImportDeclaration: { | ||
exit: function exit(path) { | ||
var node = path.node; | ||
var imported = []; | ||
var specifiers = []; | ||
imports.push({ | ||
source: node.source.value, | ||
imported: imported, | ||
specifiers: specifiers | ||
}); | ||
for (var _iterator2 = path.get('specifiers'), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { | ||
var _ref2; | ||
if (_isArray2) { | ||
if (_i2 >= _iterator2.length) break; | ||
_ref2 = _iterator2[_i2++]; | ||
} else { | ||
_i2 = _iterator2.next(); | ||
if (_i2.done) break; | ||
_ref2 = _i2.value; | ||
} | ||
var specifier = _ref2; | ||
var local = specifier.node.local.name; | ||
if (specifier.isImportDefaultSpecifier()) { | ||
imported.push('default'); | ||
specifiers.push({ | ||
kind: 'named', | ||
imported: 'default', | ||
local: local | ||
}); | ||
} | ||
if (specifier.isImportSpecifier()) { | ||
var importedName = specifier.node.imported.name; | ||
imported.push(importedName); | ||
specifiers.push({ | ||
kind: 'named', | ||
imported: importedName, | ||
local: local | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
imports.forEach(function (_ref3) { | ||
var source = _ref3.source, | ||
imported = _ref3.imported, | ||
specifiers = _ref3.specifiers; | ||
if (source.indexOf('emotion') !== -1) { | ||
var importedNames = specifiers.filter(function (v) { | ||
return ['default', 'css', 'keyframes', 'injectGlobal', 'fontFace', 'merge'].indexOf(v.imported) !== -1; | ||
}).reduce(function (acc, _ref2) { | ||
}).reduce(function (acc, _ref4) { | ||
var _extends2; | ||
var imported = _ref2.imported, | ||
local = _ref2.local; | ||
var imported = _ref4.imported, | ||
local = _ref4.local; | ||
return _extends({}, acc, (_extends2 = {}, _extends2[imported === 'default' ? 'styled' : imported] = local, _extends2)); | ||
@@ -65,3 +146,3 @@ }, defaultImportedNames); | ||
var exists = _fs2.default.existsSync(cssFilename); | ||
path.node.body.unshift(t.importDeclaration([], t.stringLiteral('./' + (0, _path.basename)(cssFilename)))); | ||
(0, _helperModuleImports.addSideEffect)(path, './' + (0, _path.basename)(cssFilename)); | ||
if (exists ? _fs2.default.readFileSync(cssFilename, 'utf8') !== toWrite : true) { | ||
@@ -81,3 +162,3 @@ if (!exists) { | ||
CallExpression: function CallExpression(callExprPath) { | ||
if (callExprPath.node.callee.name === state.importedNames.css || callExprPath.node.callee.name === '_' + state.importedNames.css) { | ||
if (callExprPath.node.callee.name === state.importedNames.css || callExprPath.node.callee === state.cssPropIdentifier) { | ||
hoistPureArgs(callExprPath); | ||
@@ -100,2 +181,8 @@ } | ||
path.addComment('leading', '#__PURE__'); | ||
if (state.opts.autoLabel) { | ||
var identifierName = (0, _babelUtils.getIdentifierName)(path, t); | ||
if (identifierName) { | ||
path.node.arguments.push(t.stringLiteral('label:' + identifierName.trim() + ';')); | ||
} | ||
} | ||
} | ||
@@ -170,2 +257,4 @@ // eslint-disable-next-line no-fallthrough | ||
var _helperModuleImports = require('@babel/helper-module-imports'); | ||
var _babelUtils = require('./babel-utils'); | ||
@@ -219,3 +308,4 @@ | ||
var name = (0, _babelUtils.getName)((0, _babelUtils.getIdentifierName)(path, t), 'css'); | ||
var identifierName = (0, _babelUtils.getIdentifierName)(path, t); | ||
var name = (0, _babelUtils.getName)(identifierName, 'css'); | ||
@@ -238,3 +328,3 @@ if (state.extractStatic && !path.node.quasi.expressions.length) { | ||
path.replaceWith(t.callExpression(identifier, new _astObject2.default((0, _babelUtils.minify)(src), path.node.quasi.expressions, t).toExpressions())); | ||
path.replaceWith(t.callExpression(identifier, new _astObject2.default((0, _babelUtils.minify)(src), path.node.quasi.expressions, t).toExpressions().concat(state.opts.autoLabel && identifierName ? [t.stringLiteral('label:' + identifierName.trim() + ';')] : []))); | ||
@@ -279,6 +369,8 @@ if (state.opts.hoist) { | ||
} | ||
return t.callExpression(t.callExpression(identifier, [tag]), new _astObject2.default((0, _babelUtils.minify)(src), path.node.quasi.expressions, t).toExpressions()); | ||
return t.callExpression(t.callExpression(identifier, state.opts.autoLabel && identifierName ? [tag, t.objectExpression([t.objectProperty(t.identifier('label'), t.stringLiteral(identifierName.trim()))])] : [tag]), new _astObject2.default((0, _babelUtils.minify)(src), path.node.quasi.expressions, t).toExpressions()); | ||
} | ||
function buildStyledObjectCallExpression(path, state, identifier, t) { | ||
var identifierName = (0, _babelUtils.getIdentifierName)(path, t); | ||
var tag = t.isCallExpression(path.node.callee) ? path.node.callee.arguments[0] : t.stringLiteral(path.node.callee.property.name); | ||
@@ -290,5 +382,6 @@ | ||
} | ||
path.addComment('leading', '#__PURE__'); | ||
return t.callExpression(t.callExpression(identifier, [tag]), args); | ||
return t.callExpression(t.callExpression(identifier, state.opts.autoLabel && identifierName ? [tag, t.objectExpression([t.objectProperty(t.identifier('label'), t.stringLiteral(identifierName.trim()))])] : [tag]), args); | ||
} | ||
@@ -295,0 +388,0 @@ |
{ | ||
"name": "babel-plugin-emotion", | ||
"version": "8.0.9", | ||
"description": "A recommended babel preprocessing plugin for emotion, the The Next Generation of CSS-in-JS.", | ||
"version": "8.0.10", | ||
"description": "A recommended babel preprocessing plugin for emotion, The Next Generation of CSS-in-JS.", | ||
"main": "lib/index.js", | ||
@@ -17,7 +17,7 @@ "files": [ | ||
"dependencies": { | ||
"babel-generator": "^6.26.0", | ||
"babel-macros": "^1.0.2", | ||
"@babel/helper-module-imports": "7.0.0-beta.31", | ||
"babel-macros": "^1.2.0", | ||
"babel-plugin-syntax-jsx": "^6.18.0", | ||
"convert-source-map": "^1.5.0", | ||
"emotion-utils": "^8.0.9", | ||
"emotion-utils": "^8.0.10", | ||
"source-map": "^0.5.7", | ||
@@ -27,2 +27,3 @@ "touch": "^1.0.0" | ||
"devDependencies": { | ||
"@babel/core": "7.0.0-beta.31", | ||
"babel-cli": "^6.24.1", | ||
@@ -29,0 +30,0 @@ "npm-run-all": "^4.0.2", |
@@ -20,3 +20,3 @@ # babel-plugin-emotion | ||
| `css` as Prop | | ✅ | Convenient helper for calling `css` and appending the generated className during compile time. | | ||
| Contextual Class Names | | ✅ | Generated class names include the name of the variable or component they were defined in. | ||
## Example | ||
@@ -81,2 +81,3 @@ | ||
"sourceMap": false, | ||
"autoLabel": false, | ||
"extractStatic": false, | ||
@@ -105,6 +106,6 @@ "importedNames": { | ||
"production": { | ||
"plugins": [["emotion", { "sourceMap": false, "hoist": true }]] | ||
"plugins": [["emotion", { "sourceMap": false, "hoist": true, "autoLabel": true }]] | ||
}, | ||
"development": { | ||
"plugins": [["emotion", { "sourceMap": true, "hoist": false }]] | ||
"plugins": [["emotion", { "sourceMap": true, "hoist": false, "autoLabel": true }]] | ||
} | ||
@@ -167,5 +168,68 @@ } | ||
### `autoLabel` | ||
`boolean`, defaults to `false`. | ||
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. | ||
#### css | ||
**In** | ||
```javascript | ||
const brownStyles = css({ color: 'brown' }); | ||
``` | ||
**Out** | ||
```javascript | ||
const brownStyles = /*#__PURE__*/css({ color: 'blue' }, "label:brownStyles;"); | ||
``` | ||
`brownStyles`'s value would be `css-1q8eu9e-brownStyles` | ||
#### styled | ||
**In** | ||
```javascript | ||
const Profile = () => { | ||
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 Profile = () => { | ||
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-13djram-H1` | ||
### `extractStatic` | ||
`boolean`, defaults to | ||
`boolean`, defaults to `false`. | ||
@@ -172,0 +236,0 @@ This option enables the following: |
import { hashArray } from './index' | ||
export function getIdentifierName(path, t) { | ||
function getDeclaratorName(path, t) { | ||
const parent = path.findParent(p => p.isVariableDeclarator()) | ||
@@ -8,2 +8,17 @@ return parent && t.isIdentifier(parent.node.id) ? parent.node.id.name : '' | ||
export function getIdentifierName(path, t) { | ||
const classParent = path.findParent(p => t.isClass(p)) | ||
if (classParent && classParent.node.id) { | ||
return t.isIdentifier(classParent.node.id) ? classParent.node.id.name : '' | ||
} else if ( | ||
classParent && | ||
classParent.node.superClass && | ||
classParent.node.superClass.name | ||
) { | ||
return `${getDeclaratorName(path, t)}(${classParent.node.superClass.name})` | ||
} | ||
return getDeclaratorName(path, t) | ||
} | ||
export function getRuntimeImportPath(path, t) { | ||
@@ -10,0 +25,0 @@ const binding = path.scope.getBinding(path.node.name) |
@@ -0,1 +1,2 @@ | ||
import { addNamed } from '@babel/helper-module-imports' | ||
import { addSourceMaps } from './source-map' | ||
@@ -108,3 +109,3 @@ | ||
if (!state.cssPropIdentifier) { | ||
state.cssPropIdentifier = path.hub.file.addImport('emotion', 'css') | ||
state.cssPropIdentifier = addNamed(path, 'css', 'emotion') | ||
} | ||
@@ -119,6 +120,3 @@ return state.cssPropIdentifier | ||
if (!state.cssPropMergeIdentifier) { | ||
state.cssPropMergeIdentifier = path.hub.file.addImport( | ||
'emotion', | ||
'merge' | ||
) | ||
state.cssPropMergeIdentifier = addNamed(path, 'merge', 'emotion') | ||
} | ||
@@ -125,0 +123,0 @@ return state.cssPropMergeIdentifier |
173
src/index.js
@@ -5,2 +5,3 @@ // @flow weak | ||
import { touchSync } from 'touch' | ||
import { addSideEffect } from '@babel/helper-module-imports' | ||
import { | ||
@@ -48,3 +49,4 @@ getIdentifierName, | ||
let { hash, src } = createRawStringFromTemplateLiteral(path.node.quasi) | ||
const name = getName(getIdentifierName(path, t), 'css') | ||
const identifierName = getIdentifierName(path, t) | ||
const name = getName(identifierName, 'css') | ||
@@ -73,7 +75,9 @@ if (state.extractStatic && !path.node.quasi.expressions.length) { | ||
identifier, | ||
new ASTObject( | ||
minify(src), | ||
path.node.quasi.expressions, | ||
t | ||
).toExpressions() | ||
new ASTObject(minify(src), path.node.quasi.expressions, t) | ||
.toExpressions() | ||
.concat( | ||
state.opts.autoLabel && identifierName | ||
? [t.stringLiteral(`label:${identifierName.trim()};`)] | ||
: [] | ||
) | ||
) | ||
@@ -127,4 +131,18 @@ ) | ||
} | ||
return t.callExpression( | ||
t.callExpression(identifier, [tag]), | ||
t.callExpression( | ||
identifier, | ||
state.opts.autoLabel && identifierName | ||
? [ | ||
tag, | ||
t.objectExpression([ | ||
t.objectProperty( | ||
t.identifier('label'), | ||
t.stringLiteral(identifierName.trim()) | ||
) | ||
]) | ||
] | ||
: [tag] | ||
), | ||
new ASTObject(minify(src), path.node.quasi.expressions, t).toExpressions() | ||
@@ -135,2 +153,3 @@ ) | ||
export function buildStyledObjectCallExpression(path, state, identifier, t) { | ||
const identifierName = getIdentifierName(path, t) | ||
const tag = t.isCallExpression(path.node.callee) | ||
@@ -144,5 +163,22 @@ ? path.node.callee.arguments[0] | ||
} | ||
path.addComment('leading', '#__PURE__') | ||
return t.callExpression(t.callExpression(identifier, [tag]), args) | ||
return t.callExpression( | ||
t.callExpression( | ||
identifier, | ||
state.opts.autoLabel && identifierName | ||
? [ | ||
tag, | ||
t.objectExpression([ | ||
t.objectProperty( | ||
t.identifier('label'), | ||
t.stringLiteral(identifierName.trim()) | ||
) | ||
]) | ||
] | ||
: [tag] | ||
), | ||
args | ||
) | ||
} | ||
@@ -174,31 +210,83 @@ | ||
} | ||
state.file.metadata.modules.imports.forEach( | ||
({ source, imported, specifiers }) => { | ||
if (source.indexOf('emotion') !== -1) { | ||
const importedNames = specifiers | ||
.filter( | ||
v => | ||
[ | ||
'default', | ||
'css', | ||
'keyframes', | ||
'injectGlobal', | ||
'fontFace', | ||
'merge' | ||
].indexOf(v.imported) !== -1 | ||
) | ||
.reduce( | ||
(acc, { imported, local }) => ({ | ||
...acc, | ||
[imported === 'default' ? 'styled' : imported]: local | ||
}), | ||
defaultImportedNames | ||
) | ||
state.importedNames = { | ||
...importedNames, | ||
...state.opts.importedNames | ||
const imports = [] | ||
let isModule = false | ||
for (const node of path.node.body) { | ||
if (t.isModuleDeclaration(node)) { | ||
isModule = true | ||
break | ||
} | ||
} | ||
if (isModule) { | ||
path.traverse({ | ||
ImportDeclaration: { | ||
exit(path) { | ||
const { node } = path | ||
const imported = [] | ||
const specifiers = [] | ||
imports.push({ | ||
source: node.source.value, | ||
imported, | ||
specifiers | ||
}) | ||
for (const specifier of path.get('specifiers')) { | ||
const local = specifier.node.local.name | ||
if (specifier.isImportDefaultSpecifier()) { | ||
imported.push('default') | ||
specifiers.push({ | ||
kind: 'named', | ||
imported: 'default', | ||
local | ||
}) | ||
} | ||
if (specifier.isImportSpecifier()) { | ||
const importedName = specifier.node.imported.name | ||
imported.push(importedName) | ||
specifiers.push({ | ||
kind: 'named', | ||
imported: importedName, | ||
local | ||
}) | ||
} | ||
} | ||
} | ||
} | ||
}) | ||
} | ||
imports.forEach(({ source, imported, specifiers }) => { | ||
if (source.indexOf('emotion') !== -1) { | ||
const importedNames = specifiers | ||
.filter( | ||
v => | ||
[ | ||
'default', | ||
'css', | ||
'keyframes', | ||
'injectGlobal', | ||
'fontFace', | ||
'merge' | ||
].indexOf(v.imported) !== -1 | ||
) | ||
.reduce( | ||
(acc, { imported, local }) => ({ | ||
...acc, | ||
[imported === 'default' ? 'styled' : imported]: local | ||
}), | ||
defaultImportedNames | ||
) | ||
state.importedNames = { | ||
...importedNames, | ||
...state.opts.importedNames | ||
} | ||
} | ||
) | ||
}) | ||
@@ -223,8 +311,3 @@ state.extractStatic = | ||
const exists = fs.existsSync(cssFilename) | ||
path.node.body.unshift( | ||
t.importDeclaration( | ||
[], | ||
t.stringLiteral('./' + basename(cssFilename)) | ||
) | ||
) | ||
addSideEffect(path, './' + basename(cssFilename)) | ||
if ( | ||
@@ -248,3 +331,3 @@ exists ? fs.readFileSync(cssFilename, 'utf8') !== toWrite : true | ||
callExprPath.node.callee.name === state.importedNames.css || | ||
callExprPath.node.callee.name === `_${state.importedNames.css}` | ||
callExprPath.node.callee === state.cssPropIdentifier | ||
) { | ||
@@ -267,2 +350,10 @@ hoistPureArgs(callExprPath) | ||
path.addComment('leading', '#__PURE__') | ||
if (state.opts.autoLabel) { | ||
const identifierName = getIdentifierName(path, t) | ||
if (identifierName) { | ||
path.node.arguments.push( | ||
t.stringLiteral(`label:${identifierName.trim()};`) | ||
) | ||
} | ||
} | ||
} | ||
@@ -269,0 +360,0 @@ // eslint-disable-next-line no-fallthrough |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
64182
1526
260
4
+ Added@babel/helper-module-imports@7.0.0-beta.31(transitive)
+ Added@babel/types@7.0.0-beta.31(transitive)
+ Addedto-fast-properties@2.0.0(transitive)
- Removedbabel-generator@^6.26.0
- Removedbabel-generator@6.26.1(transitive)
- Removedbabel-messages@6.23.0(transitive)
- Removedbabel-runtime@6.26.0(transitive)
- Removedbabel-types@6.26.0(transitive)
- Removedcore-js@2.6.12(transitive)
- Removeddetect-indent@4.0.0(transitive)
- Removedis-finite@1.1.0(transitive)
- Removedjsesc@1.3.0(transitive)
- Removedregenerator-runtime@0.11.1(transitive)
- Removedrepeating@2.0.1(transitive)
- Removedto-fast-properties@1.0.3(transitive)
- Removedtrim-right@1.0.1(transitive)
Updatedbabel-macros@^1.2.0
Updatedemotion-utils@^8.0.10