From 6a67aca6a0429cf931bc9eeb64da253183af6471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Tue, 11 May 2021 17:23:38 -0400 Subject: [PATCH] fix: check export specifier in getLocalExportMetadata --- .../src/normalize-and-load-metadata.ts | 23 +++++++++++++++---- .../export-namespace-without-plugin/input.mjs | 2 ++ .../options.json | 3 +++ .../fixtures/noInterop-loose/options.json | 5 ++++ 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/export-namespace-without-plugin/input.mjs create mode 100644 packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/export-namespace-without-plugin/options.json create mode 100644 packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/options.json diff --git a/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts b/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts index 45046e0bc0f1..35e1b02b17d4 100644 --- a/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts +++ b/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.ts @@ -189,6 +189,20 @@ function getExportSpecifierName( } } +function assertExportSpecifier( + path: NodePath, +): asserts path is NodePath { + if (path.isExportSpecifier()) { + return; + } else if (path.isExportNamespaceSpecifier()) { + throw path.buildCodeFrameError( + "Export namespace should be first transformed by `@babel/plugin-proposal-export-namespace-from`.", + ); + } else { + throw path.buildCodeFrameError("Unexpected export specifier type"); + } +} + /** * Get metadata about the imports and exports present in this module. */ @@ -307,9 +321,7 @@ function getModuleMetadata( if (!data.loc) data.loc = child.node.loc; child.get("specifiers").forEach(spec => { - if (!spec.isExportSpecifier()) { - throw spec.buildCodeFrameError("Unexpected export specifier type"); - } + assertExportSpecifier(spec); const importName = getExportSpecifierName( spec.get("local"), stringSpecifiers, @@ -415,8 +427,9 @@ function getLocalExportMetadata( child.node.source && child.get("source").isStringLiteral() ) { - child.node.specifiers.forEach(specifier => { - bindingKindLookup.set(specifier.local.name, "block"); + child.get("specifiers").forEach(spec => { + assertExportSpecifier(spec); + bindingKindLookup.set(spec.get("local").node.name, "block"); }); return; } diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/export-namespace-without-plugin/input.mjs b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/export-namespace-without-plugin/input.mjs new file mode 100644 index 000000000000..df12dc3fa5e1 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/export-namespace-without-plugin/input.mjs @@ -0,0 +1,2 @@ +export * as ns from "./foo"; + diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/export-namespace-without-plugin/options.json b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/export-namespace-without-plugin/options.json new file mode 100644 index 000000000000..46be7d0eabe3 --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/export-namespace-without-plugin/options.json @@ -0,0 +1,3 @@ +{ + "throws": "Export namespace should be first transformed by `@babel/plugin-proposal-export-namespace-from`." +} diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/options.json b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/options.json new file mode 100644 index 000000000000..adeea0a6893f --- /dev/null +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/noInterop-loose/options.json @@ -0,0 +1,5 @@ +{ + "plugins": [ + ["transform-modules-commonjs", { "noInterop": true, "loose": true }] + ] +}