Thanks to visit codestin.com
Credit goes to github.com

Skip to content

SyntaxError when a single import/export statement is used #30

@NMinhNguyen

Description

@NMinhNguyen
  • 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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions