Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
183 lines
4.2 KiB
Plaintext
183 lines
4.2 KiB
Plaintext
import {
|
|
transformExpressionWithStyles,
|
|
createTransformerMacro,
|
|
getSourceMap,
|
|
addImport
|
|
} from './utils'
|
|
|
|
export const transformCssCallExpression = (
|
|
{ state, babel, path, sourceMap, annotateAsPure = true } /*: {
|
|
state: *,
|
|
babel: *,
|
|
path: *,
|
|
sourceMap?: string,
|
|
annotateAsPure?: boolean
|
|
} */
|
|
) => {
|
|
let node = transformExpressionWithStyles({
|
|
babel,
|
|
state,
|
|
path,
|
|
shouldLabel: true,
|
|
sourceMap
|
|
})
|
|
if (node) {
|
|
path.replaceWith(node)
|
|
path.hoist()
|
|
} else if (annotateAsPure && path.isCallExpression()) {
|
|
path.addComment('leading', '#__PURE__')
|
|
}
|
|
}
|
|
|
|
export const transformCsslessArrayExpression = (
|
|
{ state, babel, path } /*: {
|
|
babel: *,
|
|
state: *,
|
|
path: *
|
|
} */
|
|
) => {
|
|
let t = babel.types
|
|
let expressionPath = path.get('value.expression')
|
|
let sourceMap =
|
|
state.emotionSourceMap && path.node.loc !== undefined
|
|
? getSourceMap(path.node.loc.start, state)
|
|
: ''
|
|
|
|
expressionPath.replaceWith(
|
|
t.callExpression(
|
|
// the name of this identifier doesn't really matter at all
|
|
// it'll never appear in generated code
|
|
t.identifier('___shouldNeverAppearCSS'),
|
|
path.node.value.expression.elements
|
|
)
|
|
)
|
|
|
|
transformCssCallExpression({
|
|
babel,
|
|
state,
|
|
path: expressionPath,
|
|
sourceMap,
|
|
annotateAsPure: false
|
|
})
|
|
|
|
if (t.isCallExpression(expressionPath)) {
|
|
expressionPath.replaceWith(t.arrayExpression(expressionPath.node.arguments))
|
|
}
|
|
}
|
|
|
|
export const transformCsslessObjectExpression = (
|
|
{ state, babel, path, cssImport } /*: {
|
|
babel: *,
|
|
state: *,
|
|
path: *,
|
|
cssImport: { importSource: string, cssExport: string }
|
|
} */
|
|
) => {
|
|
let t = babel.types
|
|
let expressionPath = path.get('value.expression')
|
|
let sourceMap =
|
|
state.emotionSourceMap && path.node.loc !== undefined
|
|
? getSourceMap(path.node.loc.start, state)
|
|
: ''
|
|
|
|
expressionPath.replaceWith(
|
|
t.callExpression(
|
|
// the name of this identifier doesn't really matter at all
|
|
// it'll never appear in generated code
|
|
t.identifier('___shouldNeverAppearCSS'),
|
|
[path.node.value.expression]
|
|
)
|
|
)
|
|
|
|
transformCssCallExpression({
|
|
babel,
|
|
state,
|
|
path: expressionPath,
|
|
sourceMap
|
|
})
|
|
|
|
if (t.isCallExpression(expressionPath)) {
|
|
expressionPath
|
|
.get('callee')
|
|
.replaceWith(
|
|
addImport(state, cssImport.importSource, cssImport.cssExport, 'css')
|
|
)
|
|
}
|
|
}
|
|
|
|
let cssTransformer = (
|
|
{ state, babel, reference } /*: {
|
|
state: any,
|
|
babel: any,
|
|
reference: any
|
|
} */
|
|
) => {
|
|
transformCssCallExpression({ babel, state, path: reference.parentPath })
|
|
}
|
|
|
|
let globalTransformer = (
|
|
{ state, babel, reference, importSource, options } /*: {
|
|
state: any,
|
|
babel: any,
|
|
reference: any,
|
|
importSource: string,
|
|
options: { cssExport?: string }
|
|
} */
|
|
) => {
|
|
const t = babel.types
|
|
|
|
if (
|
|
!t.isJSXIdentifier(reference.node) ||
|
|
!t.isJSXOpeningElement(reference.parentPath.node)
|
|
) {
|
|
return
|
|
}
|
|
|
|
const stylesPropPath = reference.parentPath
|
|
.get('attributes')
|
|
.find(p => t.isJSXAttribute(p.node) && p.node.name.name === 'styles')
|
|
|
|
if (!stylesPropPath) {
|
|
return
|
|
}
|
|
|
|
if (t.isJSXExpressionContainer(stylesPropPath.node.value)) {
|
|
if (t.isArrayExpression(stylesPropPath.node.value.expression)) {
|
|
transformCsslessArrayExpression({
|
|
state,
|
|
babel,
|
|
path: stylesPropPath
|
|
})
|
|
} else if (t.isObjectExpression(stylesPropPath.node.value.expression)) {
|
|
transformCsslessObjectExpression({
|
|
state,
|
|
babel,
|
|
path: stylesPropPath,
|
|
cssImport:
|
|
options.cssExport !== undefined
|
|
? {
|
|
importSource,
|
|
cssExport: options.cssExport
|
|
}
|
|
: {
|
|
importSource: '@emotion/react',
|
|
cssExport: 'css'
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
export const transformers = {
|
|
// this is an empty function because this transformer is never called
|
|
// we don't run any transforms on `jsx` directly
|
|
// instead we use it as a hint to enable css prop optimization
|
|
jsx: () => {},
|
|
css: cssTransformer,
|
|
Global: globalTransformer
|
|
}
|
|
|
|
export default createTransformerMacro(transformers, {
|
|
importSource: '@emotion/react'
|
|
})
|