|
1 | | -import { createMacro, MacroError } from 'babel-plugin-macros' |
2 | 1 | import { processTaggedTemplateExpression } from './babel-external' |
3 | 2 | import { |
4 | 3 | setStateOptions, |
5 | 4 | createReactComponentImportDeclaration |
6 | 5 | } from './_utils' |
7 | 6 | import { STYLE_COMPONENT } from './_constants' |
8 | 7 |
|
9 | | -export default createMacro(styledJsxMacro) |
| 8 | +export default ({ createMacro, MacroError }) => { |
| 9 | + return createMacro(styledJsxMacro) |
10 | 10 |
|
11 | | -function styledJsxMacro({ references, state }) { |
12 | | - setStateOptions(state) |
| 11 | + function styledJsxMacro({ references, state }) { |
| 12 | + setStateOptions(state) |
13 | 13 |
|
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 = [] |
19 | 19 |
|
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 | + } |
34 | 34 |
|
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 |
41 | 41 |
|
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 | + } |
59 | 61 |
|
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 | + } |
68 | 70 |
|
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 | + } |
79 | 81 |
|
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 | + } |
83 | 86 | } |
84 | | - } |
85 | 87 |
|
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 | + } |
94 | 96 |
|
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 | + }) |
108 | 111 | }) |
109 | 112 | }) |
110 | | - }) |
111 | 113 |
|
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 | + } |
120 | 123 | } |
121 | 124 | } |
0 commit comments