Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

babel-plugin-emotion

Package Overview
Dependencies
Maintainers
2
Versions
90
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-emotion - npm Package Compare versions

Comparing version 8.0.12 to 9.0.0-0

10

lib/ast-object.js

@@ -9,3 +9,3 @@ 'use strict';

return interpolations.reduce(function (array, interp, i) {
return array.concat(interp, strings[i + 1]);
return array.concat([interp], strings[i + 1]);
}, [strings[0]]);

@@ -18,3 +18,3 @@ };

this.stringSrc = src;
this.src = src;
this.expressions = expressions || [];

@@ -72,3 +72,5 @@ this.t = t;

return interleave(strings, finalExpressions).filter(function (node) {
return interleave(strings, finalExpressions).filter(
// $FlowFixMe
function (node) {
return node.value !== '';

@@ -79,3 +81,3 @@ });

ASTObject.prototype.toExpressions = function toExpressions() {
return this.replacePlaceholdersWithExpressions(this.getDynamicMatches(this.stringSrc), this.stringSrc);
return this.replacePlaceholdersWithExpressions(this.getDynamicMatches(this.src), this.src);
};

@@ -82,0 +84,0 @@

43

lib/babel-utils.js

@@ -16,2 +16,3 @@ 'use strict';

function getDeclaratorName(path, t) {
// $FlowFixMe
var parent = path.findParent(function (p) {

@@ -22,7 +23,10 @@ return p.isVariableDeclarator();

}
function getIdentifierName(path, t) {
var classParent = path.findParent(function (p) {
return t.isClass(p);
});
var classParent = void 0;
if (path) {
// $FlowFixMe
classParent = path.findParent(function (p) {
return t.isClass(p);
});
}
if (classParent && classParent.node.id) {

@@ -38,2 +42,3 @@ return t.isIdentifier(classParent.node.id) ? classParent.node.id.name : '';

function getRuntimeImportPath(path, t) {
// $FlowFixMe
var binding = path.scope.getBinding(path.node.name);

@@ -54,2 +59,3 @@ if (!t.isImportDeclaration(binding.path.parentPath)) {

if (state.emotionImports[runtimeImportPath][importName] === undefined) {
// $FlowFixMe
state.emotionImports[runtimeImportPath][importName] = path.scope.generateUidIdentifier(path.node.name);

@@ -61,16 +67,19 @@ }

function addRuntimeImports(state, t) {
if (state.emotionImports === undefined) return;
Object.keys(state.emotionImports).forEach(function (importPath) {
var importSpecifiers = [];
Object.keys(state.emotionImports[importPath]).forEach(function (importName) {
var identifier = state.emotionImports[importPath][importName];
if (importName === 'default') {
importSpecifiers.push(t.importDefaultSpecifier(identifier));
} else {
importSpecifiers.push(t.importSpecifier(identifier, t.identifier(importName)));
}
if (state.emotionImports) {
var _emotionImports = state.emotionImports;
Object.keys(_emotionImports).forEach(function (importPath) {
var importSpecifiers = [];
Object.keys(_emotionImports[importPath]).forEach(function (importName) {
var identifier = _emotionImports[importPath][importName];
if (importName === 'default') {
importSpecifiers.push(t.importDefaultSpecifier(identifier));
} else {
importSpecifiers.push(t.importSpecifier(identifier, t.identifier(importName)));
}
});
// $FlowFixMe
state.file.path.node.body.unshift(t.importDeclaration(importSpecifiers, t.stringLiteral(importPath)));
});
state.file.path.node.body.unshift(t.importDeclaration(importSpecifiers, t.stringLiteral(importPath)));
});
state.emotionImports = undefined;
state.emotionImports = undefined;
}
}

@@ -77,0 +86,0 @@ function getName(identifierName, prefix) {

@@ -54,12 +54,14 @@ 'use strict';

cssPath.parentPath.remove();
if (t.isJSXExpressionContainer(classNamesValue)) {
var _args = [add(cssTemplateExpression, add(t.stringLiteral(' '), classNamesValue.expression))];
if (classNamesPath && classNamesPath.parentPath) {
if (t.isJSXExpressionContainer(classNamesValue)) {
var _args = [add(cssTemplateExpression, add(t.stringLiteral(' '), classNamesValue.expression))];
if (state.opts.sourceMap) {
_args.push(t.stringLiteral((0, _sourceMap.addSourceMaps)(cssPath.node.loc.start, state)));
if (state.opts.sourceMap) {
_args.push(t.stringLiteral((0, _sourceMap.addSourceMaps)(cssPath.node.loc.start, state)));
}
classNamesPath.parentPath.replaceWith(createClassNameAttr(t.callExpression(getMergeIdentifier(), _args)));
} else {
classNamesPath.parentPath.replaceWith(createClassNameAttr(add(cssTemplateExpression, t.stringLiteral(' ' + (classNamesValue.value || '')))));
}
classNamesPath.parentPath.replaceWith(createClassNameAttr(t.callExpression(getMergeIdentifier(), _args)));
} else {
classNamesPath.parentPath.replaceWith(createClassNameAttr(add(cssTemplateExpression, t.stringLiteral(' ' + (classNamesValue.value || '')))));
}

@@ -72,3 +74,3 @@

function createClassNameAttr(expression) {
return t.jSXAttribute(t.jSXIdentifier('className'), t.JSXExpressionContainer(expression));
return t.jSXAttribute(t.jSXIdentifier('className'), t.jSXExpressionContainer(expression));
}

@@ -78,3 +80,3 @@

if (state.opts.autoImportCssProp !== false) {
var cssImport = (0, _helperModuleImports.addNamed)(path, 'css', 'emotion');
var cssImport = (0, _helperModuleImports.addNamed)(path, 'css', state.emotionImportPath);
state.cssPropIdentifiers.push(cssImport);

@@ -88,3 +90,3 @@ return cssImport;

if (state.opts.autoImportCssProp !== false) {
return (0, _helperModuleImports.addNamed)(path, 'merge', 'emotion');
return (0, _helperModuleImports.addNamed)(path, 'merge', state.emotionImportPath);
} else {

@@ -91,0 +93,0 @@ return t.identifier(state.importedNames.merge);

@@ -5,5 +5,4 @@ 'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; // weak
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
exports.hashArray = hashArray;

@@ -25,2 +24,8 @@ exports.hoistPureArgs = hoistPureArgs;

enter: function enter(path, state) {
var hasFilepath = path.hub.file.opts.filename && path.hub.file.opts.filename !== 'unknown';
state.emotionImportPath = 'emotion';
if (state.opts.primaryInstance !== undefined) {
state.emotionImportPath = getInstancePathToImport(state.opts.primaryInstance, path.hub.file.opts.filename);
}
state.importedNames = _extends({}, defaultImportedNames, state.opts.importedNames);

@@ -44,5 +49,5 @@

var node = _ref;
var _node = _ref;
if (t.isModuleDeclaration(node)) {
if (t.isModuleDeclaration(_node)) {
isModule = true;

@@ -108,3 +113,6 @@ break;

}
var emotionPaths = defaultEmotionPaths.concat((state.opts.instances || []).map(function (instancePath) {
return getInstancePathToCompare(instancePath, process.cwd());
}));
var dirname = hasFilepath ? _path2.default.dirname(path.hub.file.opts.filename) : '';
imports.forEach(function (_ref3) {

@@ -115,5 +123,5 @@ var source = _ref3.source,

if (source.indexOf('emotion') !== -1) {
var importedNames = specifiers.filter(function (v) {
return ['default', 'css', 'keyframes', 'injectGlobal', 'fontFace', 'merge'].indexOf(v.imported) !== -1;
if (emotionPaths.indexOf(getInstancePathToCompare(source, dirname)) !== -1) {
var _importedNames = specifiers.filter(function (v) {
return importedNameKeys.indexOf(v.imported) !== -1;
}).reduce(function (acc, _ref4) {

@@ -126,3 +134,3 @@ var _extends2;

}, defaultImportedNames);
state.importedNames = _extends({}, importedNames, state.opts.importedNames);
state.importedNames = _extends({}, _importedNames, state.opts.importedNames);
}

@@ -151,3 +159,3 @@ });

var exists = _fs2.default.existsSync(cssFilename);
(0, _helperModuleImports.addSideEffect)(path, './' + (0, _path.basename)(cssFilename));
(0, _helperModuleImports.addSideEffect)(path, './' + _path2.default.basename(cssFilename));
if (exists ? _fs2.default.readFileSync(cssFilename, 'utf8') !== toWrite : true) {

@@ -177,2 +185,3 @@ if (!exists) {

enter: function enter(path, state) {
// $FlowFixMe
if (path[visited]) {

@@ -197,3 +206,2 @@ return;

case state.importedNames.injectGlobal:
case state.importedNames.fontFace:
if (state.opts.sourceMap === true && path.node.loc !== undefined) {

@@ -216,3 +224,3 @@ path.node.arguments.push(t.stringLiteral((0, _sourceMap.addSourceMaps)(path.node.loc.start, state)));

}
// $FlowFixMe
path[visited] = true;

@@ -233,5 +241,7 @@ },

TaggedTemplateExpression: function TaggedTemplateExpression(path, state) {
// $FlowFixMe
if (path[visited]) {
return;
}
// $FlowFixMe
path[visited] = true;

@@ -255,6 +265,2 @@ if (

});
} else if (path.node.tag.name === state.importedNames.fontFace) {
replaceCssWithCallExpression(path, path.node.tag, state, t, function (src, name, hash) {
return '@font-face {' + src + '}';
}, true);
} else if (path.node.tag.name === state.importedNames.injectGlobal) {

@@ -275,2 +281,6 @@ replaceCssWithCallExpression(path, path.node.tag, state, t, undefined, true, function () {

var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _findRoot = require('find-root');

@@ -280,4 +290,2 @@

var _path = require('path');
var _touch = require('touch');

@@ -332,13 +340,13 @@

var _createRawStringFromT = (0, _babelUtils.createRawStringFromTemplateLiteral)(path.node.quasi),
hash = _createRawStringFromT.hash,
src = _createRawStringFromT.src;
_hash = _createRawStringFromT.hash,
_src = _createRawStringFromT.src;
var identifierName = (0, _babelUtils.getIdentifierName)(path, t);
var name = (0, _babelUtils.getName)(identifierName, 'css');
var _name = (0, _babelUtils.getName)(identifierName, 'css');
if (state.extractStatic && !path.node.quasi.expressions.length) {
var staticCSSRules = staticStylis(staticCSSSelectorCreator(name, hash), staticCSSSrcCreator(src, name, hash));
var staticCSSRules = staticStylis(staticCSSSelectorCreator(_name, _hash), staticCSSSrcCreator(_src, _name, _hash));
state.insertStaticRules([staticCSSRules]);
if (!removePath) {
return path.replaceWith(t.stringLiteral(name + '-' + hash));
return path.replaceWith(t.stringLiteral(_name + '-' + _hash));
}

@@ -352,6 +360,6 @@ return path.replaceWith(t.identifier('undefined'));

if (state.opts.sourceMap === true && path.node.quasi.loc !== undefined) {
src += (0, _sourceMap.addSourceMaps)(path.node.quasi.loc.start, state);
_src += (0, _sourceMap.addSourceMaps)(path.node.quasi.loc.start, state);
}
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() + ';')] : [])));
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() + ';')] : [])));

@@ -372,2 +380,4 @@ if (state.opts.hoist) {

var unsafeRequire = require;
var getPackageRootPath = (0, _emotionUtils.memoize)(function (filename) {

@@ -391,13 +401,21 @@ return (0, _findRoot2.default)(filename);

rootPath = getPackageRootPath(filename);
moduleName = require(rootPath + '/package.json').name;
moduleName = unsafeRequire(rootPath + '/package.json').name;
} catch (err) {}
var finalPath = filename === rootPath ? (0, _path.basename)(filename) : filename.slice(rootPath.length);
var finalPath = filename === rootPath ? _path2.default.basename(filename) : filename.slice(rootPath.length);
var positionInFile = state.count++;
var stableClassName = (0, _babelUtils.getName)('' + hashArray([(0, _path.normalize)(finalPath), moduleName, state.file.code]) + positionInFile, 'css');
var stuffToHash = [moduleName];
if (finalPath) {
stuffToHash.push(_path2.default.normalize(finalPath));
} else {
stuffToHash.push(state.file.code);
}
var stableClassName = 'e' + hashArray(stuffToHash) + positionInFile;
return t.objectProperty(t.identifier('target'), t.stringLiteral(stableClassName));
}
function buildStyledCallExpression(identifier, tag, path, state, t) {

@@ -409,9 +427,8 @@ var identifierName = (0, _babelUtils.getIdentifierName)(path, t);

if (state.extractStatic && !path.node.quasi.expressions.length) {
var _createRawStringFromT2 = (0, _babelUtils.createRawStringFromTemplateLiteral)(path.node.quasi, identifierName, 'styled' // we don't want these styles to be merged in css``
),
hash = _createRawStringFromT2.hash,
_src = _createRawStringFromT2.src;
var _createRawStringFromT2 = (0, _babelUtils.createRawStringFromTemplateLiteral)(path.node.quasi),
_hash2 = _createRawStringFromT2.hash,
_src2 = _createRawStringFromT2.src;
var staticClassName = (0, _babelUtils.getName)(hash, 'css');
var staticCSSRules = staticStylis('.' + staticClassName, _src);
var staticClassName = 'css-' + _hash2;
var staticCSSRules = staticStylis('.' + staticClassName, _src2);

@@ -442,2 +459,3 @@ state.insertStaticRules([staticCSSRules]);

function buildStyledObjectCallExpression(path, state, identifier, t) {
var targetProperty = buildTargetObjectProperty(path, state, t);
var identifierName = (0, _babelUtils.getIdentifierName)(path, t);

@@ -451,5 +469,11 @@ var tag = t.isCallExpression(path.node.callee) ? path.node.callee.arguments[0] : t.stringLiteral(path.node.callee.property.name);

var objectProperties = [targetProperty];
if (state.opts.autoLabel && identifierName) {
objectProperties.push(t.objectProperty(t.identifier('label'), t.stringLiteral(identifierName.trim())));
}
path.addComment('leading', '#__PURE__');
return t.callExpression(t.callExpression(identifier, state.opts.autoLabel && identifierName ? [tag, t.objectExpression([t.objectProperty(t.identifier('label'), t.stringLiteral(identifierName.trim()))])] : [tag]), args);
return t.callExpression(t.callExpression(identifier, [tag, t.objectExpression(objectProperties)]), args);
}

@@ -464,4 +488,39 @@

injectGlobal: 'injectGlobal',
fontFace: 'fontFace',
merge: 'merge'
};
};
var importedNameKeys = Object.keys(defaultImportedNames).map(function (key) {
return key === 'styled' ? 'default' : key;
});
var defaultEmotionPaths = ['emotion', 'react-emotion', 'preact-emotion'];
function getRelativePath(filepath, absoluteInstancePath) {
var relativePath = _path2.default.relative(_path2.default.dirname(filepath), absoluteInstancePath);
return relativePath.charAt(0) === '.' ? relativePath : './' + relativePath;
}
function getAbsolutePath(instancePath, rootPath) {
if (instancePath.charAt(0) === '.') {
var absoluteInstancePath = _path2.default.resolve(rootPath, instancePath);
return absoluteInstancePath;
}
return false;
}
function getInstancePathToImport(instancePath, filepath) {
var absolutePath = getAbsolutePath(instancePath, process.cwd());
if (absolutePath === false) {
return instancePath;
}
return getRelativePath(filepath, absolutePath);
}
function getInstancePathToCompare(instancePath, rootPath) {
var absolutePath = getAbsolutePath(instancePath, rootPath);
if (absolutePath === false) {
return instancePath;
}
return absolutePath;
}

@@ -11,2 +11,3 @@ 'use strict';

function macro(_ref) {

@@ -21,3 +22,2 @@ var references = _ref.references,

case 'injectGlobal':
case 'fontFace':
{

@@ -24,0 +24,0 @@ isPure = false;

{
"name": "babel-plugin-emotion",
"version": "8.0.12",
"version": "9.0.0-0",
"description": "A recommended babel preprocessing plugin for emotion, The Next Generation of CSS-in-JS.",

@@ -21,3 +21,3 @@ "main": "lib/index.js",

"convert-source-map": "^1.5.0",
"emotion-utils": "^8.0.12",
"emotion-utils": "^9.0.0-0",
"find-root": "^1.1.0",

@@ -34,5 +34,5 @@ "source-map": "^0.5.7",

"author": "Kye Hohenberger",
"homepage": "https://github.com/tkh44/emotion#readme",
"homepage": "https://emotion.sh",
"license": "MIT",
"repository": "https://github.com/tkh44/emotion/tree/master/packages/babel-plugin-emotion",
"repository": "https://github.com/emotion-js/emotion/tree/master/packages/babel-plugin-emotion",
"keywords": [

@@ -46,4 +46,4 @@ "styles",

"bugs": {
"url": "https://github.com/tkh44/emotion/issues"
"url": "https://github.com/emotion-js/emotion/issues"
}
}

@@ -261,1 +261,27 @@ # babel-plugin-emotion

### `instances`
`Array<string>`, defaults to
`['emotion', 'react-emotion', 'preact-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**](docs/instances.md)
### `primaryInstance`
`string`, defaults to
`'emotion'`
This option allows `babel-plugin-emotion` to know where to import emotion from when it needs to import emotion. Currently this is only used for the css prop to import `css` and `merge` but it could be used for other purposes in the future so it's recommend to make sure that this instance exports everything returned from `createEmotion`, [an up-to-date example of this can be seen in the emotion package's source](https://github.com/emotion-js/emotion/blob/master/packages/emotion/src/index.js).
[**Documentation**](docs/instances.md)

@@ -1,4 +0,9 @@

const interleave = (strings, interpolations) =>
// @flow
import type { Types, Expression, StringLiteral } from 'babel-flow-types'
const interleave = (
strings: Array<StringLiteral>,
interpolations: Array<Expression>
) =>
interpolations.reduce(
(array, interp, i) => array.concat(interp, strings[i + 1]),
(array, interp, i) => array.concat([interp], strings[i + 1]),
[strings[0]]

@@ -8,13 +13,12 @@ )

export default class ASTObject {
props: Array<any>
expressions: Array<any>
composesCount: number
expressions: Array<Expression>
t: any
src: string
constructor(src, expressions, t) {
this.stringSrc = src
constructor(src: string, expressions: Array<Expression>, t: Types) {
this.src = src
this.expressions = expressions || []
this.t = t
}
getDynamicMatches(str) {
getDynamicMatches(str: string) {
const re = /xxx(\d+)xxx/gm

@@ -62,3 +66,6 @@ let match

return interleave(strings, finalExpressions).filter(
node => node.value !== ''
// $FlowFixMe
(node: StringLiteral) => {
return node.value !== ''
}
)

@@ -68,6 +75,6 @@ }

return this.replacePlaceholdersWithExpressions(
this.getDynamicMatches(this.stringSrc),
this.stringSrc
this.getDynamicMatches(this.src),
this.src
)
}
}

@@ -0,4 +1,8 @@

// @flow
import { hashArray } from './index'
import type { BabelPath, EmotionBabelPluginPass } from './index'
import type { Types, Identifier } from 'babel-flow-types'
function getDeclaratorName(path, t) {
function getDeclaratorName(path: BabelPath, t: Types) {
// $FlowFixMe
const parent = path.findParent(p => p.isVariableDeclarator())

@@ -8,4 +12,8 @@ return parent && t.isIdentifier(parent.node.id) ? parent.node.id.name : ''

export function getIdentifierName(path, t) {
const classParent = path.findParent(p => t.isClass(p))
export function getIdentifierName(path: BabelPath, t: Types) {
let classParent
if (path) {
// $FlowFixMe
classParent = path.findParent(p => t.isClass(p))
}
if (classParent && classParent.node.id) {

@@ -24,3 +32,4 @@ return t.isIdentifier(classParent.node.id) ? classParent.node.id.name : ''

export function getRuntimeImportPath(path, t) {
export function getRuntimeImportPath(path: BabelPath, t: Types) {
// $FlowFixMe
const binding = path.scope.getBinding(path.node.name)

@@ -36,3 +45,16 @@ if (!t.isImportDeclaration(binding.path.parentPath)) {

export function buildMacroRuntimeNode(path, state, importName, t) {
type EmotionMacroPluginPass = EmotionBabelPluginPass & {
emotionImports: void | {
[key: string]: {
[key: string]: Identifier
}
}
}
export function buildMacroRuntimeNode(
path: BabelPath,
state: EmotionMacroPluginPass,
importName: string,
t: Types
) {
const runtimeImportPath = getRuntimeImportPath(path, t)

@@ -44,2 +66,3 @@ if (state.emotionImports === undefined) state.emotionImports = {}

if (state.emotionImports[runtimeImportPath][importName] === undefined) {
// $FlowFixMe
state.emotionImports[runtimeImportPath][

@@ -52,23 +75,26 @@ importName

export function addRuntimeImports(state, t) {
if (state.emotionImports === undefined) return
Object.keys(state.emotionImports).forEach(importPath => {
const importSpecifiers = []
Object.keys(state.emotionImports[importPath]).forEach(importName => {
const identifier = state.emotionImports[importPath][importName]
if (importName === 'default') {
importSpecifiers.push(t.importDefaultSpecifier(identifier))
} else {
importSpecifiers.push(
t.importSpecifier(identifier, t.identifier(importName))
)
}
export function addRuntimeImports(state: EmotionMacroPluginPass, t: Types) {
if (state.emotionImports) {
const emotionImports = state.emotionImports
Object.keys(emotionImports).forEach(importPath => {
const importSpecifiers = []
Object.keys(emotionImports[importPath]).forEach(importName => {
const identifier = emotionImports[importPath][importName]
if (importName === 'default') {
importSpecifiers.push(t.importDefaultSpecifier(identifier))
} else {
importSpecifiers.push(
t.importSpecifier(identifier, t.identifier(importName))
)
}
})
// $FlowFixMe
state.file.path.node.body.unshift(
t.importDeclaration(importSpecifiers, t.stringLiteral(importPath))
)
})
state.file.path.node.body.unshift(
t.importDeclaration(importSpecifiers, t.stringLiteral(importPath))
)
})
state.emotionImports = undefined
state.emotionImports = undefined
}
}
export function getName(identifierName?: string, prefix: string): string {
export function getName(identifierName?: string, prefix: string) {
const parts = []

@@ -84,3 +110,3 @@ parts.push(prefix)

quasis: Array<{ value: { cooked: string } }>
}): { src: string, dynamicValueCount: number } {
}) {
let strs = quasi.quasis.map(x => x.value.cooked)

@@ -124,3 +150,3 @@ let hash = hashArray([...strs])

export const minify = code =>
export const minify = (code: string) =>
code.split(symbolRegex).reduce((str, fragment, index) => {

@@ -127,0 +153,0 @@ // Even-indices are non-symbol fragments

@@ -0,5 +1,12 @@

// @flow
import { addNamed } from '@babel/helper-module-imports'
import { addSourceMaps } from './source-map'
import type { BabelPath, EmotionBabelPluginPass } from './index'
import type { Types } from 'babel-flow-types'
export default function(path, state, t) {
export default function(
path: BabelPath,
state: EmotionBabelPluginPass,
t: Types
) {
let cssPath

@@ -69,26 +76,28 @@ let classNamesPath

cssPath.parentPath.remove()
if (t.isJSXExpressionContainer(classNamesValue)) {
const args = [
add(
cssTemplateExpression,
add(t.stringLiteral(' '), classNamesValue.expression)
)
]
if (state.opts.sourceMap) {
args.push(t.stringLiteral(addSourceMaps(cssPath.node.loc.start, state)))
}
classNamesPath.parentPath.replaceWith(
createClassNameAttr(t.callExpression(getMergeIdentifier(), args))
)
} else {
classNamesPath.parentPath.replaceWith(
createClassNameAttr(
if (classNamesPath && classNamesPath.parentPath) {
if (t.isJSXExpressionContainer(classNamesValue)) {
const args = [
add(
cssTemplateExpression,
t.stringLiteral(` ${classNamesValue.value || ''}`)
add(t.stringLiteral(' '), classNamesValue.expression)
)
]
if (state.opts.sourceMap) {
args.push(t.stringLiteral(addSourceMaps(cssPath.node.loc.start, state)))
}
classNamesPath.parentPath.replaceWith(
createClassNameAttr(t.callExpression(getMergeIdentifier(), args))
)
)
} else {
classNamesPath.parentPath.replaceWith(
createClassNameAttr(
add(
cssTemplateExpression,
t.stringLiteral(` ${classNamesValue.value || ''}`)
)
)
)
}
}

@@ -103,3 +112,3 @@

t.jSXIdentifier('className'),
t.JSXExpressionContainer(expression)
t.jSXExpressionContainer(expression)
)

@@ -110,3 +119,3 @@ }

if (state.opts.autoImportCssProp !== false) {
const cssImport = addNamed(path, 'css', 'emotion')
const cssImport = addNamed(path, 'css', state.emotionImportPath)
state.cssPropIdentifiers.push(cssImport)

@@ -120,3 +129,3 @@ return cssImport

if (state.opts.autoImportCssProp !== false) {
return addNamed(path, 'merge', 'emotion')
return addNamed(path, 'merge', state.emotionImportPath)
} else {

@@ -123,0 +132,0 @@ return t.identifier(state.importedNames.merge)

@@ -1,5 +0,5 @@

// @flow weak
// @flow
import fs from 'fs'
import nodePath from 'path'
import findRoot from 'find-root'
import { basename, normalize } from 'path'
import { touchSync } from 'touch'

@@ -13,3 +13,10 @@ import { addSideEffect } from '@babel/helper-module-imports'

} from './babel-utils'
import type {
BabelPath as _BabelPath,
Identifier,
BabelPluginPass,
Types,
StringLiteral,
Babel
} from 'babel-flow-types'
import { hashString, Stylis, memoize } from 'emotion-utils'

@@ -21,3 +28,7 @@ import { addSourceMaps } from './source-map'

export function hashArray(arr) {
export type BabelPath = _BabelPath & {
node: *
}
export function hashArray(arr: Array<string>) {
return hashString(arr.join(''))

@@ -28,3 +39,3 @@ }

export function hoistPureArgs(path) {
export function hoistPureArgs(path: BabelPath) {
const args = path.get('arguments')

@@ -41,10 +52,36 @@

type ImportedNames = {
css: string,
keyframes: string,
injectGlobal: string,
styled: string,
merge: string
}
export type EmotionBabelPluginPass = BabelPluginPass & {
extractStatic: boolean,
insertStaticRules: (rules: Array<string>) => void,
emotionImportPath: string,
staticRules: Array<string>,
cssPropIdentifiers: Array<Identifier>,
importedNames: ImportedNames,
count: number,
opts: any
}
export function replaceCssWithCallExpression(
path,
identifier,
state,
t,
staticCSSSrcCreator = src => src,
removePath = false,
staticCSSSelectorCreator = (name, hash) => `.${name}-${hash}`
path: BabelPath,
identifier: Identifier,
state: EmotionBabelPluginPass,
t: Types,
staticCSSSrcCreator: (
src: string,
name: string,
hash: string
) => string = src => src,
removePath: boolean = false,
staticCSSSelectorCreator: (name: string, hash: string) => string = (
name,
hash
) => `.${name}-${hash}`
) {

@@ -102,2 +139,4 @@ try {

const unsafeRequire = require
const getPackageRootPath = memoize(filename => findRoot(filename))

@@ -119,18 +158,22 @@

rootPath = getPackageRootPath(filename)
moduleName = require(rootPath + '/package.json').name
moduleName = unsafeRequire(rootPath + '/package.json').name
} catch (err) {}
const finalPath =
filename === rootPath ? basename(filename) : filename.slice(rootPath.length)
filename === rootPath
? nodePath.basename(filename)
: filename.slice(rootPath.length)
const positionInFile = state.count++
const stableClassName = getName(
`${hashArray([
normalize(finalPath),
moduleName,
state.file.code
])}${positionInFile}`,
'css'
)
const stuffToHash = [moduleName]
if (finalPath) {
stuffToHash.push(nodePath.normalize(finalPath))
} else {
stuffToHash.push(state.file.code)
}
const stableClassName = `e${hashArray(stuffToHash)}${positionInFile}`
return t.objectProperty(

@@ -141,4 +184,9 @@ t.identifier('target'),

}
export function buildStyledCallExpression(identifier, tag, path, state, t) {
export function buildStyledCallExpression(
identifier: Identifier,
tag: StringLiteral,
path: BabelPath,
state: EmotionBabelPluginPass,
t: Types
) {
const identifierName = getIdentifierName(path, t)

@@ -149,8 +197,4 @@

if (state.extractStatic && !path.node.quasi.expressions.length) {
const { hash, src } = createRawStringFromTemplateLiteral(
path.node.quasi,
identifierName,
'styled' // we don't want these styles to be merged in css``
)
const staticClassName = getName(hash, 'css')
const { hash, src } = createRawStringFromTemplateLiteral(path.node.quasi)
const staticClassName = `css-${hash}`
const staticCSSRules = staticStylis(`.${staticClassName}`, src)

@@ -198,3 +242,9 @@

export function buildStyledObjectCallExpression(path, state, identifier, t) {
export function buildStyledObjectCallExpression(
path: BabelPath,
state: EmotionBabelPluginPass,
identifier: Identifier,
t: Types
) {
const targetProperty = buildTargetObjectProperty(path, state, t)
const identifierName = getIdentifierName(path, t)

@@ -210,19 +260,17 @@ const tag = t.isCallExpression(path.node.callee)

const objectProperties = [targetProperty]
if (state.opts.autoLabel && identifierName) {
objectProperties.push(
t.objectProperty(
t.identifier('label'),
t.stringLiteral(identifierName.trim())
)
)
}
path.addComment('leading', '#__PURE__')
return t.callExpression(
t.callExpression(
identifier,
state.opts.autoLabel && identifierName
? [
tag,
t.objectExpression([
t.objectProperty(
t.identifier('label'),
t.stringLiteral(identifierName.trim())
)
])
]
: [tag]
),
t.callExpression(identifier, [tag, t.objectExpression(objectProperties)]),
args

@@ -234,3 +282,3 @@ )

const defaultImportedNames = {
const defaultImportedNames: ImportedNames = {
styled: 'styled',

@@ -240,7 +288,45 @@ css: 'css',

injectGlobal: 'injectGlobal',
fontFace: 'fontFace',
merge: 'merge'
}
export default function(babel) {
const importedNameKeys = Object.keys(defaultImportedNames).map(
key => (key === 'styled' ? 'default' : key)
)
const defaultEmotionPaths = ['emotion', 'react-emotion', 'preact-emotion']
function getRelativePath(filepath: string, absoluteInstancePath: string) {
let relativePath = nodePath.relative(
nodePath.dirname(filepath),
absoluteInstancePath
)
return relativePath.charAt(0) === '.' ? relativePath : `./${relativePath}`
}
function getAbsolutePath(instancePath: string, rootPath: string) {
if (instancePath.charAt(0) === '.') {
let absoluteInstancePath = nodePath.resolve(rootPath, instancePath)
return absoluteInstancePath
}
return false
}
function getInstancePathToImport(instancePath: string, filepath: string) {
let absolutePath = getAbsolutePath(instancePath, process.cwd())
if (absolutePath === false) {
return instancePath
}
return getRelativePath(filepath, absolutePath)
}
function getInstancePathToCompare(instancePath: string, rootPath: string) {
let absolutePath = getAbsolutePath(instancePath, rootPath)
if (absolutePath === false) {
return instancePath
}
return absolutePath
}
export default function(babel: Babel) {
const { types: t } = babel

@@ -253,3 +339,14 @@

Program: {
enter(path, state) {
enter(path: BabelPath, state: EmotionBabelPluginPass) {
const hasFilepath =
path.hub.file.opts.filename &&
path.hub.file.opts.filename !== 'unknown'
state.emotionImportPath = 'emotion'
if (state.opts.primaryInstance !== undefined) {
state.emotionImportPath = getInstancePathToImport(
state.opts.primaryInstance,
path.hub.file.opts.filename
)
}
state.importedNames = {

@@ -312,17 +409,18 @@ ...defaultImportedNames,

}
const emotionPaths = defaultEmotionPaths.concat(
(state.opts.instances || []).map(instancePath =>
getInstancePathToCompare(instancePath, process.cwd())
)
)
let dirname = hasFilepath
? nodePath.dirname(path.hub.file.opts.filename)
: ''
imports.forEach(({ source, imported, specifiers }) => {
if (source.indexOf('emotion') !== -1) {
if (
emotionPaths.indexOf(
getInstancePathToCompare(source, dirname)
) !== -1
) {
const importedNames = specifiers
.filter(
v =>
[
'default',
'css',
'keyframes',
'injectGlobal',
'fontFace',
'merge'
].indexOf(v.imported) !== -1
)
.filter(v => importedNameKeys.indexOf(v.imported) !== -1)
.reduce(

@@ -352,3 +450,3 @@ (acc, { imported, local }) => ({

},
exit(path, state) {
exit(path: BabelPath, state: EmotionBabelPluginPass) {
if (state.staticRules.length !== 0) {

@@ -361,3 +459,3 @@ const toWrite = state.staticRules.join('\n').trim()

const exists = fs.existsSync(cssFilename)
addSideEffect(path, './' + basename(cssFilename))
addSideEffect(path, './' + nodePath.basename(cssFilename))
if (

@@ -374,3 +472,3 @@ exists ? fs.readFileSync(cssFilename, 'utf8') !== toWrite : true

},
JSXOpeningElement(path, state) {
JSXOpeningElement(path: BabelPath, state: EmotionBabelPluginPass) {
cssProps(path, state, t)

@@ -392,3 +490,4 @@ if (state.opts.hoist) {

CallExpression: {
enter(path, state) {
enter(path: BabelPath, state: EmotionBabelPluginPass) {
// $FlowFixMe
if (path[visited]) {

@@ -414,3 +513,2 @@ return

case state.importedNames.injectGlobal:
case state.importedNames.fontFace:
if (

@@ -448,6 +546,6 @@ state.opts.sourceMap === true &&

}
// $FlowFixMe
path[visited] = true
},
exit(path, state) {
exit(path: BabelPath, state: EmotionBabelPluginPass) {
try {

@@ -472,6 +570,8 @@ if (

},
TaggedTemplateExpression(path, state) {
TaggedTemplateExpression(path: BabelPath, state: EmotionBabelPluginPass) {
// $FlowFixMe
if (path[visited]) {
return
}
// $FlowFixMe
path[visited] = true

@@ -522,11 +622,2 @@ if (

)
} else if (path.node.tag.name === state.importedNames.fontFace) {
replaceCssWithCallExpression(
path,
path.node.tag,
state,
t,
(src, name, hash) => `@font-face {${src}}`,
true
)
} else if (path.node.tag.name === state.importedNames.injectGlobal) {

@@ -533,0 +624,0 @@ replaceCssWithCallExpression(

@@ -0,1 +1,2 @@

// @flow
import {

@@ -2,0 +3,0 @@ buildStyledCallExpression,

@@ -0,1 +1,2 @@

// @flow
import { replaceCssWithCallExpression } from './index'

@@ -11,4 +12,3 @@ import { buildMacroRuntimeNode, addRuntimeImports } from './babel-utils'

switch (referenceKey) {
case 'injectGlobal':
case 'fontFace': {
case 'injectGlobal': {
isPure = false

@@ -15,0 +15,0 @@ }

@@ -0,3 +1,6 @@

// @flow
import { SourceMapGenerator } from 'source-map'
import convert from 'convert-source-map'
import type { EmotionBabelPluginPass } from './index'
import type { BabelFile } from 'babel-flow-types'

@@ -8,3 +11,3 @@ function getGeneratorOpts(file) {

export function makeSourceMapGenerator(file) {
export function makeSourceMapGenerator(file: BabelFile) {
const generatorOpts = getGeneratorOpts(file)

@@ -21,3 +24,6 @@ const filename = generatorOpts.sourceFileName

export function addSourceMaps(offset, state) {
export function addSourceMaps(
offset: { line: number, column: number },
state: EmotionBabelPluginPass
) {
const generator = makeSourceMapGenerator(state.file)

@@ -24,0 +30,0 @@ const generatorOpts = getGeneratorOpts(state.file)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc