From a080c82777895114535bec5a3f92f953e492b30d Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig Date: Mon, 28 Sep 2020 16:22:13 +0200 Subject: [PATCH] [cjs] Skip duplicate reexported bindings in namespace reexports (#11739) --- packages/babel-helper-module-transforms/src/index.js | 10 +++++++++- .../test/fixtures/amd/export-from/output.js | 1 + .../test/fixtures/loose/export-from/output.js | 1 + .../test/fixtures/interop-loose/export-from/output.js | 1 + .../test/fixtures/interop/export-all/output.js | 1 + .../test/fixtures/interop/export-from/output.js | 1 + .../test/fixtures/lazy-dep/reexport-all/output.js | 1 + .../test/fixtures/lazy-local/reexport-all/output.js | 1 + .../fixtures/lazy-whitelist/reexport-all/output.js | 2 ++ .../test/fixtures/regression/T7165/output.js | 1 + .../test/fixtures/strict/export-all/output.js | 1 + .../test/fixtures/loose/export-from-6/output.js | 1 + .../test/fixtures/umd/export-from-6/output.js | 1 + .../test/fixtures/runtime-corejs2/modules/output.js | 1 + .../fixtures/runtime-corejs3/modules-loose/output.js | 1 + .../test/fixtures/runtime-corejs3/modules/output.js | 1 + .../test/fixtures/runtime/modules/output.js | 1 + 17 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/babel-helper-module-transforms/src/index.js b/packages/babel-helper-module-transforms/src/index.js index 854a76fcb3f2..81983f773c09 100644 --- a/packages/babel-helper-module-transforms/src/index.js +++ b/packages/babel-helper-module-transforms/src/index.js @@ -236,14 +236,22 @@ function buildNamespaceReexport(metadata, namespace, loose) { Object.keys(NAMESPACE).forEach(function(key) { if (key === "default" || key === "__esModule") return; VERIFY_NAME_LIST; + if (key in EXPORTS && EXPORTS[key] === NAMESPACE[key]) return; EXPORTS[key] = NAMESPACE[key]; }); ` - : template.statement` + : // Also skip already assigned bindings if they are strictly equal + // to be somewhat more spec-compliant when a file has multiple + // namespace re-exports that would cause a binding to be exported + // multiple times. However, multiple bindings of the same name that + // export the same primitive value are silently skipped + // (the spec requires an "ambigous bindings" early error here). + template.statement` Object.keys(NAMESPACE).forEach(function(key) { if (key === "default" || key === "__esModule") return; VERIFY_NAME_LIST; + if (key in EXPORTS && EXPORTS[key] === NAMESPACE[key]) return; Object.defineProperty(EXPORTS, key, { enumerable: true, diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/amd/export-from/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/amd/export-from/output.js index 7dd0d1811c63..a1f8e7ec0ab0 100644 --- a/packages/babel-plugin-transform-modules-amd/test/fixtures/amd/export-from/output.js +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/amd/export-from/output.js @@ -6,6 +6,7 @@ define(["exports", "foo"], function (_exports, _foo) { }); Object.keys(_foo).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in _exports && _exports[key] === _foo[key]) return; Object.defineProperty(_exports, key, { enumerable: true, get: function () { diff --git a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from/output.js b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from/output.js index 9933165d6e9c..84514950346a 100644 --- a/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from/output.js +++ b/packages/babel-plugin-transform-modules-amd/test/fixtures/loose/export-from/output.js @@ -4,6 +4,7 @@ define(["exports", "foo"], function (_exports, _foo) { _exports.__esModule = true; Object.keys(_foo).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in _exports && _exports[key] === _foo[key]) return; _exports[key] = _foo[key]; }); }); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from/output.js index 8901160e3d1b..44ea971b11f9 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop-loose/export-from/output.js @@ -6,5 +6,6 @@ var _foo = require("foo"); Object.keys(_foo).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _foo[key]) return; exports[key] = _foo[key]; }); diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/export-all/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/export-all/output.js index 95892f7cc67c..9f51a2747fb2 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/export-all/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/export-all/output.js @@ -11,6 +11,7 @@ var _react = babelHelpers.interopRequireWildcard(require("react")); Object.keys(_react).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _react[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/export-from/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/export-from/output.js index 2c7b3bc5c6ac..ccb8b014043f 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/export-from/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/interop/export-from/output.js @@ -8,6 +8,7 @@ var _foo = require("foo"); Object.keys(_foo).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _foo[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-dep/reexport-all/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-dep/reexport-all/output.js index 2c7b3bc5c6ac..ccb8b014043f 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-dep/reexport-all/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-dep/reexport-all/output.js @@ -8,6 +8,7 @@ var _foo = require("foo"); Object.keys(_foo).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _foo[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-local/reexport-all/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-local/reexport-all/output.js index 9f28bb11420c..d6832ddafd42 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-local/reexport-all/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-local/reexport-all/output.js @@ -8,6 +8,7 @@ var _foo = require("./foo"); Object.keys(_foo).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _foo[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-whitelist/reexport-all/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-whitelist/reexport-all/output.js index bc299957cbe3..6de5e257a9fd 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-whitelist/reexport-all/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/lazy-whitelist/reexport-all/output.js @@ -8,6 +8,7 @@ var _white = require("white"); Object.keys(_white).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _white[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { @@ -20,6 +21,7 @@ var _black = require("black"); Object.keys(_black).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _black[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7165/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7165/output.js index cc5fe3b4a091..785bcd377c56 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7165/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/regression/T7165/output.js @@ -10,6 +10,7 @@ var _bar = require("bar"); Object.keys(_bar).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _bar[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { diff --git a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/strict/export-all/output.js b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/strict/export-all/output.js index 443315cbadc4..d7ef4d0c5a7c 100644 --- a/packages/babel-plugin-transform-modules-commonjs/test/fixtures/strict/export-all/output.js +++ b/packages/babel-plugin-transform-modules-commonjs/test/fixtures/strict/export-all/output.js @@ -27,6 +27,7 @@ var _mod = require("mod"); Object.keys(_mod).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _mod[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () { diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-6/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-6/output.js index 8405ded47ad5..e779928fa4ed 100644 --- a/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-6/output.js +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/loose/export-from-6/output.js @@ -16,6 +16,7 @@ _exports.__esModule = true; Object.keys(_foo).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in _exports && _exports[key] === _foo[key]) return; _exports[key] = _foo[key]; }); }); diff --git a/packages/babel-plugin-transform-modules-umd/test/fixtures/umd/export-from-6/output.js b/packages/babel-plugin-transform-modules-umd/test/fixtures/umd/export-from-6/output.js index 46e4a2b27dd2..12df8e30bce1 100644 --- a/packages/babel-plugin-transform-modules-umd/test/fixtures/umd/export-from-6/output.js +++ b/packages/babel-plugin-transform-modules-umd/test/fixtures/umd/export-from-6/output.js @@ -18,6 +18,7 @@ }); Object.keys(_foo).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in _exports && _exports[key] === _foo[key]) return; Object.defineProperty(_exports, key, { enumerable: true, get: function () { diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/modules/output.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/modules/output.js index c3eab7f58ed2..061601e92166 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/modules/output.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs2/modules/output.js @@ -16,6 +16,7 @@ var _mod = require("mod"); _Object$keys(_mod).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _mod[key]) return; _Object$defineProperty(exports, key, { enumerable: true, diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/modules-loose/output.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/modules-loose/output.js index 2a1a8fe7aa92..2eb624007929 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/modules-loose/output.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/modules-loose/output.js @@ -23,6 +23,7 @@ var _mod = require("mod"); _forEachInstanceProperty(_context = _Object$keys(_mod)).call(_context, function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _mod[key]) return; exports[key] = _mod[key]; }); diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/modules/output.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/modules/output.js index 75793607c414..02a06aef15ab 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/modules/output.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime-corejs3/modules/output.js @@ -28,6 +28,7 @@ var _mod = require("mod"); _forEachInstanceProperty(_context = _Object$keys(_mod)).call(_context, function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _mod[key]) return; _Object$defineProperty(exports, key, { enumerable: true, diff --git a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/output.js b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/output.js index 260de19e94a1..63f11cee7276 100644 --- a/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/output.js +++ b/packages/babel-plugin-transform-runtime/test/fixtures/runtime/modules/output.js @@ -12,6 +12,7 @@ var _mod = require("mod"); Object.keys(_mod).forEach(function (key) { if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _mod[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function () {