Skip to content

Commit

Permalink
Fixed an issue with styles containing a trailing css variable not bei…
Browse files Browse the repository at this point in the history
…ng inserted correctly where the styled were optimized by our Babel plugin to a static opaque object
  • Loading branch information
Andarist committed Mar 11, 2021
1 parent 5bf3522 commit 40a8344
Show file tree
Hide file tree
Showing 11 changed files with 931 additions and 28 deletions.
7 changes: 7 additions & 0 deletions .changeset/sixty-pants-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@emotion/cache': patch
'@emotion/react': patch
'@emotion/styled': patch
---

Fixed an issue with styles containing a trailing css variable not being inserted correctly where the styled were optimized by our Babel plugin to a static opaque object.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@
"@babel/plugin-syntax-jsx": "^7.12.1",
"@babel/plugin-transform-flow-strip-types": "^7.6.3",
"@babel/plugin-transform-react-jsx": "^7.12.1",
"@babel/preset-env": "^7.7.1",
"@babel/preset-env": "^7.13.10",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.12.1",
"@babel/register": "^7.7.0",
Expand Down
51 changes: 34 additions & 17 deletions packages/babel-plugin/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ import coreMacro, {
} from './core-macro'
import { getStyledOptions, createTransformerMacro } from './utils'

const EMOTION_BABEL_PLUGIN_ANNOTATION_REGEX = /\*?\s*@emotion\/babel-plugin\s+(.+$)/

// this is really intended to only be used internally
const getEmotionBabelPluginPragmaOptions = state => {
if (!state.file.ast.comments) {
return {}
}
return state.file.ast.comments
.map(comment => comment.value.match(EMOTION_BABEL_PLUGIN_ANNOTATION_REGEX))
.filter(Boolean)
.map(match => JSON.parse(`{${match[1]}}`))
.reduce((a, b) => Object.assign(a, b), {})
}

const getCssExport = (reexported, importSource, mapping) => {
const cssExport = Object.keys(mapping).find(localExportName => {
const [packageName, exportName] = mapping[localExportName].canonicalImport
Expand Down Expand Up @@ -75,17 +89,18 @@ export type EmotionBabelPluginPass = any

const AUTO_LABEL_VALUES = ['dev-only', 'never', 'always']

export default function(babel: *, options: *) {
if (
options.autoLabel !== undefined &&
!AUTO_LABEL_VALUES.includes(options.autoLabel)
) {
const validateAutoLabel = value => {
if (value !== undefined && !AUTO_LABEL_VALUES.includes(value)) {
throw new Error(
`The 'autoLabel' option must be undefined, or one of the following: ${AUTO_LABEL_VALUES.map(
s => `"${s}"`
).join(', ')}`
)
}
}

export default function(babel: *, options: *) {
validateAutoLabel(options.autoLabel)

let t = babel.types
return {
Expand Down Expand Up @@ -147,6 +162,20 @@ export default function(babel: *, options: *) {
})
},
Program(path: *, state: *) {
const pragmaOptions = getEmotionBabelPluginPragmaOptions(state)

state.transformCssProp =
(pragmaOptions.cssPropOptimization ??
state.opts.cssPropOptimization) !== false
state.emotionSourceMap =
(pragmaOptions.sourceMap ?? state.opts.sourceMap) !== false
state.emotionAutoLabel =
pragmaOptions.autoLabel ?? state.opts.autoLabel ?? 'dev-only'
state.emotionLabelFormat =
pragmaOptions.labelFormat ?? state.opts.labelFormat

validateAutoLabel(state.emotionAutoLabel)

let macros = {}
let jsxReactImports: Array<{
importSource: string,
Expand Down Expand Up @@ -240,18 +269,6 @@ export default function(babel: *, options: *) {
}
}
}

if (state.opts.cssPropOptimization === false) {
state.transformCssProp = false
} else {
state.transformCssProp = true
}

if (state.opts.sourceMap === false) {
state.emotionSourceMap = false
} else {
state.emotionSourceMap = true
}
},
JSXAttribute(path: *, state: *) {
if (path.node.name.name !== 'css' || !state.transformCssProp) {
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-plugin/src/utils/get-styled-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const createObjectSpreadLike = (t, file, ...objs) =>
t.callExpression(file.addHelper('extends'), [t.objectExpression([]), ...objs])

export let getStyledOptions = (t: *, path: *, state: *) => {
const autoLabel = state.opts.autoLabel || 'dev-only'
const autoLabel = state.emotionAutoLabel

let args = path.node.arguments
let optionsArgument = args.length >= 2 ? args[1] : null
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-plugin/src/utils/label.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function getLabel(
export function getLabelFromPath(path: *, state: *, t: *) {
return getLabel(
getIdentifierName(path, t),
state.opts.labelFormat,
state.emotionLabelFormat,
state.file.opts.filename
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export let transformExpressionWithStyles = ({
shouldLabel: boolean,
sourceMap?: string
}): * => {
const autoLabel = state.opts.autoLabel || 'dev-only'
const autoLabel = state.emotionAutoLabel
let t = babel.types
if (t.isTaggedTemplateExpression(path)) {
if (
Expand Down
4 changes: 3 additions & 1 deletion packages/cache/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ let createCache = (options: Options): EmotionCache => {
}
}

stylis(selector ? `${selector}{${serialized.styles}}` : serialized.styles)
stylis(
selector ? `${selector}{${serialized.styles};}` : serialized.styles
)

if (shouldCache) {
cache.inserted[serialized.name] = true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should insert opaque style object with trailing css variable 1`] = `
.emotion-0 {
color: hotpink;
--some-variable: 16px;
}
<div
className="emotion-0"
>
Text
</div>
`;
23 changes: 23 additions & 0 deletions packages/react/__tests__/babel/no-extra-babel-generated-content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/** @jsx jsx */
/** @emotion/babel-plugin "autoLabel": "never" */
/** @emotion/babel-plugin "sourceMap": false */

import 'test-utils/next-env'
import { jsx, css } from '@emotion/react'
import renderer from 'react-test-renderer'

test('should insert opaque style object with trailing css variable', () => {
// styles here are simple enough so they are transformed by Babel to the opaque style with {name, styles} shape
const tree = renderer.create(
<div
css={css`
color: hotpink;
--some-variable: 16px;
`}
>
Text
</div>
)

expect(tree.toJSON()).toMatchSnapshot()
})
2 changes: 1 addition & 1 deletion site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "emotion site",
"version": "9.3.0",
"dependencies": {
"@babel/preset-env": "^7.7.1",
"@babel/preset-env": "^7.13.10",
"@babel/preset-react": "^7.12.1",
"@babel/standalone": "^7.7.3",
"@mdx-js/mdx": "^1.1.0",
Expand Down

0 comments on commit 40a8344

Please sign in to comment.