From 3824beedaf6b8f34dda8c2370bd7d1a7236733c0 Mon Sep 17 00:00:00 2001 From: Ivan Kopeykin Date: Thu, 13 Apr 2023 17:16:32 +0300 Subject: [PATCH 1/4] support destructuring assignment with AwaitExpression --- lib/dependencies/ImportParserPlugin.js | 18 +++++++++++++++++- lib/javascript/JavascriptParser.js | 14 ++++++++++++-- .../chunks/destructuring-assignment/dir1/a.js | 3 +++ .../chunks/destructuring-assignment/index.js | 12 ++++++++++++ .../destructuring-assignment/warnings.js | 3 +++ 5 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 test/cases/chunks/destructuring-assignment/dir1/a.js create mode 100644 test/cases/chunks/destructuring-assignment/index.js create mode 100644 test/cases/chunks/destructuring-assignment/warnings.js diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index 718b0482828..a3aba061d36 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -27,6 +27,8 @@ class ImportParserPlugin { } apply(parser) { + const exportsFromEnumerable = enumerable => + Array.from(enumerable, e => [e]); parser.hooks.importCall.tap("ImportParserPlugin", expr => { const param = parser.evaluateExpression(expr.source); @@ -184,7 +186,7 @@ class ImportParserPlugin { if (typeof importOptions.webpackExports === "string") { exports = [[importOptions.webpackExports]]; } else { - exports = Array.from(importOptions.webpackExports, e => [e]); + exports = exportsFromEnumerable(importOptions.webpackExports); } } } @@ -205,6 +207,20 @@ class ImportParserPlugin { mode = "lazy"; } + const referencedPropertiesInDestructuring = + parser.destructuringAssignmentPropertiesFor(expr); + if (referencedPropertiesInDestructuring) { + if (exports) { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackExports\` could not be used with destructuring assignment.`, + expr.loc + ) + ); + } + exports = exportsFromEnumerable(referencedPropertiesInDestructuring); + } + if (param.isString()) { if (mode === "eager") { const dep = new ImportEagerDependency( diff --git a/lib/javascript/JavascriptParser.js b/lib/javascript/JavascriptParser.js index 6d9e9e79027..5b09c4b296e 100644 --- a/lib/javascript/JavascriptParser.js +++ b/lib/javascript/JavascriptParser.js @@ -1927,7 +1927,12 @@ class JavascriptParser extends Parser { for (const id of set) keys.add(id); } - this.destructuringAssignmentProperties.set(expression.right, keys); + this.destructuringAssignmentProperties.set( + expression.right.type === "AwaitExpression" + ? expression.right.argument + : expression.right, + keys + ); if (expression.right.type === "AssignmentExpression") { this.preWalkAssignmentExpression(expression.right); @@ -2183,7 +2188,12 @@ class JavascriptParser extends Parser { const keys = this._preWalkObjectPattern(declarator.id); if (!keys) return; - this.destructuringAssignmentProperties.set(declarator.init, keys); + this.destructuringAssignmentProperties.set( + declarator.init.type === "AwaitExpression" + ? declarator.init.argument + : declarator.init, + keys + ); if (declarator.init.type === "AssignmentExpression") { this.preWalkAssignmentExpression(declarator.init); diff --git a/test/cases/chunks/destructuring-assignment/dir1/a.js b/test/cases/chunks/destructuring-assignment/dir1/a.js new file mode 100644 index 00000000000..ce622ee6530 --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/dir1/a.js @@ -0,0 +1,3 @@ +export const a = 1; +export default 3; +export const usedExports = __webpack_exports_info__.usedExports; diff --git a/test/cases/chunks/destructuring-assignment/index.js b/test/cases/chunks/destructuring-assignment/index.js new file mode 100644 index 00000000000..626a65391e1 --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/index.js @@ -0,0 +1,12 @@ +it("should load only used exports", async (done) => { + const { default: def, usedExports } = await import("./dir1/a"); + expect(def).toBe(3); + expect(usedExports).toEqual(["default", "usedExports"]); + done(); +}); + +it("should get warning on using 'webpackExports' with destructuring assignment", async (done) => { + const { default: def } = await import(/* webpackExports: ["a"] */"./dir1/a?2"); + expect(def).toBe(3); + done(); +}); diff --git a/test/cases/chunks/destructuring-assignment/warnings.js b/test/cases/chunks/destructuring-assignment/warnings.js new file mode 100644 index 00000000000..f2a8d6f3837 --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/warnings.js @@ -0,0 +1,3 @@ +module.exports = [ + [/`webpackExports` could not be used with destructuring assignment./] +]; From a9d1df4c2262755586830f02250bdfaa9678fa9f Mon Sep 17 00:00:00 2001 From: Ivan Kopeykin Date: Sat, 15 Apr 2023 19:36:31 +0300 Subject: [PATCH 2/4] fix test cases --- test/__snapshots__/StatsTestCases.basictest.js.snap | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/__snapshots__/StatsTestCases.basictest.js.snap b/test/__snapshots__/StatsTestCases.basictest.js.snap index 0f68e9cfd26..226a274d78b 100644 --- a/test/__snapshots__/StatsTestCases.basictest.js.snap +++ b/test/__snapshots__/StatsTestCases.basictest.js.snap @@ -1840,9 +1840,9 @@ webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for output-module 1`] = ` -"asset main.mjs 10 KiB [emitted] [javascript module] (name: main) -asset 52.mjs 402 bytes [emitted] [javascript module] -runtime modules 6.07 KiB 8 modules +"asset main.mjs 9.57 KiB [emitted] [javascript module] (name: main) +asset 52.mjs 358 bytes [emitted] [javascript module] +runtime modules 5.8 KiB 7 modules orphan modules 38 bytes [orphan] 1 module cacheable modules 263 bytes ./index.js + 1 modules 225 bytes [built] [code generated] From fe818568b7826dbb01279b0d0763b5ca642ffd4b Mon Sep 17 00:00:00 2001 From: Ivan Kopeykin Date: Sat, 15 Apr 2023 21:07:51 +0300 Subject: [PATCH 3/4] fix tests --- test/cases/chunks/destructuring-assignment/test.filter.js | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 test/cases/chunks/destructuring-assignment/test.filter.js diff --git a/test/cases/chunks/destructuring-assignment/test.filter.js b/test/cases/chunks/destructuring-assignment/test.filter.js new file mode 100644 index 00000000000..181167c763e --- /dev/null +++ b/test/cases/chunks/destructuring-assignment/test.filter.js @@ -0,0 +1,4 @@ +module.exports = function(config) { + // This test can't run in development mode + return config.mode !== "development"; +}; From 185d6d651ae33280486643887e66321689b37c28 Mon Sep 17 00:00:00 2001 From: Ivan Kopeykin Date: Sat, 15 Apr 2023 22:19:26 +0300 Subject: [PATCH 4/4] fix prettier --- test/cases/chunks/destructuring-assignment/test.filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cases/chunks/destructuring-assignment/test.filter.js b/test/cases/chunks/destructuring-assignment/test.filter.js index 181167c763e..f176154b261 100644 --- a/test/cases/chunks/destructuring-assignment/test.filter.js +++ b/test/cases/chunks/destructuring-assignment/test.filter.js @@ -1,4 +1,4 @@ -module.exports = function(config) { +module.exports = function (config) { // This test can't run in development mode return config.mode !== "development"; };