Skip to content

Commit 067fcd7

Browse files
authored
fix: load babel macro dynamically (#812)
1 parent 2a31e73 commit 067fcd7

File tree

7 files changed

+134
-192
lines changed

7 files changed

+134
-192
lines changed

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
],
2424
"typings": "./index.d.ts",
2525
"scripts": {
26-
"build": "rm -rf dist && rm -rf out && yarn build-babel && yarn build-webpack && yarn build-index",
27-
"build-babel": "bunchee src/babel.js -f cjs --runtime node -e react -e babel-plugin-macros -o dist/babel/index.js",
28-
"build-webpack": "bunchee src/webpack.js -f cjs --runtime node -e react -e babel-plugin-macros -o dist/webpack/index.js",
26+
"build-babel": "bunchee src/babel.js -f cjs -e babel-plugin-macros --runtime node -o dist/babel/index.js",
27+
"build": "rm -rf dist && rm -rf out && yarn build-webpack && yarn build-index && yarn build-babel",
28+
"build-webpack": "bunchee src/webpack.js -f cjs --runtime node -o dist/webpack/index.js",
2929
"build-index": "bunchee src/index.js -f cjs --runtime node -o dist/index/index.js",
3030
"test": "ava",
3131
"lint": "eslint ./src",
@@ -79,7 +79,7 @@
7979
"@babel/types": "7.15.0",
8080
"ava": "4.3.1",
8181
"babel-plugin-macros": "2.8.0",
82-
"bunchee": "2.0.3",
82+
"bunchee": "2.0.4",
8383
"convert-source-map": "1.7.0",
8484
"eslint": "7.32.0",
8585
"eslint-config-prettier": "4.0.0",

src/babel.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { default as babelMacro } from './macro'
2020
import { default as babelTest } from './babel-test'
2121

2222
export function macro() {
23-
return babelMacro
23+
return babelMacro(require('babel-plugin-macros'))
2424
}
2525

2626
export function test() {

src/macro.js

Lines changed: 101 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,121 +1,124 @@
1-
import { createMacro, MacroError } from 'babel-plugin-macros'
21
import { processTaggedTemplateExpression } from './babel-external'
32
import {
43
setStateOptions,
54
createReactComponentImportDeclaration
65
} from './_utils'
76
import { STYLE_COMPONENT } from './_constants'
87

9-
export default createMacro(styledJsxMacro)
8+
export default ({ createMacro, MacroError }) => {
9+
return createMacro(styledJsxMacro)
1010

11-
function styledJsxMacro({ references, state }) {
12-
setStateOptions(state)
11+
function styledJsxMacro({ references, state }) {
12+
setStateOptions(state)
1313

14-
// Holds a reference to all the lines where strings are tagged using the `css` tag name.
15-
// We print a warning at the end of the macro in case there is any reference to css,
16-
// because `css` is generally used as default import name for 'styled-jsx/css'.
17-
// People who want to migrate from this macro to pure styled-jsx might have name conflicts issues.
18-
const cssReferences = []
14+
// Holds a reference to all the lines where strings are tagged using the `css` tag name.
15+
// We print a warning at the end of the macro in case there is any reference to css,
16+
// because `css` is generally used as default import name for 'styled-jsx/css'.
17+
// People who want to migrate from this macro to pure styled-jsx might have name conflicts issues.
18+
const cssReferences = []
1919

20-
// references looks like this
21-
// {
22-
// default: [path, path],
23-
// resolve: [path],
24-
// }
25-
Object.keys(references).forEach(refName => {
26-
// Enforce `resolve` as named import so people
27-
// can only import { resolve } from 'styled-jsx/macro'
28-
// or an alias of it eg. { resolve as foo }
29-
if (refName !== 'default' && refName !== 'resolve') {
30-
throw new MacroError(
31-
`Imported an invalid named import: ${refName}. Please import: resolve`
32-
)
33-
}
20+
// references looks like this
21+
// {
22+
// default: [path, path],
23+
// resolve: [path],
24+
// }
25+
Object.keys(references).forEach(refName => {
26+
// Enforce `resolve` as named import so people
27+
// can only import { resolve } from 'styled-jsx/macro'
28+
// or an alias of it eg. { resolve as foo }
29+
if (refName !== 'default' && refName !== 'resolve') {
30+
throw new MacroError(
31+
`Imported an invalid named import: ${refName}. Please import: resolve`
32+
)
33+
}
3434

35-
// Start processing the references for refName
36-
references[refName].forEach(path => {
37-
// We grab the parent path. Eg.
38-
// path -> css
39-
// path.parenPath -> css`div { color: red }`
40-
let templateExpression = path.parentPath
35+
// Start processing the references for refName
36+
references[refName].forEach(path => {
37+
// We grab the parent path. Eg.
38+
// path -> css
39+
// path.parenPath -> css`div { color: red }`
40+
let templateExpression = path.parentPath
4141

42-
// templateExpression member expression?
43-
// path -> css
44-
// path.parentPath -> css.resolve
45-
if (templateExpression.isMemberExpression()) {
46-
// grab .resolve
47-
const tagPropertyName = templateExpression.get('property').node.name
48-
// Member expressions are only valid on default imports
49-
// eg. import css from 'styled-jsx/macro'
50-
if (refName !== 'default') {
51-
throw new MacroError(
52-
`Can't use named import ${path.node.name} as a member expression: ${
53-
path.node.name
54-
}.${tagPropertyName}\`div { color: red }\` Please use it directly: ${
55-
path.node.name
56-
}\`div { color: red }\``
57-
)
58-
}
42+
// templateExpression member expression?
43+
// path -> css
44+
// path.parentPath -> css.resolve
45+
if (templateExpression.isMemberExpression()) {
46+
// grab .resolve
47+
const tagPropertyName = templateExpression.get('property').node.name
48+
// Member expressions are only valid on default imports
49+
// eg. import css from 'styled-jsx/macro'
50+
if (refName !== 'default') {
51+
throw new MacroError(
52+
`Can't use named import ${
53+
path.node.name
54+
} as a member expression: ${
55+
path.node.name
56+
}.${tagPropertyName}\`div { color: red }\` Please use it directly: ${
57+
path.node.name
58+
}\`div { color: red }\``
59+
)
60+
}
5961

60-
// Otherwise enforce `css.resolve`
61-
if (tagPropertyName !== 'resolve') {
62-
throw new MacroError(
63-
`Using an invalid tag: ${tagPropertyName}. Please use ${
64-
templateExpression.get('object').node.name
65-
}.resolve`
66-
)
67-
}
62+
// Otherwise enforce `css.resolve`
63+
if (tagPropertyName !== 'resolve') {
64+
throw new MacroError(
65+
`Using an invalid tag: ${tagPropertyName}. Please use ${
66+
templateExpression.get('object').node.name
67+
}.resolve`
68+
)
69+
}
6870

69-
// Grab the TaggedTemplateExpression
70-
// i.e. css.resolve`div { color: red }`
71-
templateExpression = templateExpression.parentPath
72-
} else {
73-
if (refName === 'default') {
74-
const { name } = path.node
75-
throw new MacroError(
76-
`Can't use default import directly eg. ${name}\`div { color: red }\`. Please use ${name}.resolve\`div { color: red }\` instead.`
77-
)
78-
}
71+
// Grab the TaggedTemplateExpression
72+
// i.e. css.resolve`div { color: red }`
73+
templateExpression = templateExpression.parentPath
74+
} else {
75+
if (refName === 'default') {
76+
const { name } = path.node
77+
throw new MacroError(
78+
`Can't use default import directly eg. ${name}\`div { color: red }\`. Please use ${name}.resolve\`div { color: red }\` instead.`
79+
)
80+
}
7981

80-
if (path.node.name === 'css') {
81-
// If the path node name is `css` we push it to the references above to emit a warning later.
82-
cssReferences.push(path.node.loc.start.line)
82+
if (path.node.name === 'css') {
83+
// If the path node name is `css` we push it to the references above to emit a warning later.
84+
cssReferences.push(path.node.loc.start.line)
85+
}
8386
}
84-
}
8587

86-
if (!state.styleComponentImportName) {
87-
const programPath = path.findParent(p => p.isProgram())
88-
state.styleComponentImportName = programPath.scope.generateUidIdentifier(
89-
STYLE_COMPONENT
90-
).name
91-
const importDeclaration = createReactComponentImportDeclaration(state)
92-
programPath.unshiftContainer('body', importDeclaration)
93-
}
88+
if (!state.styleComponentImportName) {
89+
const programPath = path.findParent(p => p.isProgram())
90+
state.styleComponentImportName = programPath.scope.generateUidIdentifier(
91+
STYLE_COMPONENT
92+
).name
93+
const importDeclaration = createReactComponentImportDeclaration(state)
94+
programPath.unshiftContainer('body', importDeclaration)
95+
}
9496

95-
// Finally transform the path :)
96-
processTaggedTemplateExpression({
97-
type: 'resolve',
98-
path: templateExpression,
99-
file: state.file,
100-
splitRules:
101-
typeof state.opts.optimizeForSpeed === 'boolean'
102-
? state.opts.optimizeForSpeed
103-
: process.env.NODE_ENV === 'production',
104-
plugins: state.plugins,
105-
vendorPrefixes: state.opts.vendorPrefixes,
106-
sourceMaps: state.opts.sourceMaps,
107-
styleComponentImportName: state.styleComponentImportName
97+
// Finally transform the path :)
98+
processTaggedTemplateExpression({
99+
type: 'resolve',
100+
path: templateExpression,
101+
file: state.file,
102+
splitRules:
103+
typeof state.opts.optimizeForSpeed === 'boolean'
104+
? state.opts.optimizeForSpeed
105+
: process.env.NODE_ENV === 'production',
106+
plugins: state.plugins,
107+
vendorPrefixes: state.opts.vendorPrefixes,
108+
sourceMaps: state.opts.sourceMaps,
109+
styleComponentImportName: state.styleComponentImportName
110+
})
108111
})
109112
})
110-
})
111113

112-
if (cssReferences.length > 0) {
113-
console.warn(
114-
`styled-jsx - Warning - We detected that you named your tag as \`css\` at lines: ${cssReferences.join(
115-
', '
116-
)}.\n` +
117-
'This tag name is usually used as default import name for `styled-jsx/css`.\n' +
118-
'Porting macro code to pure styled-jsx in the future might be a bit problematic.'
119-
)
114+
if (cssReferences.length > 0) {
115+
console.warn(
116+
`styled-jsx - Warning - We detected that you named your tag as \`css\` at lines: ${cssReferences.join(
117+
', '
118+
)}.\n` +
119+
'This tag name is usually used as default import name for `styled-jsx/css`.\n' +
120+
'Porting macro code to pure styled-jsx in the future might be a bit problematic.'
121+
)
122+
}
120123
}
121124
}

test/fixtures/macro.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import css, { resolve } from '../../src/macro'
1+
import css, { resolve } from '../../test/helpers/babel-test.macro'
22

33
const { className, styles } = resolve`
44
div { color: red }

test/helpers/babel-test.macro.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { macro } from '../../src/babel'
2+
3+
const m = macro()
4+
console.log('m', m)
5+
export default m

test/macro.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ test('transpiles correctly', async t => {
2727
test('throws when using the default export directly', async t => {
2828
const { message } = await t.throwsAsync(() =>
2929
transformSource(`
30-
import css from './src/macro'
30+
import css from './test/helpers/babel-test.macro'
3131
3232
css\`div { color: red }\`
3333
`)
@@ -39,7 +39,7 @@ test('throws when using the default export directly', async t => {
3939
test('throws when using the default export directly and it is not called css', async t => {
4040
const { message } = await t.throwsAsync(() =>
4141
transformSource(`
42-
import foo from './src/macro'
42+
import foo from './test/helpers/babel-test.macro'
4343
4444
foo\`div { color: red }\`
4545
`)
@@ -51,7 +51,7 @@ test('throws when using the default export directly and it is not called css', a
5151
test('throws when using the default export directly and it is not called resolve', async t => {
5252
const { message } = await t.throwsAsync(() =>
5353
transformSource(`
54-
import resolve from './src/macro'
54+
import resolve from './test/helpers/babel-test.macro'
5555
5656
resolve\`div { color: red }\`
5757
`)
@@ -63,7 +63,7 @@ test('throws when using the default export directly and it is not called resolve
6363
test('throws when using an invalid method from the default export', async t => {
6464
const { message } = await t.throwsAsync(() =>
6565
transformSource(`
66-
import css from './src/macro'
66+
import css from './test/helpers/babel-test.macro'
6767
6868
css.foo\`div { color: red }\`
6969
`)
@@ -75,7 +75,7 @@ test('throws when using an invalid method from the default export', async t => {
7575
test('throws when using a named import different than resolve', async t => {
7676
const { message } = await t.throwsAsync(() =>
7777
transformSource(`
78-
import { foo } from './src/macro'
78+
import { foo } from './test/helpers/babel-test.macro'
7979
8080
foo\`div { color: red }\`
8181
`)
@@ -87,7 +87,7 @@ test('throws when using a named import different than resolve', async t => {
8787
test('throws when using a named import as a member expression', async t => {
8888
const { message } = await t.throwsAsync(() =>
8989
transformSource(`
90-
import { resolve } from './src/macro'
90+
import { resolve } from './test/helpers/babel-test.macro'
9191
9292
resolve.foo\`div { color: red }\`
9393
`)
@@ -98,7 +98,7 @@ test('throws when using a named import as a member expression', async t => {
9898

9999
test('can alias the named import', async t => {
100100
const { code } = await transformSource(`
101-
import { resolve as foo } from './src/macro'
101+
import { resolve as foo } from './test/helpers/babel-test.macro'
102102
103103
foo\`div { color: red }\`
104104
`)
@@ -107,7 +107,7 @@ test('can alias the named import', async t => {
107107

108108
test('injects JSXStyle for nested scope', async t => {
109109
const { code } = await transformSource(`
110-
import { resolve } from './src/macro'
110+
import { resolve } from './test/helpers/babel-test.macro'
111111
112112
function test() {
113113
resolve\`div { color: red }\`

0 commit comments

Comments
 (0)