Skip to content

Commit

Permalink
Fix support for Global transformer with importMap
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Nov 17, 2019
1 parent 831d1d4 commit 687e9d8
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as React from 'react'
import { SomeGlobalFromCore } from 'package-two'

const getBgColor = () => ({ backgroundColor: '#fff' })

export default () => (
<SomeGlobalFromCore styles={{ color: 'hotpink', ...getBgColor() }} />
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as React from 'react'
import { SomeGlobalFromCore } from 'package-two'

export default () => <SomeGlobalFromCore styles={{ color: 'hotpink' }} />
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`import mapping global 1`] = `
"import * as React from 'react'
import { SomeGlobalFromCore } from 'package-two'
export default () => <SomeGlobalFromCore styles={{ color: 'hotpink' }} />
↓ ↓ ↓ ↓ ↓ ↓
function _EMOTION_STRINGIFIED_CSS_ERROR__() { return \\"You have tried to stringify object returned from \`css\` function. It isn't supposed to be used directly (e.g. as value of the \`className\` prop), but rather handed to emotion so it can handle it (e.g. as value of \`css\` prop).\\"; }
import * as React from 'react';
import { SomeGlobalFromCore } from 'package-two';
var _ref = process.env.NODE_ENV === \\"production\\" ? {
name: \\"1lrxbo5\\",
styles: \\"color:hotpink;\\"
} : {
name: \\"1lrxbo5\\",
styles: \\"color:hotpink;\\",
map: \\"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImdsb2JhbC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHeUMiLCJmaWxlIjoiZ2xvYmFsLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBTb21lR2xvYmFsRnJvbUNvcmUgfSBmcm9tICdwYWNrYWdlLXR3bydcblxuZXhwb3J0IGRlZmF1bHQgKCkgPT4gPFNvbWVHbG9iYWxGcm9tQ29yZSBzdHlsZXM9e3sgY29sb3I6ICdob3RwaW5rJyB9fSAvPlxuIl19 */\\",
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
};
export default (() => <SomeGlobalFromCore styles={_ref} />);"
`;

exports[`import mapping global-needs-css 1`] = `
"import * as React from 'react'
import { SomeGlobalFromCore } from 'package-two'
const getBgColor = () => ({ backgroundColor: '#fff' })
export default () => (
<SomeGlobalFromCore styles={{ color: 'hotpink', ...getBgColor() }} />
)
↓ ↓ ↓ ↓ ↓ ↓
import { someCssFromCore as _css } from \\"package-two\\";
import * as React from 'react';
import { SomeGlobalFromCore } from 'package-two';
const getBgColor = () => ({
backgroundColor: '#fff'
});
export default (() => <SomeGlobalFromCore styles={
/*#__PURE__*/
_css({
color: 'hotpink',
...getBgColor()
}, process.env.NODE_ENV === \\"production\\" ? \\"\\" : \\"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImdsb2JhbC1uZWVkcy1jc3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBTXNCIiwiZmlsZSI6Imdsb2JhbC1uZWVkcy1jc3MuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IFNvbWVHbG9iYWxGcm9tQ29yZSB9IGZyb20gJ3BhY2thZ2UtdHdvJ1xuXG5jb25zdCBnZXRCZ0NvbG9yID0gKCkgPT4gKHsgYmFja2dyb3VuZENvbG9yOiAnI2ZmZicgfSlcblxuZXhwb3J0IGRlZmF1bHQgKCkgPT4gKFxuICA8U29tZUdsb2JhbEZyb21Db3JlIHN0eWxlcz17eyBjb2xvcjogJ2hvdHBpbmsnLCAuLi5nZXRCZ0NvbG9yKCkgfX0gLz5cbilcbiJdfQ== */\\")} />);"
`;

exports[`import mapping jsx 1`] = `
"/** @jsx someJsx */
import { someJsx } from 'package-two'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ babelTester('import mapping', __dirname, {
},
someCssFromCore: {
canonicalImport: ['@emotion/core', 'css']
},
SomeGlobalFromCore: {
canonicalImport: ['@emotion/core', 'Global']
}
},

Expand Down
36 changes: 29 additions & 7 deletions packages/babel-plugin-emotion/src/core-macro.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ export const transformCssCallExpression = ({
export const transformInlineCsslessExpression = ({
state,
babel,
path
path,
cssImport = { importSource: '@emotion/core', cssExport: 'css' }
}: {
babel: *,
state: *,
path: *
path: *,
cssImport?: { importSource: string, cssExport: string }
}) => {
let t = babel.types
let expressionPath = path.get('value.expression')
Expand All @@ -66,12 +68,12 @@ export const transformInlineCsslessExpression = ({
sourceMap
})

const { importSource = '@emotion/core', cssExport = 'css' } = state

if (t.isCallExpression(expressionPath)) {
expressionPath
.get('callee')
.replaceWith(addImport(state, importSource, cssExport, 'css'))
.replaceWith(
addImport(state, cssImport.importSource, cssImport.cssExport, 'css')
)
}
}

Expand All @@ -87,7 +89,19 @@ let cssTransformer = ({
transformCssCallExpression({ babel, state, path: reference.parentPath })
}

let globalTransformer = ({ state, babel, reference }) => {
let globalTransformer = ({
state,
babel,
reference,
importSource,
options
}: {
state: any,
babel: any,
reference: any,
importSource: string,
options: { cssExport?: string }
}) => {
const t = babel.types

if (
Expand All @@ -110,7 +124,15 @@ let globalTransformer = ({ state, babel, reference }) => {
(t.isObjectExpression(stylesPropPath.node.value.expression) ||
t.isArrayExpression(stylesPropPath.node.value.expression))
) {
transformInlineCsslessExpression({ state, babel, path: stylesPropPath })
transformInlineCsslessExpression({
state,
babel,
path: stylesPropPath,
cssImport: options.cssExport !== undefined && {
importSource,
cssExport: options.cssExport
}
})
}
}

Expand Down
61 changes: 40 additions & 21 deletions packages/babel-plugin-emotion/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ import coreMacro, {
} from './core-macro'
import { getStyledOptions, createTransformerMacro } from './utils'

const getCssExport = (reexported, importSource, mapping) => {
const cssExport = Object.keys(mapping).find(localExportName => {
const [packageName, exportName] = mapping[localExportName].canonicalImport
return packageName === '@emotion/core' && exportName === 'css'
})

if (!cssExport) {
throw new Error(
`You have specified that '${importSource}' re-exports '${reexported}' from '@emotion/core' but it doesn't also re-export 'css' from '@emotion/core', 'css' is necessary for certain optimisations, please re-export it from '${importSource}'`
)
}

return cssExport
}

let webStyledMacro = createStyledMacro({
importSource: '@emotion/styled/base',
originalImportSource: '@emotion/styled',
Expand Down Expand Up @@ -122,7 +137,7 @@ export default function(babel: *) {
let jsxCoreImports: Array<{
importSource: string,
export: string,
cssExport: string | null
cssExport: string
}> = [
{ importSource: '@emotion/core', export: 'jsx', cssExport: 'css' }
]
Expand All @@ -137,7 +152,7 @@ export default function(babel: *) {
jsxCoreImports.push({
importSource,
export: localExportName,
cssExport: null
cssExport: getCssExport('jsx', importSource, value)
})
return
}
Expand All @@ -149,6 +164,22 @@ export default function(babel: *) {
)
}

let extraOptions

if (packageName === '@emotion/core' && exportName === 'Global') {
// this option is not supposed to be set in importMap
extraOptions = {
cssExport: getCssExport('Global', importSource, value)
}
} else if (
packageName === '@emotion/styled' &&
exportName === 'default'
) {
// this is supposed to override defaultOptions value
// and let correct value to be set if coming in options
extraOptions = { styledBaseImport: undefined }
}

let [exportTransformer, defaultOptions] =
// $FlowFixMe
Array.isArray(packageTransformers[exportName])
Expand All @@ -157,30 +188,13 @@ export default function(babel: *) {

transformers[localExportName] = [
exportTransformer,
{ ...defaultOptions, styledBaseImport: undefined, ...options }
{ ...defaultOptions, ...extraOptions, ...options }
]
})
macros[importSource] = createTransformerMacro(transformers, {
importSource
})
})
jsxCoreImports.forEach(jsxCoreImport => {
if (jsxCoreImport.importSource === '@emotion/core') return
let { transformers } = macros[jsxCoreImport.importSource]
for (let key in transformers) {
if (transformers[key][0] === coreTransformers.css) {
jsxCoreImport.cssExport = key
return
}
}
throw new Error(
`You have specified that '${
jsxCoreImport.importSource
}' re-exports 'jsx' from '@emotion/core' but it doesn't also re-export 'css' from '@emotion/core', 'css' is necessary for certain optimisations, please re-export it from '${
jsxCoreImport.importSource
}'`
)
})
state.pluginMacros = {
'@emotion/styled': webStyledMacro,
'@emotion/core': coreMacro,
Expand Down Expand Up @@ -227,7 +241,12 @@ export default function(babel: *) {
(t.isObjectExpression(path.node.value.expression) ||
t.isArrayExpression(path.node.value.expression))
) {
transformInlineCsslessExpression({ state, babel, path })
transformInlineCsslessExpression({
state,
babel,
path,
cssImport: state.jsxCoreImport
})
}
},
CallExpression: {
Expand Down

0 comments on commit 687e9d8

Please sign in to comment.