babel-plugin-codegen version: 4.0.0
node version: not sure, I used Code Sandbox
npm (or yarn) version: not sure, I used Code Sandbox
Relevant code or config
import codegen from "babel-plugin-codegen/macro";
// Based on https://github.com/kentcdodds/babel-plugin-codegen#use-with-babel-plugin-macros
// except using 1 item in the array, not several.
codegen`module.exports = ['a'].map(l => 'export const ' + l + ' = ' + JSON.stringify(l)).join(';')`;
// Or more simply:
codegen`module.exports = 'export const a = "a";'`;
What you did: a little hard to see from the CodeSandbox, but the above input will be compiled like so:
// ↓ ↓ ↓ ↓ ↓ ↓
(function () {
export var a = "a";
})();
What happened: led to a SyntaxError
SyntaxError: Unexpected token 'export'
because it was wrapped into an IIFE by Babel.
Note that if you check out the repo instead of CodeSandbox, the error you get is
./src/codegen.js 4:2
Module parse failed: 'import' and 'export' may only appear at the top level (4:2)
You may need an appropriate loader to handle this file type.
| // Or more simply:
| (function () {
> export var a = "a";
| })();
Reproduction repository: https://github.com/NMinhNguyen/babel-plugin-codegen-single-export-import-issue/blob/master/src/codegen.js
Problem description: There is currently a workaround such as including an extra semicolon ; to ensure it gets treated as multiple statements:
-codegen`module.exports = 'export const a = "a";'`;
+codegen`module.exports = 'export const a = "a";;'`;
because then multiple statements are emitted, and the logic at
|
} else if (Array.isArray(replacement)) { |
|
path.replaceWithMultiple(replacement) |
|
} else { |
|
path.replaceWith(replacement) |
|
} |
won't call
path.replaceWith(replacement) which wraps single statements into an IIFE (
https://github.com/babel/babel/blob/d50e78d/packages/babel-traverse/src/path/replacement.js#L213-L224) if
toSequenceExpression was false-y.
Suggested solution: I was initially thinking to always call path.replaceWithMultiple(replacement), where replacement could be made a 1-item array if it's not an array already, but I'm not sure of the impact of that. Perhaps we could add this workaround to the README for now? Unless someone else knows that it's a safe thing to do for sure?
babel-plugin-codegenversion: 4.0.0nodeversion: not sure, I used Code Sandboxnpm(oryarn) version: not sure, I used Code SandboxRelevant code or config
What you did: a little hard to see from the CodeSandbox, but the above input will be compiled like so:
What happened: led to a
SyntaxErrorbecause it was wrapped into an IIFE by Babel.
Note that if you check out the repo instead of CodeSandbox, the error you get is
Reproduction repository: https://github.com/NMinhNguyen/babel-plugin-codegen-single-export-import-issue/blob/master/src/codegen.js
Problem description: There is currently a workaround such as including an extra semicolon
;to ensure it gets treated as multiple statements:because then multiple statements are emitted, and the logic at
babel-plugin-codegen/src/helpers.js
Lines 54 to 58 in ff9fcc6
path.replaceWith(replacement)which wraps single statements into an IIFE (https://github.com/babel/babel/blob/d50e78d/packages/babel-traverse/src/path/replacement.js#L213-L224) iftoSequenceExpressionwas false-y.Suggested solution: I was initially thinking to always call
path.replaceWithMultiple(replacement), wherereplacementcould be made a 1-item array if it's not an array already, but I'm not sure of the impact of that. Perhaps we could add this workaround to theREADMEfor now? Unless someone else knows that it's a safe thing to do for sure?