diff --git a/lib/Dependency.js b/lib/Dependency.js index dcd123d03..a523c4ad5 100644 --- a/lib/Dependency.js +++ b/lib/Dependency.js @@ -83,7 +83,7 @@ class Dependency { if (!module) return null; return new DependencyReference( () => moduleGraph.getModule(this), - true, + DependencyReference.NS_OBJECT_IMPORTED, this.weak ); } diff --git a/lib/FlagDependencyUsagePlugin.js b/lib/FlagDependencyUsagePlugin.js index 271e05e7b..874b5a687 100644 --- a/lib/FlagDependencyUsagePlugin.js +++ b/lib/FlagDependencyUsagePlugin.js @@ -7,6 +7,7 @@ const { UsageState } = require("./ModuleGraph"); const { STAGE_DEFAULT } = require("./OptimizationStages"); +const { NS_OBJECT_IMPORTED } = require("./dependencies/DependencyReference"); const Queue = require("./util/Queue"); /** @typedef {import("./Compiler")} Compiler */ @@ -15,9 +16,6 @@ const Queue = require("./util/Queue"); /** @typedef {import("./Module")} Module */ /** @typedef {import("./ModuleGraph").ExportsInfo} ExportsInfo */ -const NS_OBJ_USED = [[]]; -const NOTHING_USED = []; - class FlagDependencyUsagePlugin { /** * @param {Compiler} compiler the compiler instance @@ -92,6 +90,7 @@ class FlagDependencyUsagePlugin { } else { // for a module without side effects we stop tracking usage here when no export is used // This module won't be evaluated in this case + // TODO webpack 6 remove this check if (module.factoryMeta.sideEffectFree) return; if (exportsInfo.setUsedForSideEffectsOnly()) { queue.enqueue(module); @@ -122,14 +121,7 @@ class FlagDependencyUsagePlugin { const referenceModule = reference.module; const importedNames = reference.importedNames; - processModule( - referenceModule, - importedNames === false - ? NOTHING_USED - : importedNames === true - ? NS_OBJ_USED - : importedNames.map(n => (Array.isArray(n) ? n : [n])) - ); + processModule(referenceModule, importedNames); }; for (const module of modules) { @@ -145,7 +137,7 @@ class FlagDependencyUsagePlugin { for (const dep of deps) { const module = moduleGraph.getModule(dep); if (module) { - processModule(module, NS_OBJ_USED); + processModule(module, NS_OBJECT_IMPORTED); } } } diff --git a/lib/dependencies/DependencyReference.js b/lib/dependencies/DependencyReference.js index b69b7e666..c89574a7e 100644 --- a/lib/dependencies/DependencyReference.js +++ b/lib/dependencies/DependencyReference.js @@ -7,6 +7,7 @@ /** @typedef {import("../Module")} Module */ /** @typedef {() => Module} ModuleCallback */ +/** @typedef {string[]} StringArray */ class DependencyReference { // module must be dynamic, you must pass a function returning a module @@ -14,7 +15,7 @@ class DependencyReference { /** * * @param {ModuleCallback} moduleCallback a callback to get the referenced module - * @param {(string | string[])[] | boolean} importedNames imported named from the module + * @param {StringArray[]} importedNames imported named from the module * @param {boolean=} weak if this is a weak reference * @param {number} order the order information or NaN if don't care */ @@ -65,4 +66,7 @@ class DependencyReference { } } +DependencyReference.NO_IMPORTED_NAMES = []; +DependencyReference.NS_OBJECT_IMPORTED = [[]]; + module.exports = DependencyReference; diff --git a/lib/dependencies/HarmonyExportImportedSpecifierDependency.js b/lib/dependencies/HarmonyExportImportedSpecifierDependency.js index f0d3dc2df..1fa54155c 100644 --- a/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +++ b/lib/dependencies/HarmonyExportImportedSpecifierDependency.js @@ -339,12 +339,13 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { case "reexport-named-default": return new DependencyReference( mode.getModule, - ["default"], + [["default"]], false, this.sourceOrder ); case "reexport-partial-namespace-object": { + /** @type {string[][]} */ const importedNames = []; const processExportsInfo = (prefix, exportsInfo) => { for (const exportInfo of exportsInfo.orderedExports) { @@ -377,7 +378,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { case "reexport-non-harmony-undefined": return new DependencyReference( mode.getModule, - true, + DependencyReference.NS_OBJECT_IMPORTED, false, this.sourceOrder ); @@ -393,7 +394,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { case "dynamic-reexport": return new DependencyReference( mode.getModule, - true, + DependencyReference.NS_OBJECT_IMPORTED, false, this.sourceOrder ); diff --git a/lib/dependencies/HarmonyImportDependency.js b/lib/dependencies/HarmonyImportDependency.js index 563f3da14..381675395 100644 --- a/lib/dependencies/HarmonyImportDependency.js +++ b/lib/dependencies/HarmonyImportDependency.js @@ -40,7 +40,7 @@ class HarmonyImportDependency extends ModuleDependency { if (!moduleGraph.getModule(this)) return null; return new DependencyReference( () => moduleGraph.getModule(this), - false, + DependencyReference.NO_IMPORTED_NAMES, this.weak, this.sourceOrder ); diff --git a/lib/dependencies/HarmonyImportSpecifierDependency.js b/lib/dependencies/HarmonyImportSpecifierDependency.js index bd4fe67f6..038c0c4fe 100644 --- a/lib/dependencies/HarmonyImportSpecifierDependency.js +++ b/lib/dependencies/HarmonyImportSpecifierDependency.js @@ -81,7 +81,9 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency { const ids = this.getIds(moduleGraph); return new DependencyReference( () => moduleGraph.getModule(this), - ids.length > 0 && !this.namespaceObjectAsContext ? [ids] : true, + ids.length > 0 && !this.namespaceObjectAsContext + ? [ids] + : DependencyReference.NS_OBJECT_IMPORTED, false, this.sourceOrder ); diff --git a/lib/dependencies/RequireIncludeDependency.js b/lib/dependencies/RequireIncludeDependency.js index bc444708f..57e6da0d7 100644 --- a/lib/dependencies/RequireIncludeDependency.js +++ b/lib/dependencies/RequireIncludeDependency.js @@ -33,7 +33,7 @@ class RequireIncludeDependency extends ModuleDependency { // This doesn't use any export return new DependencyReference( () => moduleGraph.getModule(this), - false, + DependencyReference.NO_IMPORTED_NAMES, false ); } diff --git a/lib/dependencies/StaticExportsDependency.js b/lib/dependencies/StaticExportsDependency.js index 4a1f71c42..3e27579dc 100644 --- a/lib/dependencies/StaticExportsDependency.js +++ b/lib/dependencies/StaticExportsDependency.js @@ -41,7 +41,7 @@ class StaticExportsDependency extends NullDependency { // TODO introduce a flag whether exports can be mangled or not return new DependencyReference( () => moduleGraph.getParentModule(this), - true, + DependencyReference.NS_OBJECT_IMPORTED, false ); } diff --git a/lib/dependencies/WebAssemblyExportImportedDependency.js b/lib/dependencies/WebAssemblyExportImportedDependency.js index c0080d2fd..6436369a7 100644 --- a/lib/dependencies/WebAssemblyExportImportedDependency.js +++ b/lib/dependencies/WebAssemblyExportImportedDependency.js @@ -34,7 +34,7 @@ class WebAssemblyExportImportedDependency extends ModuleDependency { return new DependencyReference( () => moduleGraph.getModule(this), - [this.name], + [[this.name]], false ); } diff --git a/lib/dependencies/WebAssemblyImportDependency.js b/lib/dependencies/WebAssemblyImportDependency.js index b047b5c72..0ca6f2ad8 100644 --- a/lib/dependencies/WebAssemblyImportDependency.js +++ b/lib/dependencies/WebAssemblyImportDependency.js @@ -43,7 +43,7 @@ class WebAssemblyImportDependency extends ModuleDependency { return new DependencyReference( () => moduleGraph.getModule(this), - [this.name], + [[this.name]], false ); } diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 4e540c338..2e24d1b44 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -391,7 +391,8 @@ class ModuleConcatenationPlugin { ref => ref && ref.module && - (Array.isArray(ref.importedNames) || + ((Array.isArray(ref.importedNames) && + ref.importedNames.every(i => i.length > 0)) || Array.isArray(moduleGraph.getProvidedExports(ref.module))) ) diff --git a/lib/wasm/WasmFinalizeExportsPlugin.js b/lib/wasm/WasmFinalizeExportsPlugin.js index fd4a8ae4f..66618724a 100644 --- a/lib/wasm/WasmFinalizeExportsPlugin.js +++ b/lib/wasm/WasmFinalizeExportsPlugin.js @@ -47,10 +47,9 @@ class WasmFinalizeExportsPlugin { const importedNames = ref.importedNames; if (Array.isArray(importedNames)) { - importedNames.forEach(nameOrNames => { - const name = Array.isArray(nameOrNames) - ? nameOrNames[0] - : nameOrNames; + importedNames.forEach(names => { + if (names.length === 0) return; + const name = names[0]; // 3. and uses a func with an incompatible JS signature if ( Object.prototype.hasOwnProperty.call( diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index def7ac33a..f538dc5bb 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -2295,6 +2295,7 @@ Built at: Thu Jan 01 1970 00:00:00 GMT Entrypoint index = index.js Entrypoint entry = entry.js [10] ./index.js 150 bytes {826} [built] + ModuleConcatenation bailout: Cannot concat with ./cjs.js (<- Module is not an ECMAScript module) ModuleConcatenation bailout: Cannot concat with ./entry.js (<- Module is an entry point) ModuleConcatenation bailout: Cannot concat with ./eval.js (<- Module uses eval()) ModuleConcatenation bailout: Cannot concat with ./module-id.js (<- Module uses module.id) diff --git a/test/configCases/deep-scope-analysis/remove-export-scope-hoisting/webpack.config.js b/test/configCases/deep-scope-analysis/remove-export-scope-hoisting/webpack.config.js index 873be6c70..7273c546c 100644 --- a/test/configCases/deep-scope-analysis/remove-export-scope-hoisting/webpack.config.js +++ b/test/configCases/deep-scope-analysis/remove-export-scope-hoisting/webpack.config.js @@ -1,5 +1,8 @@ const DependencyReference = require("../../../../").dependencies .DependencyReference; + +/** @typedef {import("../../../../lib/Compilation")} Compilation */ + module.exports = { optimization: { usedExports: true, @@ -7,31 +10,38 @@ module.exports = { }, plugins: [ function() { - this.hooks.compilation.tap("Test", compilation => { - compilation.hooks.dependencyReference.tap("Test", (ref, dep) => { - const module = compilation.moduleGraph.getParentModule(dep); - if ( - module.identifier().endsWith("module.js") && - ref.module && - ref.module.identifier().endsWith("reference.js") && - Array.isArray(ref.importedNames) && - ref.importedNames.some( - names => names.length === 1 && names[0] === "unused" - ) - ) { - const newExports = ref.importedNames.filter( - names => names.length !== 1 || names[0] !== "unused" - ); - return new DependencyReference( - () => ref.module, - newExports.length > 0 ? newExports : false, - ref.weak, - ref.order - ); - } - return ref; - }); - }); + this.hooks.compilation.tap( + "Test", + /** + * @param {Compilation} compilation the compilation + * @returns {void} + */ + compilation => { + compilation.hooks.dependencyReference.tap("Test", (ref, dep) => { + const module = compilation.moduleGraph.getParentModule(dep); + if ( + module.identifier().endsWith("module.js") && + ref.module && + ref.module.identifier().endsWith("reference.js") && + Array.isArray(ref.importedNames) && + ref.importedNames.some( + names => names.length === 1 && names[0] === "unused" + ) + ) { + const newExports = ref.importedNames.filter( + names => names.length !== 1 || names[0] !== "unused" + ); + return new DependencyReference( + () => ref.module, + newExports, + ref.weak, + ref.order + ); + } + return ref; + }); + } + ); } ] }; diff --git a/test/configCases/deep-scope-analysis/remove-export/webpack.config.js b/test/configCases/deep-scope-analysis/remove-export/webpack.config.js index 063df7033..9aa041d2c 100644 --- a/test/configCases/deep-scope-analysis/remove-export/webpack.config.js +++ b/test/configCases/deep-scope-analysis/remove-export/webpack.config.js @@ -1,5 +1,8 @@ const DependencyReference = require("../../../../").dependencies .DependencyReference; + +/** @typedef {import("../../../../lib/Compilation")} Compilation */ + module.exports = { optimization: { usedExports: true, @@ -24,7 +27,7 @@ module.exports = { ); return new DependencyReference( () => ref.module, - newExports.length > 0 ? newExports : false, + newExports, ref.weak, ref.order ); diff --git a/test/configCases/parsing/harmony-this-concat/webpack.config.js b/test/configCases/parsing/harmony-this-concat/webpack.config.js index 16687213a..dfb1984cf 100644 --- a/test/configCases/parsing/harmony-this-concat/webpack.config.js +++ b/test/configCases/parsing/harmony-this-concat/webpack.config.js @@ -1,4 +1,3 @@ -var webpack = require("../../../../"); module.exports = { module: { strictThisContextOnImports: true