From 0a2a37c31f004e37611008287807fa584bac30f9 Mon Sep 17 00:00:00 2001 From: Artem Yavorsky Date: Wed, 29 Nov 2017 21:58:29 +0200 Subject: [PATCH] Fix `export from` assignment order for loose mode. (#6863) * Consider reexports for bindingKindLookup. * Update test cases according to reexports change * Fix order for assign reexports. * void 0 assignation to module keys only for loose mode. * Create buildReexportsFromMeta helper. * Update umd/amd fixtures. * Refactor reexports build. * Hoist template for reexports. * Use map as a second argument of Array.from. * Remove unnecessary export. --- .../src/index.js | 51 ++++++++++++------- .../src/normalize-and-load-metadata.js | 30 +++++++---- .../fixtures/loose/export-from-2/expected.js | 1 + .../fixtures/loose/export-from-3/expected.js | 1 + .../fixtures/loose/export-from-4/expected.js | 1 + .../fixtures/loose/export-from-5/expected.js | 1 + .../fixtures/loose/export-from-6/expected.js | 1 + .../loose/noInterop-export-from/expected.js | 1 + .../src/index.js | 1 - .../interop-loose/export-from-2/expected.js | 4 +- .../interop-loose/export-from-3/expected.js | 6 ++- .../interop-loose/export-from-4/expected.js | 4 +- .../interop-loose/export-from-5/expected.js | 4 +- .../interop-loose/export-from-6/expected.js | 6 ++- .../interop-loose/export-from-7/expected.js | 4 +- .../interop-loose/export-from-8/expected.js | 5 +- .../fixtures/loose/export-from-2/expected.js | 1 + .../fixtures/loose/export-from-3/expected.js | 1 + .../fixtures/loose/export-from-4/expected.js | 1 + .../fixtures/loose/export-from-5/expected.js | 1 + .../fixtures/loose/export-from/expected.js | 1 + 21 files changed, 87 insertions(+), 39 deletions(-) diff --git a/packages/babel-helper-module-transforms/src/index.js b/packages/babel-helper-module-transforms/src/index.js index 186f1ad3be..522a1438dc 100644 --- a/packages/babel-helper-module-transforms/src/index.js +++ b/packages/babel-helper-module-transforms/src/index.js @@ -29,6 +29,7 @@ export function rewriteModuleStatementsAndPrepareHeader( const meta = normalizeAndLoadModuleMetadata(path, exportName, { noInterop, + loose, }); if (!allowTopLevelThis) { @@ -55,6 +56,7 @@ export function rewriteModuleStatementsAndPrepareHeader( } const nameList = buildExportNameListDeclaration(path, meta); + if (nameList) { meta.exportNameListName = nameList.name; headers.push(nameList.statement); @@ -126,6 +128,9 @@ export function buildNamespaceInitStatements( }), ); } + if (loose) { + statements.push(...buildReexportsFromMeta(metadata, sourceMetadata, loose)); + } for (const exportName of sourceMetadata.reexportNamespace) { // Assign export to namespace object. statements.push( @@ -150,6 +155,31 @@ export function buildNamespaceInitStatements( return statements; } +const getTemplateForReexport = loose => { + return loose + ? template.statement`EXPORTS.EXPORT_NAME = NAMESPACE.IMPORT_NAME;` + : template` + Object.defineProperty(EXPORTS, "EXPORT_NAME", { + enumerable: true, + get: function() { + return NAMESPACE.IMPORT_NAME; + }, + }); + `; +}; + +const buildReexportsFromMeta = (meta, metadata, loose) => { + const templateForCurrentMode = getTemplateForReexport(loose); + return Array.from(metadata.reexports, ([exportName, importName]) => + templateForCurrentMode({ + EXPORTS: meta.exportName, + EXPORT_NAME: exportName, + NAMESPACE: metadata.name, + IMPORT_NAME: importName, + }), + ); +}; + /** * Build an "__esModule" header statement setting the property on a given object. */ @@ -269,25 +299,10 @@ function buildExportInitializationStatements( exportNames.push(...data.names); } } + for (const data of metadata.source.values()) { - for (const [exportName, importName] of data.reexports) { - initStatements.push( - (loose - ? template.statement`EXPORTS.EXPORT_NAME = NAMESPACE.IMPORT_NAME;` - : template` - Object.defineProperty(EXPORTS, "EXPORT_NAME", { - enumerable: true, - get: function() { - return NAMESPACE.IMPORT_NAME; - }, - }); - `)({ - EXPORTS: metadata.exportName, - EXPORT_NAME: exportName, - NAMESPACE: data.name, - IMPORT_NAME: importName, - }), - ); + if (!loose) { + initStatements.push(...buildReexportsFromMeta(metadata, data, loose)); } for (const exportName of data.reexportNamespace) { exportNames.push(exportName); diff --git a/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.js b/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.js index 87890a3a6c..2e5f254474 100644 --- a/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.js +++ b/packages/babel-helper-module-transforms/src/normalize-and-load-metadata.js @@ -86,7 +86,7 @@ export function isSideEffectImport(source: SourceModuleMetadata) { export default function normalizeModuleAndLoadMetadata( programPath: NodePath, exportName?: string, - { noInterop = false } = {}, + { noInterop = false, loose = false } = {}, ): ModuleMetadata { if (!exportName) { exportName = programPath.scope.generateUidIdentifier("exports").name; @@ -94,7 +94,7 @@ export default function normalizeModuleAndLoadMetadata( nameAnonymousExports(programPath); - const { local, source } = getModuleMetadata(programPath); + const { local, source } = getModuleMetadata(programPath, loose); removeModuleDeclarations(programPath); @@ -120,8 +120,8 @@ export default function normalizeModuleAndLoadMetadata( /** * Get metadata about the imports and exports present in this module. */ -function getModuleMetadata(programPath: NodePath) { - const localData = getLocalExportMetadata(programPath); +function getModuleMetadata(programPath: NodePath, loose: boolean) { + const localData = getLocalExportMetadata(programPath, loose); const sourceData = new Map(); const getData = sourceNode => { @@ -260,6 +260,7 @@ function getModuleMetadata(programPath: NodePath) { */ function getLocalExportMetadata( programPath: NodePath, + loose: boolean, ): Map { const bindingKindLookup = new Map(); @@ -269,8 +270,19 @@ function getLocalExportMetadata( kind = "import"; } else { if (child.isExportDefaultDeclaration()) child = child.get("declaration"); - if (child.isExportNamedDeclaration() && child.node.declaration) { - child = child.get("declaration"); + if (child.isExportNamedDeclaration()) { + if (child.node.declaration) { + child = child.get("declaration"); + } else if ( + loose && + child.node.source && + child.get("source").isStringLiteral() + ) { + child.node.specifiers.forEach(specifier => { + bindingKindLookup.set(specifier.local.name, "block"); + }); + return; + } } if (child.isFunctionDeclaration()) { @@ -295,6 +307,7 @@ function getLocalExportMetadata( const getLocalMetadata = idPath => { const localName = idPath.node.name; let metadata = localMetadata.get(localName); + if (!metadata) { const kind = bindingKindLookup.get(localName); @@ -314,7 +327,7 @@ function getLocalExportMetadata( }; programPath.get("body").forEach(child => { - if (child.isExportNamedDeclaration() && !child.node.source) { + if (child.isExportNamedDeclaration() && (loose || !child.node.source)) { if (child.node.declaration) { const declaration = child.get("declaration"); const ids = declaration.getOuterBindingIdentifierPaths(); @@ -324,7 +337,6 @@ function getLocalExportMetadata( 'Illegal export "__esModule".', ); } - getLocalMetadata(ids[name]).names.push(name); }); } else { @@ -335,7 +347,6 @@ function getLocalExportMetadata( if (exported.node.name === "__esModule") { throw exported.buildCodeFrameError('Illegal export "__esModule".'); } - getLocalMetadata(local).names.push(exported.node.name); }); } @@ -354,7 +365,6 @@ function getLocalExportMetadata( } } }); - return localMetadata; } diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-2/expected.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-2/expected.js index 36a7d9081e..35117cd749 100644 --- a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-2/expected.js +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-2/expected.js @@ -2,5 +2,6 @@ define(["exports", "foo"], function (_exports, _foo) { "use strict"; _exports.__esModule = true; + _exports.foo = void 0; _exports.foo = _foo.foo; }); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-3/expected.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-3/expected.js index 8e2a65f922..ebb27ba6e8 100644 --- a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-3/expected.js +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-3/expected.js @@ -2,6 +2,7 @@ define(["exports", "foo"], function (_exports, _foo) { "use strict"; _exports.__esModule = true; + _exports.bar = _exports.foo = void 0; _exports.foo = _foo.foo; _exports.bar = _foo.bar; }); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-4/expected.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-4/expected.js index 67d4ff8925..7bdea461e5 100644 --- a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-4/expected.js +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-4/expected.js @@ -2,5 +2,6 @@ define(["exports", "foo"], function (_exports, _foo) { "use strict"; _exports.__esModule = true; + _exports.bar = void 0; _exports.bar = _foo.foo; }); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-5/expected.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-5/expected.js index 8dd82c261c..0c422e03b7 100644 --- a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-5/expected.js +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-5/expected.js @@ -2,5 +2,6 @@ define(["exports", "foo"], function (_exports, _foo) { "use strict"; _exports.__esModule = true; + _exports.default = void 0; _exports.default = _foo.foo; }); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-6/expected.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-6/expected.js index b17d2a42ae..a27b4a9df0 100644 --- a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-6/expected.js +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from-6/expected.js @@ -2,6 +2,7 @@ define(["exports", "foo"], function (_exports, _foo) { "use strict"; _exports.__esModule = true; + _exports.bar = _exports.default = void 0; _exports.default = _foo.foo; _exports.bar = _foo.bar; }); diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/noInterop-export-from/expected.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/noInterop-export-from/expected.js index 6670c43181..198468a7d0 100644 --- a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/noInterop-export-from/expected.js +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/noInterop-export-from/expected.js @@ -2,5 +2,6 @@ define(["exports", "foo"], function (_exports, _foo) { "use strict"; _exports.__esModule = true; + _exports.default = void 0; _exports.default = _foo.default; }); diff --git a/packages/babel-plugin-transform-modules-commonjs/src/index.js b/packages/babel-plugin-transform-modules-commonjs/src/index.js index e65c8bd96e..b0066a9774 100644 --- a/packages/babel-plugin-transform-modules-commonjs/src/index.js +++ b/packages/babel-plugin-transform-modules-commonjs/src/index.js @@ -16,7 +16,6 @@ export default function(api, options) { strict, strictMode, noInterop, - // Defaulting to 'true' for now. May change before 7.x major. allowCommonJSExports = true, } = options; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-2/expected.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-2/expected.js index 433c1c3ebc..22d457d6f9 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-2/expected.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-2/expected.js @@ -1,6 +1,8 @@ "use strict"; exports.__esModule = true; -exports.foo = _foo.foo; +exports.foo = void 0; var _foo = require("foo"); + +exports.foo = _foo.foo; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-3/expected.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-3/expected.js index 2529d6d951..57b882aca9 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-3/expected.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-3/expected.js @@ -1,7 +1,9 @@ "use strict"; exports.__esModule = true; -exports.foo = _foo.foo; -exports.bar = _foo.bar; +exports.bar = exports.foo = void 0; var _foo = require("foo"); + +exports.foo = _foo.foo; +exports.bar = _foo.bar; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-4/expected.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-4/expected.js index 46ca416dd8..8104e090ea 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-4/expected.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-4/expected.js @@ -1,6 +1,8 @@ "use strict"; exports.__esModule = true; -exports.bar = _foo.foo; +exports.bar = void 0; var _foo = require("foo"); + +exports.bar = _foo.foo; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-5/expected.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-5/expected.js index da307ddc71..24548dae60 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-5/expected.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-5/expected.js @@ -1,6 +1,8 @@ "use strict"; exports.__esModule = true; -exports.default = _foo.foo; +exports.default = void 0; var _foo = require("foo"); + +exports.default = _foo.foo; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-6/expected.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-6/expected.js index 236757e90d..acba4f460c 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-6/expected.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-6/expected.js @@ -1,7 +1,9 @@ "use strict"; exports.__esModule = true; -exports.default = _foo.foo; -exports.bar = _foo.bar; +exports.bar = exports.default = void 0; var _foo = require("foo"); + +exports.default = _foo.foo; +exports.bar = _foo.bar; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-7/expected.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-7/expected.js index 49116efe2c..e0585e8fc2 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-7/expected.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-7/expected.js @@ -1,6 +1,8 @@ "use strict"; exports.__esModule = true; -exports.foo = _foo.default; +exports.foo = void 0; var _foo = babelHelpers.interopRequireDefault(require("foo")); + +exports.foo = _foo.default; diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-8/expected.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-8/expected.js index 6da56f2b81..659ce72ccd 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-8/expected.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from-8/expected.js @@ -1,6 +1,9 @@ "use strict"; exports.__esModule = true; + +var _foo = require("foo"); + exports.foo = _foo.foo; exports.foo1 = _foo.foo1; exports.foo2 = _foo.foo2; @@ -102,5 +105,3 @@ exports.foo97 = _foo.foo97; exports.foo98 = _foo.foo98; exports.foo99 = _foo.foo99; exports.foo100 = _foo.foo100; - -var _foo = require("foo"); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-2/expected.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-2/expected.js index 520a6b509b..5d4745ee56 100644 --- a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-2/expected.js +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-2/expected.js @@ -14,5 +14,6 @@ "use strict"; _exports.__esModule = true; + _exports.default = void 0; _exports.default = _foo.foo; }); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-3/expected.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-3/expected.js index 5a6f824f43..b0d8ec7d4c 100644 --- a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-3/expected.js +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-3/expected.js @@ -14,6 +14,7 @@ "use strict"; _exports.__esModule = true; + _exports.bar = _exports.default = void 0; _exports.default = _foo.foo; _exports.bar = _foo.bar; }); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-4/expected.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-4/expected.js index 11344ddf0d..106e0f1be4 100644 --- a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-4/expected.js +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-4/expected.js @@ -14,5 +14,6 @@ "use strict"; _exports.__esModule = true; + _exports.bar = void 0; _exports.bar = _foo.foo; }); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-5/expected.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-5/expected.js index 4ee5bc2347..fa8a45cfa8 100644 --- a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-5/expected.js +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-5/expected.js @@ -14,6 +14,7 @@ "use strict"; _exports.__esModule = true; + _exports.bar = _exports.foo = void 0; _exports.foo = _foo.foo; _exports.bar = _foo.bar; }); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from/expected.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from/expected.js index 2ccde04820..7296d30f6d 100644 --- a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from/expected.js +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from/expected.js @@ -14,5 +14,6 @@ "use strict"; _exports.__esModule = true; + _exports.foo = void 0; _exports.foo = _foo.foo; });