From a877cd51d1a579de0c42292dbe4555d43712f407 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 30 Oct 2019 06:40:40 +0100 Subject: [PATCH] add presentational dependencies which are cheaper, but allow only templating --- lib/CommonJsStuffPlugin.js | 4 +- lib/CompatibilityPlugin.js | 10 ++-- lib/ConstPlugin.js | 14 +++--- lib/DependenciesBlock.js | 24 ++------- lib/ExportsInfoApiPlugin.js | 2 +- lib/Module.js | 16 ++++++ lib/NodeStuffPlugin.js | 2 +- lib/NormalModule.js | 1 + lib/UseStrictPlugin.js | 2 +- .../AMDDefineDependencyParserPlugin.js | 12 +++-- lib/dependencies/AMDPlugin.js | 4 +- lib/dependencies/AMDRequireArrayDependency.js | 5 +- ...AMDRequireDependenciesBlockParserPlugin.js | 13 +++-- lib/dependencies/CommonJsPlugin.js | 4 +- .../CommonJsRequireDependencyParserPlugin.js | 15 +++--- .../HarmonyDetectionParserPlugin.js | 2 +- .../HarmonyExportDependencyParserPlugin.js | 4 +- .../HarmonyImportDependencyParserPlugin.js | 2 +- .../HarmonyTopLevelThisParserPlugin.js | 2 +- lib/dependencies/NullDependency.js | 8 +-- .../RequireResolveDependencyParserPlugin.js | 4 +- lib/dependencies/SystemPlugin.js | 2 +- lib/javascript/JavascriptGenerator.js | 41 ++++++++++++++- lib/javascript/JavascriptParserHelpers.js | 4 +- lib/node/NodeSourcePlugin.js | 2 +- lib/optimize/ConcatenatedModule.js | 8 +++ lib/optimize/ModuleConcatenationPlugin.js | 2 +- test/NormalModule.unittest.js | 11 ---- .../__snapshots__/StatsTestCases.test.js.snap | 50 +++++++++---------- 29 files changed, 154 insertions(+), 116 deletions(-) diff --git a/lib/CommonJsStuffPlugin.js b/lib/CommonJsStuffPlugin.js index 13c1d5a2e..cc168c7fc 100644 --- a/lib/CommonJsStuffPlugin.js +++ b/lib/CommonJsStuffPlugin.js @@ -126,7 +126,7 @@ class CommonJsStuffPlugin { RuntimeGlobals.module ]); dep.loc = expr.loc; - module.addDependency(dep); + module.addPresentationalDependency(dep); return true; } return toConstantDependency( @@ -167,7 +167,7 @@ class CommonJsStuffPlugin { : RuntimeGlobals.nodeModuleDecorator ); dep.loc = expr.loc; - parser.state.module.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }); }; diff --git a/lib/CompatibilityPlugin.js b/lib/CompatibilityPlugin.js index 7fbd87f4b..86ab92b56 100644 --- a/lib/CompatibilityPlugin.js +++ b/lib/CompatibilityPlugin.js @@ -46,7 +46,7 @@ class CompatibilityPlugin { if (second.asBool() !== true) return; const dep = new ConstDependency("require", expr.callee.range); dep.loc = expr.loc; - if (parser.state.current.dependencies.length > 1) { + if (parser.state.current.dependencies.length > 0) { const last = parser.state.current.dependencies[ parser.state.current.dependencies.length - 1 @@ -60,7 +60,7 @@ class CompatibilityPlugin { ) parser.state.current.dependencies.pop(); } - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }); }); @@ -81,7 +81,7 @@ class CompatibilityPlugin { }__`; const dep = new ConstDependency(newName, statement.id.range); dep.loc = statement.id.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); parser.tagVariable( statement.id.name, nestedWebpackRequireTag, @@ -96,7 +96,7 @@ class CompatibilityPlugin { const newName = `__nested_webpack_require_${pattern.range[0]}__`; const dep = new ConstDependency(newName, pattern.range); dep.loc = pattern.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); parser.tagVariable( pattern.name, nestedWebpackRequireTag, @@ -110,7 +110,7 @@ class CompatibilityPlugin { const newName = parser.currentTagData; const dep = new ConstDependency(newName, expr.range); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }); }; diff --git a/lib/ConstPlugin.js b/lib/ConstPlugin.js index 5d9d5344b..ce0d167d4 100644 --- a/lib/ConstPlugin.js +++ b/lib/ConstPlugin.js @@ -137,7 +137,7 @@ class ConstPlugin { if (statement.test.type !== "Literal") { const dep = new ConstDependency(`${bool}`, param.range); dep.loc = statement.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); } const branchToRemove = bool ? statement.alternate @@ -193,7 +193,7 @@ class ConstPlugin { branchToRemove.range ); dep.loc = branchToRemove.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); } return bool; } @@ -207,7 +207,7 @@ class ConstPlugin { if (expression.test.type !== "Literal") { const dep = new ConstDependency(` ${bool}`, param.range); dep.loc = expression.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); } // Expressions do not hoist. // It is safe to remove the dead branch. @@ -228,7 +228,7 @@ class ConstPlugin { branchToRemove.range ); dep.loc = branchToRemove.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return bool; } } @@ -301,7 +301,7 @@ class ConstPlugin { // const dep = new ConstDependency(` ${bool}`, param.range); dep.loc = expression.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); } else { parser.walkExpression(expression.left); } @@ -311,7 +311,7 @@ class ConstPlugin { expression.right.range ); dep.loc = expression.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); } return keepRight; } @@ -336,7 +336,7 @@ class ConstPlugin { "__resourceQuery" ); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }); }; diff --git a/lib/DependenciesBlock.js b/lib/DependenciesBlock.js index 1dd870118..d0be66579 100644 --- a/lib/DependenciesBlock.js +++ b/lib/DependenciesBlock.js @@ -61,30 +61,12 @@ class DependenciesBlock { * @returns {void} */ updateHash(hash, chunkGraph) { - for (const dep of this.dependencies) dep.updateHash(hash, chunkGraph); - for (const block of this.blocks) block.updateHash(hash, chunkGraph); - } - - /** - * @param {DependencyFilterFunction} filter filter function for dependencies, gets passed all dependency ties from current instance - * @returns {boolean} returns boolean for filter - */ - hasDependencies(filter) { - if (filter) { - for (const dep of this.dependencies) { - if (filter(dep)) return true; - } - } else { - if (this.dependencies.length > 0) { - return true; - } + for (const dep of this.dependencies) { + dep.updateHash(hash, chunkGraph); } - for (const block of this.blocks) { - if (block.hasDependencies(filter)) return true; + block.updateHash(hash, chunkGraph); } - - return false; } serialize({ write }) { diff --git a/lib/ExportsInfoApiPlugin.js b/lib/ExportsInfoApiPlugin.js index 8e334170b..128d66547 100644 --- a/lib/ExportsInfoApiPlugin.js +++ b/lib/ExportsInfoApiPlugin.js @@ -49,7 +49,7 @@ class ExportsInfoApiPlugin { .tap("ExportsInfoApiPlugin", expr => { const dep = new ConstDependency("true", expr.range); dep.loc = expr.loc; - parser.state.module.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }); }; diff --git a/lib/Module.js b/lib/Module.js index 8c94b290d..62e92b7db 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -116,6 +116,8 @@ class Module extends DependenciesBlock { this.buildMeta = undefined; /** @type {object} */ this.buildInfo = undefined; + /** @type {Dependency[]} */ + this.presentationalDependencies = []; } // TODO remove in webpack 6 @@ -323,6 +325,15 @@ class Module extends DependenciesBlock { return (this.buildInfo && this.buildInfo.moduleArgument) || "module"; } + /** + * @param {Dependency} presentationalDependency dependency being tied to module. + * This is a Dependency without edge in the module graph. It's only for presentation. + * @returns {void} + */ + addPresentationalDependency(presentationalDependency) { + this.presentationalDependencies.push(presentationalDependency); + } + /** * @param {ModuleGraph} moduleGraph the module graph * @returns {boolean} true, if the module is optional @@ -483,6 +494,9 @@ class Module extends DependenciesBlock { hash.update(exportInfo.used + ""); hash.update(exportInfo.usedName + ""); } + for (const dep of this.presentationalDependencies) { + dep.updateHash(hash, chunkGraph); + } super.updateHash(hash, chunkGraph); } @@ -659,6 +673,7 @@ class Module extends DependenciesBlock { write(this.errors); write(this.buildMeta); write(this.buildInfo); + write(this.presentationalDependencies); super.serialize(context); } @@ -673,6 +688,7 @@ class Module extends DependenciesBlock { this.errors = read(); this.buildMeta = read(); this.buildInfo = read(); + this.presentationalDependencies = read(); super.deserialize(context); } } diff --git a/lib/NodeStuffPlugin.js b/lib/NodeStuffPlugin.js index 3088c8cd3..d2c8e0db4 100644 --- a/lib/NodeStuffPlugin.js +++ b/lib/NodeStuffPlugin.js @@ -51,7 +51,7 @@ class NodeStuffPlugin { expressionName ); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }); }; diff --git a/lib/NormalModule.js b/lib/NormalModule.js index a87cd8e37..d08cfd838 100644 --- a/lib/NormalModule.js +++ b/lib/NormalModule.js @@ -559,6 +559,7 @@ class NormalModule extends Module { this.errors.length = 0; this.warnings.length = 0; this.dependencies.length = 0; + this.presentationalDependencies.length = 0; this.blocks.length = 0; this.buildMeta = {}; this.buildInfo = { diff --git a/lib/UseStrictPlugin.js b/lib/UseStrictPlugin.js index d2bfd6fe7..1f3fe2863 100644 --- a/lib/UseStrictPlugin.js +++ b/lib/UseStrictPlugin.js @@ -32,7 +32,7 @@ class UseStrictPlugin { // @see https://github.com/webpack/webpack/issues/1970 const dep = new ConstDependency("", firstNode.range); dep.loc = firstNode.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); parser.state.module.buildInfo.strict = true; } }); diff --git a/lib/dependencies/AMDDefineDependencyParserPlugin.js b/lib/dependencies/AMDDefineDependencyParserPlugin.js index af02ad7cd..a5bdb4655 100644 --- a/lib/dependencies/AMDDefineDependencyParserPlugin.js +++ b/lib/dependencies/AMDDefineDependencyParserPlugin.js @@ -80,7 +80,7 @@ class AMDDefineDependencyParserPlugin { localModule.flagUsed(); dep = new LocalModuleDependency(localModule, undefined, false); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); } else { dep = this.newRequireItemDependency(request); dep.loc = expr.loc; @@ -92,7 +92,7 @@ class AMDDefineDependencyParserPlugin { const dep = this.newRequireArrayDependency(deps, param.range); dep.loc = expr.loc; dep.optional = !!parser.scope.inTry; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; } } @@ -126,10 +126,12 @@ class AMDDefineDependencyParserPlugin { dep = new LocalModuleDependency(localModule, param.range, false); } else { dep = this.newRequireItemDependency(param.string, param.range); + dep.optional = !!parser.scope.inTry; + parser.state.current.addDependency(dep); + return true; } dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; } } @@ -311,7 +313,7 @@ class AMDDefineDependencyParserPlugin { if (namedModule) { dep.localModule = addLocalModule(parser.state, namedModule); } - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; } diff --git a/lib/dependencies/AMDPlugin.js b/lib/dependencies/AMDPlugin.js index 1100565b9..4d6952b42 100644 --- a/lib/dependencies/AMDPlugin.js +++ b/lib/dependencies/AMDPlugin.js @@ -168,7 +168,7 @@ class AMDPlugin { [RuntimeGlobals.amdDefine] ); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.typeof @@ -188,7 +188,7 @@ class AMDPlugin { [RuntimeGlobals.amdDefine] ); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return false; }); parser.hooks.typeof diff --git a/lib/dependencies/AMDRequireArrayDependency.js b/lib/dependencies/AMDRequireArrayDependency.js index 350d314ab..dd1ac833c 100644 --- a/lib/dependencies/AMDRequireArrayDependency.js +++ b/lib/dependencies/AMDRequireArrayDependency.js @@ -5,14 +5,15 @@ "use strict"; -const Dependency = require("../Dependency"); const DependencyTemplate = require("../DependencyTemplate"); const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ -class AMDRequireArrayDependency extends Dependency { +class AMDRequireArrayDependency extends NullDependency { constructor(depsArray, range) { super(); diff --git a/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js b/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js index 809a5b897..5e6ccac7d 100644 --- a/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +++ b/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js @@ -80,7 +80,7 @@ class AMDRequireDependenciesBlockParserPlugin { localModule.flagUsed(); dep = new LocalModuleDependency(localModule, undefined, false); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); } else { dep = this.newRequireItemDependency(request); dep.loc = expr.loc; @@ -92,7 +92,7 @@ class AMDRequireDependenciesBlockParserPlugin { const dep = this.newRequireArrayDependency(deps, param.range); dep.loc = expr.loc; dep.optional = !!parser.scope.inTry; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; } } @@ -128,10 +128,13 @@ class AMDRequireDependenciesBlockParserPlugin { dep = new LocalModuleDependency(localModule, param.range, false); } else { dep = this.newRequireItemDependency(param.string, param.range); + dep.loc = expr.loc; + dep.optional = !!parser.scope.inTry; + parser.state.current.addDependency(dep); + return true; } dep.loc = expr.loc; - dep.optional = !!parser.scope.inTry; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; } } @@ -217,7 +220,7 @@ class AMDRequireDependenciesBlockParserPlugin { }); if (!result) { const dep = new UnsupportedDependency("unsupported", expr.range); - old.addDependency(dep); + old.addPresentationalDependency(dep); if (parser.state.module) { parser.state.module.errors.push( new UnsupportedFeatureWarning( diff --git a/lib/dependencies/CommonJsPlugin.js b/lib/dependencies/CommonJsPlugin.js index 3abb11e86..543165d29 100644 --- a/lib/dependencies/CommonJsPlugin.js +++ b/lib/dependencies/CommonJsPlugin.js @@ -121,7 +121,7 @@ class CommonJsPlugin { // to not leak to global "require", we need to define a local require here. const dep = new ConstDependency("var require;", 0); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }); parser.hooks.canRename @@ -131,7 +131,7 @@ class CommonJsPlugin { // To avoid "not defined" error, replace the value with undefined const dep = new ConstDependency("undefined", expr.range); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return false; }); parser.hooks.typeof diff --git a/lib/dependencies/CommonJsRequireDependencyParserPlugin.js b/lib/dependencies/CommonJsRequireDependencyParserPlugin.js index 6ca53a1d3..cb94089b5 100644 --- a/lib/dependencies/CommonJsRequireDependencyParserPlugin.js +++ b/lib/dependencies/CommonJsRequireDependencyParserPlugin.js @@ -85,19 +85,16 @@ class CommonJsRequireDependencyParserPlugin { const param = parser.evaluateExpression(expr.arguments[0]); if (param.isConditional()) { let isExpression = false; - const prevLength = parser.state.current.dependencies.length; - const dep = new RequireHeaderDependency(expr.callee.range); - dep.loc = expr.loc; - parser.state.current.addDependency(dep); for (const p of param.options) { const result = processItem(expr, p); if (result === undefined) { isExpression = true; } } - if (isExpression) { - parser.state.current.dependencies.length = prevLength; - } else { + if (!isExpression) { + const dep = new RequireHeaderDependency(expr.callee.range); + dep.loc = expr.loc; + parser.state.module.addPresentationalDependency(dep); return true; } } @@ -108,7 +105,7 @@ class CommonJsRequireDependencyParserPlugin { localModule.flagUsed(); const dep = new LocalModuleDependency(localModule, expr.range, callNew); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; } else { const result = processItem(expr, param); @@ -117,7 +114,7 @@ class CommonJsRequireDependencyParserPlugin { } else { const dep = new RequireHeaderDependency(expr.callee.range); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); } return true; } diff --git a/lib/dependencies/HarmonyDetectionParserPlugin.js b/lib/dependencies/HarmonyDetectionParserPlugin.js index a5297aa4f..941b66420 100644 --- a/lib/dependencies/HarmonyDetectionParserPlugin.js +++ b/lib/dependencies/HarmonyDetectionParserPlugin.js @@ -47,7 +47,7 @@ module.exports = class HarmonyDetectionParserPlugin { }, index: -3 }; - module.addDependency(compatDep); + module.addPresentationalDependency(compatDep); parser.state.harmonyModule = true; parser.scope.isStrict = true; module.buildMeta.exportsType = "namespace"; diff --git a/lib/dependencies/HarmonyExportDependencyParserPlugin.js b/lib/dependencies/HarmonyExportDependencyParserPlugin.js index e461681ab..955b856ab 100644 --- a/lib/dependencies/HarmonyExportDependencyParserPlugin.js +++ b/lib/dependencies/HarmonyExportDependencyParserPlugin.js @@ -33,7 +33,7 @@ module.exports = class HarmonyExportDependencyParserPlugin { ); dep.loc = Object.create(statement.loc); dep.loc.index = -1; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; } ); @@ -45,7 +45,7 @@ module.exports = class HarmonyExportDependencyParserPlugin { const clearDep = new ConstDependency("", statement.range); clearDep.loc = Object.create(statement.loc); clearDep.loc.index = -1; - parser.state.current.addDependency(clearDep); + parser.state.module.addPresentationalDependency(clearDep); const sideEffectDep = new HarmonyImportSideEffectDependency( source, parser.state.lastHarmonyImportOrder diff --git a/lib/dependencies/HarmonyImportDependencyParserPlugin.js b/lib/dependencies/HarmonyImportDependencyParserPlugin.js index fc29003c3..532ffbf03 100644 --- a/lib/dependencies/HarmonyImportDependencyParserPlugin.js +++ b/lib/dependencies/HarmonyImportDependencyParserPlugin.js @@ -43,7 +43,7 @@ module.exports = class HarmonyImportDependencyParserPlugin { (parser.state.lastHarmonyImportOrder || 0) + 1; const clearDep = new ConstDependency("", statement.range); clearDep.loc = statement.loc; - parser.state.module.addDependency(clearDep); + parser.state.module.addPresentationalDependency(clearDep); const sideEffectDep = new HarmonyImportSideEffectDependency( source, parser.state.lastHarmonyImportOrder diff --git a/lib/dependencies/HarmonyTopLevelThisParserPlugin.js b/lib/dependencies/HarmonyTopLevelThisParserPlugin.js index 57c9c8868..1ecc3f7ce 100644 --- a/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +++ b/lib/dependencies/HarmonyTopLevelThisParserPlugin.js @@ -18,7 +18,7 @@ class HarmonyTopLevelThisParserPlugin { if (isHarmony) { const dep = new ConstDependency("undefined", node.range, null); dep.loc = node.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); } }); } diff --git a/lib/dependencies/NullDependency.js b/lib/dependencies/NullDependency.js index 722bf51c1..1f6502631 100644 --- a/lib/dependencies/NullDependency.js +++ b/lib/dependencies/NullDependency.js @@ -28,12 +28,12 @@ class NullDependency extends Dependency { */ updateHash(hash, chunkGraph) {} - serialize(context) { - // do nothing + serialize({ write }) { + write(this.loc); } - deserialize(context) { - // do nothing + deserialize({ read }) { + this.loc = read(); } } diff --git a/lib/dependencies/RequireResolveDependencyParserPlugin.js b/lib/dependencies/RequireResolveDependencyParserPlugin.js index 5ab3a2ce3..5fce979ac 100644 --- a/lib/dependencies/RequireResolveDependencyParserPlugin.js +++ b/lib/dependencies/RequireResolveDependencyParserPlugin.js @@ -30,7 +30,7 @@ class RequireResolveDependencyParserPlugin { } const dep = new RequireResolveHeaderDependency(expr.callee.range); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; } else { const result = processItem(expr, param, weak); @@ -39,7 +39,7 @@ class RequireResolveDependencyParserPlugin { } const dep = new RequireResolveHeaderDependency(expr.callee.range); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; } }; diff --git a/lib/dependencies/SystemPlugin.js b/lib/dependencies/SystemPlugin.js index d12ae717b..3731fec9d 100644 --- a/lib/dependencies/SystemPlugin.js +++ b/lib/dependencies/SystemPlugin.js @@ -91,7 +91,7 @@ class SystemPlugin { RuntimeGlobals.system ]); dep.loc = expr.loc; - parser.state.module.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }); diff --git a/lib/javascript/JavascriptGenerator.js b/lib/javascript/JavascriptGenerator.js index 5ff1db149..570d9a17c 100644 --- a/lib/javascript/JavascriptGenerator.js +++ b/lib/javascript/JavascriptGenerator.js @@ -85,7 +85,7 @@ class JavascriptGenerator extends Generator { const source = new ReplaceSource(originalSource); const initFragments = []; - this.sourceBlock(module, module, initFragments, source, generateContext); + this.sourceModule(module, initFragments, source, generateContext); if (initFragments.length > 0) { // Sort fragments by position. If 2 fragments have the same position, @@ -130,6 +130,45 @@ class JavascriptGenerator extends Generator { } } + /** + * @param {Module} module the module to generate + * @param {InitFragment[]} initFragments mutable list of init fragments + * @param {ReplaceSource} source the current replace source which can be modified + * @param {GenerateContext} generateContext the generateContext + * @returns {void} + */ + sourceModule(module, initFragments, source, generateContext) { + for (const dependency of module.dependencies) { + this.sourceDependency( + module, + dependency, + initFragments, + source, + generateContext + ); + } + + for (const dependency of module.presentationalDependencies) { + this.sourceDependency( + module, + dependency, + initFragments, + source, + generateContext + ); + } + + for (const childBlock of module.blocks) { + this.sourceBlock( + module, + childBlock, + initFragments, + source, + generateContext + ); + } + } + /** * @param {Module} module the module to generate * @param {DependenciesBlock} block the dependencies block which will be processed diff --git a/lib/javascript/JavascriptParserHelpers.js b/lib/javascript/JavascriptParserHelpers.js index 671093bc0..08dc43c65 100644 --- a/lib/javascript/JavascriptParserHelpers.js +++ b/lib/javascript/JavascriptParserHelpers.js @@ -13,7 +13,7 @@ exports.toConstantDependency = (parser, value, runtimeRequirements) => { return function constDependency(expr) { const dep = new ConstDependency(value, expr.range, runtimeRequirements); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); return true; }; }; @@ -50,7 +50,7 @@ exports.expressionIsUnsupported = (parser, message) => { return function unsupportedExpression(expr) { const dep = new ConstDependency("(void 0)", expr.range, null); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); if (!parser.state.module) return; parser.state.module.warnings.push( new UnsupportedFeatureWarning(message, expr.loc) diff --git a/lib/node/NodeSourcePlugin.js b/lib/node/NodeSourcePlugin.js index 4618db905..bdbdd6dae 100644 --- a/lib/node/NodeSourcePlugin.js +++ b/lib/node/NodeSourcePlugin.js @@ -51,7 +51,7 @@ module.exports = class NodeSourcePlugin { [RuntimeGlobals.global] ); dep.loc = expr.loc; - parser.state.module.addDependency(dep); + parser.state.module.addPresentationalDependency(dep); }); } }; diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index cb46be97d..0d47227bd 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -577,6 +577,7 @@ class ConcatenatedModule extends Module { // Graph this.dependencies = []; + this.presentationalDependencies = []; this.warnings = []; this.errors = []; @@ -597,6 +598,13 @@ class ConcatenatedModule extends Module { )) { this.dependencies.push(d); } + for (const d of m.presentationalDependencies.filter( + dep => + !(dep instanceof HarmonyImportDependency) || + !modules.has(compilation.moduleGraph.getModule(dep)) + )) { + this.presentationalDependencies.push(d); + } // populate file dependencies if (m.buildInfo.fileDependencies) { this.buildInfo.fileDependencies.addAll(m.buildInfo.fileDependencies); diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 680aca6b2..a273e0ed4 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -113,7 +113,7 @@ class ModuleConcatenationPlugin { if ( !module.buildMeta || module.buildMeta.exportsType !== "namespace" || - !module.dependencies.some( + !module.presentationalDependencies.some( d => d instanceof HarmonyCompatibilityDependency ) ) { diff --git a/test/NormalModule.unittest.js b/test/NormalModule.unittest.js index 6a8a4c693..3e95e99aa 100644 --- a/test/NormalModule.unittest.js +++ b/test/NormalModule.unittest.js @@ -1,7 +1,6 @@ "use strict"; const NormalModule = require("../lib/NormalModule"); -const NullDependency = require("../lib/dependencies/NullDependency"); const SourceMapSource = require("webpack-sources").SourceMapSource; const OriginalSource = require("webpack-sources").OriginalSource; const RawSource = require("webpack-sources").RawSource; @@ -180,16 +179,6 @@ describe("NormalModule", () => { }); }); - describe("#hasDependencies", () => { - it("returns true if has dependencies", () => { - normalModule.addDependency(new NullDependency()); - expect(normalModule.hasDependencies()).toBe(true); - }); - it("returns false if has dependencies", () => { - expect(normalModule.hasDependencies()).toBe(false); - }); - }); - describe("#applyNoParseRule", () => { let rule; let content; diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index fba4a3a0f..229552326 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -131,7 +131,7 @@ chunk 6e33027b71300dfeba9c.js 899 bytes [rendered] `; exports[`StatsTestCases should print correct stats for asset 1`] = ` -"Hash: c4ecc4ac09c06c7d509b +"Hash: dadbda930e31fde61024 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -447,7 +447,7 @@ Child all: `; exports[`StatsTestCases should print correct stats for chunk-module-id-range 1`] = ` -"Hash: a800a9ba396856feaf95 +"Hash: e10aafeb076eef8f2bd1 Time: Xms Built at: 1970-04-20 12:42:42 PublicPath: (none) @@ -515,7 +515,7 @@ chunk 996.bundle.js 22 bytes <{179}> [rendered] `; exports[`StatsTestCases should print correct stats for chunks-development 1`] = ` -"Hash: d20813bc827ce6429e48 +"Hash: 2a11303e167e5005439e Time: Xms Built at: 1970-04-20 12:42:42 PublicPath: (none) @@ -635,26 +635,26 @@ Entrypoint entry-1 = vendor-1.js entry-1.js `; exports[`StatsTestCases should print correct stats for commons-plugin-issue-4980 1`] = ` -"Hash: 0322711dda6b150ea64813be0c2c5ac4f1ee233a +"Hash: 11c5088030cef384e47e64484202182c974f95ad Child - Hash: 0322711dda6b150ea648 + Hash: 11c5088030cef384e47e Time: Xms Built at: 1970-04-20 12:42:42 Asset Size - app.b82161e9590d9f4a5710.js 5.81 KiB [emitted] [immutable] [name: app] + app.d6fd64d04ea003e46dd3.js 5.81 KiB [emitted] [immutable] [name: app] vendor.4101ce64a32446c20561.js 615 bytes [emitted] [immutable] [name: vendor] [id hint: vendor] - Entrypoint app = vendor.4101ce64a32446c20561.js app.b82161e9590d9f4a5710.js + Entrypoint app = vendor.4101ce64a32446c20561.js app.d6fd64d04ea003e46dd3.js ./entry-1.js + 2 modules 190 bytes [built] ./constants.js 87 bytes [built] + 2 hidden modules Child - Hash: 13be0c2c5ac4f1ee233a + Hash: 64484202182c974f95ad Time: Xms Built at: 1970-04-20 12:42:42 Asset Size - app.58ab2273685a00b61215.js 5.82 KiB [emitted] [immutable] [name: app] + app.627c1e16b9b5fb645153.js 5.82 KiB [emitted] [immutable] [name: app] vendor.4101ce64a32446c20561.js 615 bytes [emitted] [immutable] [name: vendor] [id hint: vendor] - Entrypoint app = vendor.4101ce64a32446c20561.js app.58ab2273685a00b61215.js + Entrypoint app = vendor.4101ce64a32446c20561.js app.627c1e16b9b5fb645153.js ./entry-2.js + 2 modules 197 bytes [built] ./constants.js 87 bytes [built] + 2 hidden modules" @@ -678,9 +678,9 @@ exports[`StatsTestCases should print correct stats for concat-and-sideeffects 1` `; exports[`StatsTestCases should print correct stats for define-plugin 1`] = ` -"Hash: b25ebe7b7b295232a01a9a8d6feecff6652bf00eff7e4a0e0f4379e59b2f +"Hash: 2ecfff95a59c6f113f4caba827c90e84dff35788e10eff264a44ee9769ee Child - Hash: b25ebe7b7b295232a01a + Hash: 2ecfff95a59c6f113f4c Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -688,7 +688,7 @@ Child Entrypoint main = main.js ./index.js 24 bytes [built] Child - Hash: 9a8d6feecff6652bf00e + Hash: aba827c90e84dff35788 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -696,7 +696,7 @@ Child Entrypoint main = main.js ./index.js 24 bytes [built] Child - Hash: ff7e4a0e0f4379e59b2f + Hash: e10eff264a44ee9769ee Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -729,7 +729,7 @@ Unexpected end of JSON input while parsing near '' `; exports[`StatsTestCases should print correct stats for exclude-with-loader 1`] = ` -"Hash: 573a41a01a055998604c +"Hash: 044cc6bde1cac542bb22 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -1379,7 +1379,7 @@ Entrypoint main = main.js `; exports[`StatsTestCases should print correct stats for module-assets 1`] = ` -"Hash: 800a7c66f127dad910e9 +"Hash: 76c6284536c6eaf93eee Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -1530,7 +1530,7 @@ If you don't want to include a polyfill, you can use an empty module like this: `; exports[`StatsTestCases should print correct stats for module-reasons 1`] = ` -"Hash: bb6f434427ef3617b391 +"Hash: b6469c24aa4c7dbb128f Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -2463,7 +2463,7 @@ Entrypoint e2 = runtime.js e2.js" `; exports[`StatsTestCases should print correct stats for scope-hoisting-bailouts 1`] = ` -"Hash: 2850abf0834f38d62af2 +"Hash: afd1db97faf25e43672d Time: Xms Built at: 1970-04-20 12:42:42 Entrypoint index = index.js @@ -2493,9 +2493,9 @@ external \\"external\\" 42 bytes [built] `; exports[`StatsTestCases should print correct stats for scope-hoisting-multi 1`] = ` -"Hash: 95f50af5185d282dcfbaf2c6d907d9d0df616dd7 +"Hash: 36ff61b79bdd38770761a5ce538ce4ef736da453 Child - Hash: 95f50af5185d282dcfba + Hash: 36ff61b79bdd38770761 Time: Xms Built at: 1970-04-20 12:42:42 Entrypoint first = vendor.js first.js @@ -2513,7 +2513,7 @@ Child ./common_lazy_shared.js 25 bytes [built] + 10 hidden modules Child - Hash: f2c6d907d9d0df616dd7 + Hash: a5ce538ce4ef736da453 Time: Xms Built at: 1970-04-20 12:42:42 Entrypoint first = vendor.js first.js @@ -2540,7 +2540,7 @@ Child `; exports[`StatsTestCases should print correct stats for side-effects-issue-7428 1`] = ` -"Hash: ee17dcba81fb391501b7 +"Hash: 511b75a49bce32fdac1f Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -2591,7 +2591,7 @@ Entrypoint main = main.js `; exports[`StatsTestCases should print correct stats for side-effects-simple-unused 1`] = ` -"Hash: 97eddf49297c8cbcd004 +"Hash: 5410fc291f7069e82143 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -3624,7 +3624,7 @@ chunk default/async-a.js (async-a) 134 bytes <{179}> [rendered] `; exports[`StatsTestCases should print correct stats for tree-shaking 1`] = ` -"Hash: 555c0be8eff50e0d063c +"Hash: 2332981f69bd5553a2d4 Time: Xms Built at: 1970-04-20 12:42:42 Asset Size @@ -3691,7 +3691,7 @@ WARNING in Terser Plugin: Dropping unused function someUnRemoteUsedFunction5 [./ `; exports[`StatsTestCases should print correct stats for wasm-explorer-examples-sync 1`] = ` -"Hash: 2c3fdc9668c0d61e8c09 +"Hash: 86e17ac033d009dc7bfc Time: Xms Built at: 1970-04-20 12:42:42 Asset Size