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/__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] 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/test.filter.js b/test/cases/chunks/destructuring-assignment/test.filter.js new file mode 100644 index 00000000000..f176154b261 --- /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"; +}; 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./] +];