From 00446f1a432a64bfcca6f133b687f0f01fc5352b Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Tue, 20 Dec 2022 03:32:40 +0800 Subject: [PATCH 1/6] Improve dynamic import spec compliance --- .../test/fixtures/amd/module/output.js | 2 +- .../test/fixtures/amd/no-interop/output.js | 2 +- .../test/fixtures/amd/script/output.js | 2 +- .../test/fixtures/amd/to-string/input.js | 1 + .../test/fixtures/amd/to-string/output.js | 3 ++ .../amd/with-other-import-export/output.js | 2 +- .../commonjs/exec-to-string-order/1.js | 1 + .../commonjs/exec-to-string-order/exec.js | 7 ++++ .../exec-to-string-order/options.json | 5 +++ .../commonjs/exec-to-string-throw/exec.js | 2 ++ .../exec-to-string-throw/options.json | 5 +++ .../fixtures/commonjs/to-string/output.js | 2 +- .../test/fixtures/systemjs/to-string/input.js | 1 + .../fixtures/systemjs/to-string/output.js | 10 ++++++ .../src/index.ts | 32 ++++++++++++++----- .../src/dynamic-import.ts | 5 ++- .../src/index.ts | 23 +++++++++---- .../modules-amd/output.js | 10 +++--- .../dynamic-import/modules-amd/output.js | 2 +- 19 files changed, 89 insertions(+), 28 deletions(-) create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/input.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/1.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/exec.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/options.json create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-throw/exec.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-throw/options.json create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/input.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/module/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/module/output.js index e0d86f169580..1600177ab9e3 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/module/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/module/output.js @@ -1,5 +1,5 @@ define(["require"], function (_require) { "use strict"; - var modP = new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject)); + var modP = Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/no-interop/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/no-interop/output.js index 96dab9dce6f7..8e7e674dcce0 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/no-interop/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/no-interop/output.js @@ -1,3 +1,3 @@ define(["require"], function (_require) { - var modP = new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(imported), _reject)); + var modP = Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(imported), _reject))); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/script/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/script/output.js index 0b8b11e86a92..93197dd59958 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/script/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/script/output.js @@ -1,3 +1,3 @@ define(["require"], function (_require) { - var modP = new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject)); + var modP = Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/input.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/input.js new file mode 100644 index 000000000000..130d3cafa5cb --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/input.js @@ -0,0 +1 @@ +import(2); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js new file mode 100644 index 000000000000..455cd76a1ac6 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js @@ -0,0 +1,3 @@ +define(["require"], function (_require) { + new Promise(r => r(`${2}`)).then(s => new Promise((_resolve, _reject) => _require([s], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))); +}); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/with-other-import-export/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/with-other-import-export/output.js index d5871c47383f..ecada8e624b5 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/with-other-import-export/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/with-other-import-export/output.js @@ -8,5 +8,5 @@ define(["require", "exports", "foo"], function (_require, _exports, _foo) { _foo = babelHelpers.interopRequireDefault(_foo); var mod; _exports.mod = mod; - new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject)).then(m => _exports.mod = mod = m); + Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))).then(m => _exports.mod = mod = m); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/1.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/1.js new file mode 100644 index 000000000000..bd816eaba4ca --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/1.js @@ -0,0 +1 @@ +module.exports = 1; diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/exec.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/exec.js new file mode 100644 index 000000000000..3e6bffbdfbb4 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/exec.js @@ -0,0 +1,7 @@ +let i = 0; +const promise = expect(import({ toString: () => `./${++i}.js` })) + .resolves.toHaveProperty("default", 1); +expect(i).toBe(1); +++i; +expect(i).toBe(2); +return promise; diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/options.json b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/options.json new file mode 100644 index 000000000000..eeebc1a57738 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-order/options.json @@ -0,0 +1,5 @@ +{ + "parserOpts": { + "allowReturnOutsideFunction": true + } +} diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-throw/exec.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-throw/exec.js new file mode 100644 index 000000000000..a4a59a3fec25 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-throw/exec.js @@ -0,0 +1,2 @@ +return expect(import({ toString: () => { throw "toString failed"; } })) + .rejects.toBe("toString failed"); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-throw/options.json b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-throw/options.json new file mode 100644 index 000000000000..eeebc1a57738 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-string-throw/options.json @@ -0,0 +1,5 @@ +{ + "parserOpts": { + "allowReturnOutsideFunction": true + } +} diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js index 7ec1d85d66b6..c172c3f0e7cb 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js @@ -1 +1 @@ -Promise.resolve(`${2}`).then(s => babelHelpers.interopRequireWildcard(require(s))); +new Promise(r => r(`${2}`)).then(s => babelHelpers.interopRequireWildcard(require(s))); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/input.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/input.js new file mode 100644 index 000000000000..130d3cafa5cb --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/input.js @@ -0,0 +1 @@ +import(2); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js new file mode 100644 index 000000000000..d5b31942747b --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js @@ -0,0 +1,10 @@ +System.register([], function (_export, _context) { + "use strict"; + + return { + setters: [], + execute: function () { + new Promise(r => r(`${2}`)).then(s => _context.import(s)); + } + }; +}); diff --git a/packages/babel-plugin-transform-modules-amd/src/index.ts b/packages/babel-plugin-transform-modules-amd/src/index.ts index 10cc77de1e1f..1668bb0bed1e 100644 --- a/packages/babel-plugin-transform-modules-amd/src/index.ts +++ b/packages/babel-plugin-transform-modules-amd/src/index.ts @@ -98,15 +98,31 @@ export default declare((api, options: Options) => { let result: t.Node = t.identifier("imported"); if (!noInterop) result = wrapInterop(path, result, "namespace"); + const source = getDynamicImportSource(path.node); + path.replaceWith( - template.expression.ast` - new Promise((${resolveId}, ${rejectId}) => - ${requireId}( - [${getDynamicImportSource(path.node)}], - imported => ${t.cloneNode(resolveId)}(${result}), - ${t.cloneNode(rejectId)} - ) - )`, + t.isStringLiteral(source) || + (t.isTemplateLiteral(source) && source.quasis.length === 0) + ? template.expression.ast` + Promise.resolve() + .then(() => new Promise((${resolveId}, ${rejectId}) => + ${requireId}( + [${source}], + imported => ${t.cloneNode(resolveId)}(${result}), + ${t.cloneNode(rejectId)} + ) + )) + ` + : template.expression.ast` + new Promise(r => r(${source})) + .then(s => new Promise((${resolveId}, ${rejectId}) => + ${requireId}( + [s], + imported => ${t.cloneNode(resolveId)}(${result}), + ${t.cloneNode(rejectId)} + ) + )) + `, ); }, diff --git a/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts b/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts index 0faf9f5099a0..6e6ee90c29d4 100644 --- a/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts +++ b/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts @@ -29,9 +29,8 @@ export function transformDynamicImport( Promise.resolve().then(() => ${buildRequire(source, file)}) ` : template.expression.ast` - Promise.resolve(${source}).then( - s => ${buildRequire(t.identifier("s"), file)} - ) + new Promise(r => r(${source})) + .then(s => ${buildRequire(t.identifier("s"), file)}) `; path.replaceWith(replacement); diff --git a/packages/babel-plugin-transform-modules-systemjs/src/index.ts b/packages/babel-plugin-transform-modules-systemjs/src/index.ts index c6b935534c74..76ec94869c9a 100644 --- a/packages/babel-plugin-transform-modules-systemjs/src/index.ts +++ b/packages/babel-plugin-transform-modules-systemjs/src/index.ts @@ -273,14 +273,23 @@ export default declare((api, options: Options) => { } } + const source = getDynamicImportSource(path.node); + const context = t.identifier(state.contextIdent); + path.replaceWith( - t.callExpression( - t.memberExpression( - t.identifier(state.contextIdent), - t.identifier("import"), - ), - [getDynamicImportSource(path.node)], - ), + t.isStringLiteral(source) || + (t.isTemplateLiteral(source) && source.quasis.length === 0) + ? t.callExpression( + t.memberExpression( + t.identifier(state.contextIdent), + t.identifier("import"), + ), + [source], + ) + : template.expression.ast` + new Promise(r => r(${source})) + .then(s => ${context}.import(s)) + `, ); } }, diff --git a/packages/babel-preset-env/test/fixtures/dynamic-import-babel-7/modules-amd/output.js b/packages/babel-preset-env/test/fixtures/dynamic-import-babel-7/modules-amd/output.js index e0114f02db52..c14553ec842a 100644 --- a/packages/babel-preset-env/test/fixtures/dynamic-import-babel-7/modules-amd/output.js +++ b/packages/babel-preset-env/test/fixtures/dynamic-import-babel-7/modules-amd/output.js @@ -1,7 +1,9 @@ define(["require"], function (_require) { - new Promise(function (_resolve, _reject) { - return _require(["foo"], function (imported) { - return _resolve(babelHelpers.interopRequireWildcard(imported)); - }, _reject); + Promise.resolve().then(function () { + return new Promise(function (_resolve, _reject) { + return _require(["foo"], function (imported) { + return _resolve(babelHelpers.interopRequireWildcard(imported)); + }, _reject); + }); }); }); diff --git a/packages/babel-preset-env/test/fixtures/dynamic-import/modules-amd/output.js b/packages/babel-preset-env/test/fixtures/dynamic-import/modules-amd/output.js index 8c5690b91c48..2e2bfa71abaa 100644 --- a/packages/babel-preset-env/test/fixtures/dynamic-import/modules-amd/output.js +++ b/packages/babel-preset-env/test/fixtures/dynamic-import/modules-amd/output.js @@ -1,3 +1,3 @@ define(["require"], function (_require) { - new Promise((_resolve, _reject) => _require(["foo"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject)); + Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["foo"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))); }); From fe63c958418b055f8c6b225346d360ec67377796 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Tue, 20 Dec 2022 12:32:18 +0800 Subject: [PATCH 2/6] Evaluate source outside --- .../src/dynamic-import.ts | 1 + .../test/fixtures/amd/to-string/output.js | 2 +- .../test/fixtures/commonjs/exec-throw/exec.js | 11 ++++++++++ .../fixtures/commonjs/to-string/output.js | 2 +- .../fixtures/systemjs/to-string/output.js | 2 +- .../src/index.ts | 21 ++++++++++--------- .../src/dynamic-import.ts | 9 ++++---- .../src/index.ts | 14 ++++++------- 8 files changed, 37 insertions(+), 25 deletions(-) create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-throw/exec.js diff --git a/packages/babel-helper-module-transforms/src/dynamic-import.ts b/packages/babel-helper-module-transforms/src/dynamic-import.ts index df9aedc79ac5..680b8bcd68ef 100644 --- a/packages/babel-helper-module-transforms/src/dynamic-import.ts +++ b/packages/babel-helper-module-transforms/src/dynamic-import.ts @@ -4,6 +4,7 @@ import * as t from "@babel/types"; import template from "@babel/template"; +// TODO(Babel 8): Remove this export function getDynamicImportSource( node: t.CallExpression, ): t.StringLiteral | t.TemplateLiteral { diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js index 455cd76a1ac6..62d1c61b53e8 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js @@ -1,3 +1,3 @@ define(["require"], function (_require) { - new Promise(r => r(`${2}`)).then(s => new Promise((_resolve, _reject) => _require([s], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))); + (source => new Promise(r => r("" + source)).then(s => new Promise((_resolve, _reject) => _require([s], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))))(2); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-throw/exec.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-throw/exec.js new file mode 100644 index 000000000000..6a80723db1f7 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-throw/exec.js @@ -0,0 +1,11 @@ +expect(() => { + function f() { throw "should throw"; } + import(f()); +}).toThrow("should throw"); + +expect(() => { + const a = { + get x() { throw "should throw"; }, + }; + import(a.x); +}).toThrow("should throw"); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js index c172c3f0e7cb..c79afe9ee54f 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js @@ -1 +1 @@ -new Promise(r => r(`${2}`)).then(s => babelHelpers.interopRequireWildcard(require(s))); +(source => new Promise(r => r("" + source)).then(s => babelHelpers.interopRequireWildcard(require(s))))(2); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js index d5b31942747b..8d565a3733da 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js @@ -4,7 +4,7 @@ System.register([], function (_export, _context) { return { setters: [], execute: function () { - new Promise(r => r(`${2}`)).then(s => _context.import(s)); + (source => new Promise(r => r("" + source)).then(s => _context.import(s)))(2); } }; }); diff --git a/packages/babel-plugin-transform-modules-amd/src/index.ts b/packages/babel-plugin-transform-modules-amd/src/index.ts index 1668bb0bed1e..92684b26a3d3 100644 --- a/packages/babel-plugin-transform-modules-amd/src/index.ts +++ b/packages/babel-plugin-transform-modules-amd/src/index.ts @@ -9,7 +9,6 @@ import { ensureStatementsHoisted, wrapInterop, getModuleName, - getDynamicImportSource, } from "@babel/helper-module-transforms"; import { template, types as t } from "@babel/core"; import type { PluginOptions } from "@babel/helper-module-transforms"; @@ -98,7 +97,7 @@ export default declare((api, options: Options) => { let result: t.Node = t.identifier("imported"); if (!noInterop) result = wrapInterop(path, result, "namespace"); - const source = getDynamicImportSource(path.node); + const [source] = path.node.arguments; path.replaceWith( t.isStringLiteral(source) || @@ -114,14 +113,16 @@ export default declare((api, options: Options) => { )) ` : template.expression.ast` - new Promise(r => r(${source})) - .then(s => new Promise((${resolveId}, ${rejectId}) => - ${requireId}( - [s], - imported => ${t.cloneNode(resolveId)}(${result}), - ${t.cloneNode(rejectId)} - ) - )) + (source => + new Promise(r => r("" + source)) + .then(s => new Promise((${resolveId}, ${rejectId}) => + ${requireId}( + [s], + imported => ${t.cloneNode(resolveId)}(${result}), + ${t.cloneNode(rejectId)} + ) + )) + )(${source}) `, ); }, diff --git a/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts b/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts index 6e6ee90c29d4..e91ffce8ad36 100644 --- a/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts +++ b/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts @@ -3,7 +3,6 @@ import type { NodePath } from "@babel/traverse"; import { types as t, template, type File } from "@babel/core"; -import { getDynamicImportSource } from "@babel/helper-module-transforms"; const requireNoInterop = (source: t.Expression) => template.expression.ast`require(${source})`; @@ -20,7 +19,7 @@ export function transformDynamicImport( ) { const buildRequire = noInterop ? requireNoInterop : requireInterop; - const source = getDynamicImportSource(path.node); + const [source] = path.node.arguments; const replacement = t.isStringLiteral(source) || @@ -29,8 +28,10 @@ export function transformDynamicImport( Promise.resolve().then(() => ${buildRequire(source, file)}) ` : template.expression.ast` - new Promise(r => r(${source})) - .then(s => ${buildRequire(t.identifier("s"), file)}) + (source => + new Promise(r => r("" + source)) + .then(s => ${buildRequire(t.identifier("s"), file)}) + )(${source}) `; path.replaceWith(replacement); diff --git a/packages/babel-plugin-transform-modules-systemjs/src/index.ts b/packages/babel-plugin-transform-modules-systemjs/src/index.ts index 76ec94869c9a..b316664e6f3d 100644 --- a/packages/babel-plugin-transform-modules-systemjs/src/index.ts +++ b/packages/babel-plugin-transform-modules-systemjs/src/index.ts @@ -1,11 +1,7 @@ import { declare } from "@babel/helper-plugin-utils"; import hoistVariables from "@babel/helper-hoist-variables"; import { template, types as t } from "@babel/core"; -import { - rewriteThis, - getModuleName, - getDynamicImportSource, -} from "@babel/helper-module-transforms"; +import { rewriteThis, getModuleName } from "@babel/helper-module-transforms"; import type { PluginOptions } from "@babel/helper-module-transforms"; import { isIdentifierName } from "@babel/helper-validator-identifier"; import type { NodePath, Scope, Visitor } from "@babel/traverse"; @@ -273,7 +269,7 @@ export default declare((api, options: Options) => { } } - const source = getDynamicImportSource(path.node); + const [source] = path.node.arguments; const context = t.identifier(state.contextIdent); path.replaceWith( @@ -287,8 +283,10 @@ export default declare((api, options: Options) => { [source], ) : template.expression.ast` - new Promise(r => r(${source})) - .then(s => ${context}.import(s)) + (source => + new Promise(r => r("" + source)) + .then(s => ${context}.import(s)) + )(${source}) `, ); } From 75996fe68e4d00aed78e465f330fcb37a406d71f Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Thu, 22 Dec 2022 03:21:59 +0800 Subject: [PATCH 3/6] Add buildDynamicImport --- .../src/dynamic-import.ts | 32 ++++++++++++++++ .../src/index.ts | 2 +- .../test/fixtures/amd/to-string/output.js | 2 +- .../commonjs/exec-template-literal/1.js | 1 + .../commonjs/exec-template-literal/exec.js | 3 ++ .../exec-template-literal/options.json | 5 +++ .../commonjs/exec-to-primitive/exec.js | 6 +++ .../commonjs/exec-to-primitive/foo.js | 1 + .../commonjs/exec-to-primitive/options.json | 5 +++ .../commonjs/template-literal/input.js | 2 + .../commonjs/template-literal/output.js | 2 + .../fixtures/commonjs/to-string/output.js | 2 +- .../fixtures/systemjs/to-string/output.js | 2 +- .../src/index.ts | 38 +++++++------------ .../src/dynamic-import.ts | 22 +++-------- .../src/index.ts | 33 +++++++--------- 16 files changed, 94 insertions(+), 64 deletions(-) create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/1.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/exec.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/options.json create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/exec.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/foo.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/options.json create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/template-literal/input.js create mode 100644 packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/template-literal/output.js diff --git a/packages/babel-helper-module-transforms/src/dynamic-import.ts b/packages/babel-helper-module-transforms/src/dynamic-import.ts index 680b8bcd68ef..cefde7e7dced 100644 --- a/packages/babel-helper-module-transforms/src/dynamic-import.ts +++ b/packages/babel-helper-module-transforms/src/dynamic-import.ts @@ -14,3 +14,35 @@ export function getDynamicImportSource( ? source : (template.expression.ast`\`\${${source}}\`` as t.TemplateLiteral); } + +export function buildDynamicImport( + node: t.CallExpression, + runInThen: boolean, + builder: (specifier: t.Expression) => t.Expression, +): t.Expression { + const [specifier] = node.arguments; + if ( + t.isStringLiteral(specifier) || + (t.isTemplateLiteral(specifier) && specifier.quasis.length === 0) + ) { + if (runInThen) { + return template.expression.ast` + Promise.resolve().then(() => ${builder(specifier)}) + `; + } else return builder(specifier); + } + + return template.expression.ast` + (specifier => + new Promise(r => r(${ + t.isTemplateLiteral(specifier) + ? t.identifier("specifier") + : t.templateLiteral( + [t.templateElement({ raw: "" }), t.templateElement({ raw: "" })], + [t.identifier("specifier")], + ) + })) + .then(s => ${builder(t.identifier("s"))}) + )(${specifier}) + `; +} diff --git a/packages/babel-helper-module-transforms/src/index.ts b/packages/babel-helper-module-transforms/src/index.ts index d939661d6168..fc7f53950f67 100644 --- a/packages/babel-helper-module-transforms/src/index.ts +++ b/packages/babel-helper-module-transforms/src/index.ts @@ -35,7 +35,7 @@ import type { } from "./normalize-and-load-metadata"; import type { NodePath } from "@babel/traverse"; -export { getDynamicImportSource } from "./dynamic-import"; +export { buildDynamicImport, getDynamicImportSource } from "./dynamic-import"; export { default as getModuleName } from "./get-module-name"; export type { PluginOptions } from "./get-module-name"; diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js index 62d1c61b53e8..ad66a41e03d7 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js @@ -1,3 +1,3 @@ define(["require"], function (_require) { - (source => new Promise(r => r("" + source)).then(s => new Promise((_resolve, _reject) => _require([s], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))))(2); + (specifier => new Promise(r => r(`${specifier}`)).then(s => new Promise((_resolve, _reject) => _require([s], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))))(2); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/1.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/1.js new file mode 100644 index 000000000000..bd816eaba4ca --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/1.js @@ -0,0 +1 @@ +module.exports = 1; diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/exec.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/exec.js new file mode 100644 index 000000000000..2f3a13932e5c --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/exec.js @@ -0,0 +1,3 @@ +let x = 1; +return expect(import(`./${x}.js`)) + .resolves.toHaveProperty("default", 1); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/options.json b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/options.json new file mode 100644 index 000000000000..eeebc1a57738 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-template-literal/options.json @@ -0,0 +1,5 @@ +{ + "parserOpts": { + "allowReturnOutsideFunction": true + } +} diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/exec.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/exec.js new file mode 100644 index 000000000000..09e8bf06d4e5 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/exec.js @@ -0,0 +1,6 @@ +return expect(import({ + [Symbol.toPrimitive](hint) { + if (hint === "string") return "./foo.js"; + return null; + } +})).resolves.toHaveProperty("default", "foo"); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/foo.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/foo.js new file mode 100644 index 000000000000..e7134e7006d9 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/foo.js @@ -0,0 +1 @@ +module.exports = "foo"; diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/options.json b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/options.json new file mode 100644 index 000000000000..eeebc1a57738 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/exec-to-primitive/options.json @@ -0,0 +1,5 @@ +{ + "parserOpts": { + "allowReturnOutsideFunction": true + } +} diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/template-literal/input.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/template-literal/input.js new file mode 100644 index 000000000000..ebb8aaa09cd3 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/template-literal/input.js @@ -0,0 +1,2 @@ +const x = 1; +import(`./${x}.js`); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/template-literal/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/template-literal/output.js new file mode 100644 index 000000000000..6e90671b2706 --- /dev/null +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/template-literal/output.js @@ -0,0 +1,2 @@ +const x = 1; +(specifier => new Promise(r => r(specifier)).then(s => babelHelpers.interopRequireWildcard(require(s))))(`./${x}.js`); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js index c79afe9ee54f..3618cfbe2b92 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/commonjs/to-string/output.js @@ -1 +1 @@ -(source => new Promise(r => r("" + source)).then(s => babelHelpers.interopRequireWildcard(require(s))))(2); +(specifier => new Promise(r => r(`${specifier}`)).then(s => babelHelpers.interopRequireWildcard(require(s))))(2); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js index 8d565a3733da..ffb373287cae 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js @@ -4,7 +4,7 @@ System.register([], function (_export, _context) { return { setters: [], execute: function () { - (source => new Promise(r => r("" + source)).then(s => _context.import(s)))(2); + (specifier => new Promise(r => r(`${specifier}`)).then(s => _context.import(s)))(2); } }; }); diff --git a/packages/babel-plugin-transform-modules-amd/src/index.ts b/packages/babel-plugin-transform-modules-amd/src/index.ts index 92684b26a3d3..c73af6d5dfa5 100644 --- a/packages/babel-plugin-transform-modules-amd/src/index.ts +++ b/packages/babel-plugin-transform-modules-amd/src/index.ts @@ -1,5 +1,6 @@ import { declare } from "@babel/helper-plugin-utils"; import { + buildDynamicImport, isModule, rewriteModuleStatementsAndPrepareHeader, type RewriteModuleStatementsAndPrepareHeaderOptions, @@ -97,33 +98,20 @@ export default declare((api, options: Options) => { let result: t.Node = t.identifier("imported"); if (!noInterop) result = wrapInterop(path, result, "namespace"); - const [source] = path.node.arguments; - path.replaceWith( - t.isStringLiteral(source) || - (t.isTemplateLiteral(source) && source.quasis.length === 0) - ? template.expression.ast` - Promise.resolve() - .then(() => new Promise((${resolveId}, ${rejectId}) => - ${requireId}( - [${source}], - imported => ${t.cloneNode(resolveId)}(${result}), - ${t.cloneNode(rejectId)} - ) - )) - ` - : template.expression.ast` - (source => - new Promise(r => r("" + source)) - .then(s => new Promise((${resolveId}, ${rejectId}) => - ${requireId}( - [s], - imported => ${t.cloneNode(resolveId)}(${result}), - ${t.cloneNode(rejectId)} - ) - )) - )(${source}) + buildDynamicImport( + path.node, + true, + specifier => template.expression.ast` + new Promise((${resolveId}, ${rejectId}) => + ${requireId}( + [${specifier}], + imported => ${t.cloneNode(resolveId)}(${result}), + ${t.cloneNode(rejectId)} + ) + ) `, + ), ); }, diff --git a/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts b/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts index e91ffce8ad36..1fd41826467c 100644 --- a/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts +++ b/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts @@ -3,6 +3,7 @@ import type { NodePath } from "@babel/traverse"; import { types as t, template, type File } from "@babel/core"; +import { buildDynamicImport } from "@babel/helper-module-transforms"; const requireNoInterop = (source: t.Expression) => template.expression.ast`require(${source})`; @@ -19,20 +20,9 @@ export function transformDynamicImport( ) { const buildRequire = noInterop ? requireNoInterop : requireInterop; - const [source] = path.node.arguments; - - const replacement = - t.isStringLiteral(source) || - (t.isTemplateLiteral(source) && source.quasis.length === 0) - ? template.expression.ast` - Promise.resolve().then(() => ${buildRequire(source, file)}) - ` - : template.expression.ast` - (source => - new Promise(r => r("" + source)) - .then(s => ${buildRequire(t.identifier("s"), file)}) - )(${source}) - `; - - path.replaceWith(replacement); + path.replaceWith( + buildDynamicImport(path.node, true, specifier => + buildRequire(specifier, file), + ), + ); } diff --git a/packages/babel-plugin-transform-modules-systemjs/src/index.ts b/packages/babel-plugin-transform-modules-systemjs/src/index.ts index b316664e6f3d..c3fe05786cf1 100644 --- a/packages/babel-plugin-transform-modules-systemjs/src/index.ts +++ b/packages/babel-plugin-transform-modules-systemjs/src/index.ts @@ -1,7 +1,11 @@ import { declare } from "@babel/helper-plugin-utils"; import hoistVariables from "@babel/helper-hoist-variables"; import { template, types as t } from "@babel/core"; -import { rewriteThis, getModuleName } from "@babel/helper-module-transforms"; +import { + buildDynamicImport, + getModuleName, + rewriteThis, +} from "@babel/helper-module-transforms"; import type { PluginOptions } from "@babel/helper-module-transforms"; import { isIdentifierName } from "@babel/helper-validator-identifier"; import type { NodePath, Scope, Visitor } from "@babel/traverse"; @@ -269,25 +273,16 @@ export default declare((api, options: Options) => { } } - const [source] = path.node.arguments; - const context = t.identifier(state.contextIdent); - path.replaceWith( - t.isStringLiteral(source) || - (t.isTemplateLiteral(source) && source.quasis.length === 0) - ? t.callExpression( - t.memberExpression( - t.identifier(state.contextIdent), - t.identifier("import"), - ), - [source], - ) - : template.expression.ast` - (source => - new Promise(r => r("" + source)) - .then(s => ${context}.import(s)) - )(${source}) - `, + buildDynamicImport(path.node, false, specifier => + t.callExpression( + t.memberExpression( + t.identifier(state.contextIdent), + t.identifier("import"), + ), + [specifier], + ), + ), ); } }, From aef26e9bf2c95788a643f00bd4218ac7dd794dde Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Thu, 22 Dec 2022 03:40:45 +0800 Subject: [PATCH 4/6] AMD's require don't need defer --- .../test/fixtures/amd/module/output.js | 2 +- .../test/fixtures/amd/no-interop/output.js | 2 +- .../test/fixtures/amd/script/output.js | 2 +- .../fixtures/amd/with-other-import-export/output.js | 2 +- .../babel-plugin-transform-modules-amd/src/index.ts | 2 +- .../dynamic-import-babel-7/modules-amd/output.js | 10 ++++------ .../test/fixtures/dynamic-import/modules-amd/output.js | 2 +- 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/module/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/module/output.js index 1600177ab9e3..e0d86f169580 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/module/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/module/output.js @@ -1,5 +1,5 @@ define(["require"], function (_require) { "use strict"; - var modP = Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))); + var modP = new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject)); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/no-interop/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/no-interop/output.js index 8e7e674dcce0..96dab9dce6f7 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/no-interop/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/no-interop/output.js @@ -1,3 +1,3 @@ define(["require"], function (_require) { - var modP = Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(imported), _reject))); + var modP = new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(imported), _reject)); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/script/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/script/output.js index 93197dd59958..0b8b11e86a92 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/script/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/script/output.js @@ -1,3 +1,3 @@ define(["require"], function (_require) { - var modP = Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))); + var modP = new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject)); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/with-other-import-export/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/with-other-import-export/output.js index ecada8e624b5..d5871c47383f 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/with-other-import-export/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/with-other-import-export/output.js @@ -8,5 +8,5 @@ define(["require", "exports", "foo"], function (_require, _exports, _foo) { _foo = babelHelpers.interopRequireDefault(_foo); var mod; _exports.mod = mod; - Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))).then(m => _exports.mod = mod = m); + new Promise((_resolve, _reject) => _require(["mod"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject)).then(m => _exports.mod = mod = m); }); diff --git a/packages/babel-plugin-transform-modules-amd/src/index.ts b/packages/babel-plugin-transform-modules-amd/src/index.ts index c73af6d5dfa5..4bd332ae348f 100644 --- a/packages/babel-plugin-transform-modules-amd/src/index.ts +++ b/packages/babel-plugin-transform-modules-amd/src/index.ts @@ -101,7 +101,7 @@ export default declare((api, options: Options) => { path.replaceWith( buildDynamicImport( path.node, - true, + false, specifier => template.expression.ast` new Promise((${resolveId}, ${rejectId}) => ${requireId}( diff --git a/packages/babel-preset-env/test/fixtures/dynamic-import-babel-7/modules-amd/output.js b/packages/babel-preset-env/test/fixtures/dynamic-import-babel-7/modules-amd/output.js index c14553ec842a..e0114f02db52 100644 --- a/packages/babel-preset-env/test/fixtures/dynamic-import-babel-7/modules-amd/output.js +++ b/packages/babel-preset-env/test/fixtures/dynamic-import-babel-7/modules-amd/output.js @@ -1,9 +1,7 @@ define(["require"], function (_require) { - Promise.resolve().then(function () { - return new Promise(function (_resolve, _reject) { - return _require(["foo"], function (imported) { - return _resolve(babelHelpers.interopRequireWildcard(imported)); - }, _reject); - }); + new Promise(function (_resolve, _reject) { + return _require(["foo"], function (imported) { + return _resolve(babelHelpers.interopRequireWildcard(imported)); + }, _reject); }); }); diff --git a/packages/babel-preset-env/test/fixtures/dynamic-import/modules-amd/output.js b/packages/babel-preset-env/test/fixtures/dynamic-import/modules-amd/output.js index 2e2bfa71abaa..8c5690b91c48 100644 --- a/packages/babel-preset-env/test/fixtures/dynamic-import/modules-amd/output.js +++ b/packages/babel-preset-env/test/fixtures/dynamic-import/modules-amd/output.js @@ -1,3 +1,3 @@ define(["require"], function (_require) { - Promise.resolve().then(() => new Promise((_resolve, _reject) => _require(["foo"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))); + new Promise((_resolve, _reject) => _require(["foo"], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject)); }); From 083ab3068867e1c002f70606fb9a4d02aaba7b03 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Thu, 22 Dec 2022 04:01:05 +0800 Subject: [PATCH 5/6] Update buildDynamicImport --- .../src/dynamic-import.ts | 44 ++++++++++++------- .../test/fixtures/amd/to-string/output.js | 2 +- .../fixtures/systemjs/to-string/output.js | 2 +- .../src/index.ts | 1 + .../src/dynamic-import.ts | 2 +- .../src/index.ts | 2 +- 6 files changed, 34 insertions(+), 19 deletions(-) diff --git a/packages/babel-helper-module-transforms/src/dynamic-import.ts b/packages/babel-helper-module-transforms/src/dynamic-import.ts index cefde7e7dced..d35091655f57 100644 --- a/packages/babel-helper-module-transforms/src/dynamic-import.ts +++ b/packages/babel-helper-module-transforms/src/dynamic-import.ts @@ -17,32 +17,46 @@ export function getDynamicImportSource( export function buildDynamicImport( node: t.CallExpression, - runInThen: boolean, + deferedToThen: boolean, + wrapWithPromise: boolean, builder: (specifier: t.Expression) => t.Expression, ): t.Expression { const [specifier] = node.arguments; + if ( t.isStringLiteral(specifier) || (t.isTemplateLiteral(specifier) && specifier.quasis.length === 0) ) { - if (runInThen) { + if (deferedToThen) { return template.expression.ast` Promise.resolve().then(() => ${builder(specifier)}) `; } else return builder(specifier); } - return template.expression.ast` - (specifier => - new Promise(r => r(${ - t.isTemplateLiteral(specifier) - ? t.identifier("specifier") - : t.templateLiteral( - [t.templateElement({ raw: "" }), t.templateElement({ raw: "" })], - [t.identifier("specifier")], - ) - })) - .then(s => ${builder(t.identifier("s"))}) - )(${specifier}) - `; + const specifierToString = t.isTemplateLiteral(specifier) + ? t.identifier("specifier") + : t.templateLiteral( + [t.templateElement({ raw: "" }), t.templateElement({ raw: "" })], + [t.identifier("specifier")], + ); + + if (deferedToThen) { + return template.expression.ast` + (specifier => + new Promise(r => r(${specifierToString})) + .then(s => ${builder(t.identifier("s"))}) + )(${specifier}) + `; + } else if (wrapWithPromise) { + return template.expression.ast` + (specifier => + new Promise(r => r(${builder(specifierToString)})) + )(${specifier}) + `; + } else { + return template.expression.ast` + (specifier => ${builder(specifierToString)})(${specifier}) + `; + } } diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js index ad66a41e03d7..f8ffd28bbf17 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/amd/to-string/output.js @@ -1,3 +1,3 @@ define(["require"], function (_require) { - (specifier => new Promise(r => r(`${specifier}`)).then(s => new Promise((_resolve, _reject) => _require([s], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject))))(2); + (specifier => new Promise((_resolve, _reject) => _require([`${specifier}`], imported => _resolve(babelHelpers.interopRequireWildcard(imported)), _reject)))(2); }); diff --git a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js index ffb373287cae..6af1121eb491 100644 --- a/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js +++ b/packages/babel-plugin-proposal-dynamic-import/test/fixtures/systemjs/to-string/output.js @@ -4,7 +4,7 @@ System.register([], function (_export, _context) { return { setters: [], execute: function () { - (specifier => new Promise(r => r(`${specifier}`)).then(s => _context.import(s)))(2); + (specifier => new Promise(r => r(_context.import(`${specifier}`))))(2); } }; }); diff --git a/packages/babel-plugin-transform-modules-amd/src/index.ts b/packages/babel-plugin-transform-modules-amd/src/index.ts index 4bd332ae348f..b46dff0e132f 100644 --- a/packages/babel-plugin-transform-modules-amd/src/index.ts +++ b/packages/babel-plugin-transform-modules-amd/src/index.ts @@ -102,6 +102,7 @@ export default declare((api, options: Options) => { buildDynamicImport( path.node, false, + false, specifier => template.expression.ast` new Promise((${resolveId}, ${rejectId}) => ${requireId}( diff --git a/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts b/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts index 1fd41826467c..bb132d85a1ab 100644 --- a/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts +++ b/packages/babel-plugin-transform-modules-commonjs/src/dynamic-import.ts @@ -21,7 +21,7 @@ export function transformDynamicImport( const buildRequire = noInterop ? requireNoInterop : requireInterop; path.replaceWith( - buildDynamicImport(path.node, true, specifier => + buildDynamicImport(path.node, true, false, specifier => buildRequire(specifier, file), ), ); diff --git a/packages/babel-plugin-transform-modules-systemjs/src/index.ts b/packages/babel-plugin-transform-modules-systemjs/src/index.ts index c3fe05786cf1..7e471c754c32 100644 --- a/packages/babel-plugin-transform-modules-systemjs/src/index.ts +++ b/packages/babel-plugin-transform-modules-systemjs/src/index.ts @@ -274,7 +274,7 @@ export default declare((api, options: Options) => { } path.replaceWith( - buildDynamicImport(path.node, false, specifier => + buildDynamicImport(path.node, false, true, specifier => t.callExpression( t.memberExpression( t.identifier(state.contextIdent), From 9b2100566283b50c9ed895d03ee1f1c0a7bb93c0 Mon Sep 17 00:00:00 2001 From: SuperSodaSea Date: Thu, 22 Dec 2022 04:18:24 +0800 Subject: [PATCH 6/6] Update buildDynamicImport --- .../babel-helper-module-transforms/src/dynamic-import.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/babel-helper-module-transforms/src/dynamic-import.ts b/packages/babel-helper-module-transforms/src/dynamic-import.ts index d35091655f57..e9c0fae51a22 100644 --- a/packages/babel-helper-module-transforms/src/dynamic-import.ts +++ b/packages/babel-helper-module-transforms/src/dynamic-import.ts @@ -17,7 +17,7 @@ export function getDynamicImportSource( export function buildDynamicImport( node: t.CallExpression, - deferedToThen: boolean, + deferToThen: boolean, wrapWithPromise: boolean, builder: (specifier: t.Expression) => t.Expression, ): t.Expression { @@ -27,7 +27,7 @@ export function buildDynamicImport( t.isStringLiteral(specifier) || (t.isTemplateLiteral(specifier) && specifier.quasis.length === 0) ) { - if (deferedToThen) { + if (deferToThen) { return template.expression.ast` Promise.resolve().then(() => ${builder(specifier)}) `; @@ -41,7 +41,7 @@ export function buildDynamicImport( [t.identifier("specifier")], ); - if (deferedToThen) { + if (deferToThen) { return template.expression.ast` (specifier => new Promise(r => r(${specifierToString}))