add Dependency.getCondition and conditional ModuleGraphConnections
getDependencyReference is no longer used to check of connection
This commit is contained in:
parent
180eb8ba16
commit
8d46b21fad
|
@ -239,13 +239,16 @@ class ChunkGraph {
|
|||
const { moduleGraph } = this;
|
||||
return Array.from(
|
||||
findGraphRoots(set, module => {
|
||||
return moduleGraph
|
||||
.getOutgoingConnections(module)
|
||||
.reduce((arr, connection) => {
|
||||
const module = connection.module;
|
||||
if (module) arr.push(module);
|
||||
return arr;
|
||||
}, []);
|
||||
const set = new Set();
|
||||
for (const connection of moduleGraph.getOutgoingConnections(module)) {
|
||||
if (!connection.module) continue;
|
||||
if (connection.conditional) {
|
||||
if (set.has(connection.module)) continue;
|
||||
if (!connection.active) continue;
|
||||
}
|
||||
set.add(connection.module);
|
||||
}
|
||||
return set;
|
||||
})
|
||||
).sort(compareModulesByIdentifier);
|
||||
}
|
||||
|
|
|
@ -1855,9 +1855,7 @@ class Compilation {
|
|||
* @returns {DependencyReference} a reference for the dependency
|
||||
*/
|
||||
getDependencyReference(dependency) {
|
||||
if (!this.moduleGraph.getModule(dependency)) throw new Error("TODO");
|
||||
const ref = dependency.getReference(this.moduleGraph);
|
||||
if (!ref) return null;
|
||||
return this.hooks.dependencyReference.call(ref, dependency);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,12 +81,15 @@ class Dependency {
|
|||
* @returns {DependencyReference} reference
|
||||
*/
|
||||
getReference(moduleGraph) {
|
||||
const module = moduleGraph.getModule(this);
|
||||
if (!module) return null;
|
||||
return new DependencyReference(
|
||||
() => moduleGraph.getModule(this),
|
||||
DependencyReference.NS_OBJECT_IMPORTED
|
||||
);
|
||||
return new DependencyReference(DependencyReference.NS_OBJECT_IMPORTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {function(): boolean} function to determine if the connection is active
|
||||
*/
|
||||
getCondition(moduleGraph) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -122,12 +122,15 @@ class FlagDependencyUsagePlugin {
|
|||
* @returns {void}
|
||||
*/
|
||||
const processDependency = dep => {
|
||||
const connection = moduleGraph.getConnection(dep);
|
||||
if (!connection || !connection.module || !connection.active) {
|
||||
return;
|
||||
}
|
||||
const reference = compilation.getDependencyReference(dep);
|
||||
if (!reference) return;
|
||||
const referenceModule = reference.module;
|
||||
const importedNames = reference.importedNames;
|
||||
|
||||
processModule(referenceModule, importedNames);
|
||||
processModule(connection.module, importedNames);
|
||||
};
|
||||
|
||||
for (const module of modules) {
|
||||
|
|
|
@ -331,7 +331,7 @@ class Module extends DependenciesBlock {
|
|||
const connections = moduleGraph.getIncomingConnections(this);
|
||||
return (
|
||||
connections.length > 0 &&
|
||||
connections.every(r => r.dependency && r.dependency.optional)
|
||||
connections.every(r => r.dependency && r.dependency.optional && r.active)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -384,6 +384,7 @@ class Module extends DependenciesBlock {
|
|||
hasReasonForChunk(chunk, moduleGraph, chunkGraph) {
|
||||
// check for each reason if we need the chunk
|
||||
for (const connection of moduleGraph.getIncomingConnections(this)) {
|
||||
if (!connection.active) continue;
|
||||
const fromModule = connection.originModule;
|
||||
for (const originChunk of chunkGraph.getModuleChunksIterable(
|
||||
fromModule
|
||||
|
@ -401,7 +402,7 @@ class Module extends DependenciesBlock {
|
|||
* @returns {boolean} true if at least one other module depends on this module
|
||||
*/
|
||||
hasReasons(moduleGraph) {
|
||||
return moduleGraph.getIncomingConnections(this).length > 0;
|
||||
return moduleGraph.getIncomingConnections(this).some(c => c.active);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -719,7 +719,8 @@ class ModuleGraph {
|
|||
dependency,
|
||||
module,
|
||||
undefined,
|
||||
weak
|
||||
weak,
|
||||
dependency.getCondition(this)
|
||||
);
|
||||
const mgd = this._getModuleGraphDependency(dependency);
|
||||
mgd.connection = connection;
|
||||
|
@ -745,6 +746,20 @@ class ModuleGraph {
|
|||
newMgm.incomingConnections.add(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Dependency} dependency the referencing dependency
|
||||
* @returns {void}
|
||||
*/
|
||||
removeConnection(dependency) {
|
||||
const mgd = this._getModuleGraphDependency(dependency);
|
||||
const { connection } = mgd;
|
||||
const targetMgm = this._getModuleGraphModule(connection.module);
|
||||
targetMgm.incomingConnections.delete(connection);
|
||||
const originMgm = this._getModuleGraphModule(connection.originModule);
|
||||
originMgm.outgoingConnections.delete(connection);
|
||||
mgd.connection = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Dependency} dependency the referencing dependency
|
||||
* @param {string} explanation an explanation
|
||||
|
|
|
@ -15,14 +15,25 @@ class ModuleGraphConnection {
|
|||
* @param {Module} module the referenced module
|
||||
* @param {string=} explanation some extra detail
|
||||
* @param {boolean=} weak the reference is weak
|
||||
* @param {function(): boolean=} condition condition for the connection
|
||||
*/
|
||||
constructor(originModule, dependency, module, explanation, weak = false) {
|
||||
constructor(
|
||||
originModule,
|
||||
dependency,
|
||||
module,
|
||||
explanation,
|
||||
weak = false,
|
||||
condition = undefined
|
||||
) {
|
||||
this.originModule = originModule;
|
||||
this.resolvedOriginModule = originModule;
|
||||
this.dependency = dependency;
|
||||
this.resolvedModule = module;
|
||||
this.module = module;
|
||||
this.weak = weak;
|
||||
this.conditional = !!condition;
|
||||
/** @type {function(): boolean} */
|
||||
this.condition = condition;
|
||||
/** @type {Set<string>} */
|
||||
this.explanations = new Set();
|
||||
if (explanation) {
|
||||
|
@ -30,6 +41,20 @@ class ModuleGraphConnection {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function(): boolean} condition condition for the connection
|
||||
* @returns {void}
|
||||
*/
|
||||
addCondition(condition) {
|
||||
if (this.conditional) {
|
||||
const old = this.condition;
|
||||
this.condition = () => old() && condition();
|
||||
} else {
|
||||
this.conditional = true;
|
||||
this.condition = condition;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} explanation the explanation to add
|
||||
* @returns {void}
|
||||
|
@ -41,6 +66,11 @@ class ModuleGraphConnection {
|
|||
get explanation() {
|
||||
return Array.from(this.explanations).join(" ");
|
||||
}
|
||||
|
||||
get active() {
|
||||
if (!this.conditional) return true;
|
||||
return this.condition();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ModuleGraphConnection;
|
||||
|
|
|
@ -39,7 +39,7 @@ class InferAsyncModulesPlugin {
|
|||
const connections = moduleGraph.getIncomingConnections(module);
|
||||
for (const connection of connections) {
|
||||
const dep = connection.dependency;
|
||||
if (dep instanceof HarmonyImportDependency) {
|
||||
if (dep instanceof HarmonyImportDependency && connection.active) {
|
||||
if (
|
||||
this.errorOnMissingAwait &&
|
||||
dep instanceof HarmonyImportSideEffectDependency &&
|
||||
|
|
|
@ -69,22 +69,18 @@ const extraceBlockInfoMap = compilation => {
|
|||
* @returns {void}
|
||||
*/
|
||||
const iteratorDependency = d => {
|
||||
// We skip Dependencies without Reference
|
||||
const ref = compilation.getDependencyReference(d);
|
||||
if (!ref) {
|
||||
return;
|
||||
}
|
||||
// We skip Dependencies without Module pointer
|
||||
const refModule = ref.module;
|
||||
if (!refModule) {
|
||||
return;
|
||||
}
|
||||
// We skip weak Dependencies
|
||||
if (d.weak) {
|
||||
const connection = compilation.moduleGraph.getConnection(d);
|
||||
if (
|
||||
!connection ||
|
||||
!connection.module ||
|
||||
!connection.active ||
|
||||
connection.weak
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
blockInfoModules.add(refModule);
|
||||
blockInfoModules.add(connection.module);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,16 +10,12 @@
|
|||
/** @typedef {string[]} StringArray */
|
||||
|
||||
class DependencyReference {
|
||||
// module must be dynamic, you must pass a function returning a module
|
||||
// The point is that the `module` in Dependency could be replaced i. e. because of Scope Hoisting
|
||||
/**
|
||||
*
|
||||
* @param {ModuleCallback} moduleCallback a callback to get the referenced module
|
||||
* @param {StringArray[]} importedNames imported named from the module
|
||||
* @param {number} order the order information or NaN if don't care
|
||||
*/
|
||||
constructor(moduleCallback, importedNames, order = NaN) {
|
||||
this.moduleCallback = moduleCallback;
|
||||
constructor(importedNames, order = NaN) {
|
||||
// true: full object
|
||||
// false: only sideeffects/no export
|
||||
// array of strings: the exports with this names
|
||||
|
@ -28,19 +24,21 @@ class DependencyReference {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {DependencyReference[]} array an array (will be modified)
|
||||
* @returns {DependencyReference[]} the array again
|
||||
* @template T
|
||||
* @param {T[]} array an array (will be modified)
|
||||
* @param {function(T): DependencyReference} selector selector function
|
||||
* @returns {T[]} the array again
|
||||
*/
|
||||
static sort(array) {
|
||||
/** @type {WeakMap<DependencyReference, number>} */
|
||||
const originalOrder = new WeakMap();
|
||||
static sort(array, selector) {
|
||||
/** @type {Map<T, number>} */
|
||||
const originalOrder = new Map();
|
||||
let i = 0;
|
||||
for (const ref of array) {
|
||||
originalOrder.set(ref, i++);
|
||||
}
|
||||
return array.sort((a, b) => {
|
||||
const aOrder = a.order;
|
||||
const bOrder = b.order;
|
||||
const aOrder = selector(a).order;
|
||||
const bOrder = selector(b).order;
|
||||
if (isNaN(aOrder)) {
|
||||
if (!isNaN(bOrder)) {
|
||||
return 1;
|
||||
|
@ -58,10 +56,6 @@ class DependencyReference {
|
|||
return aOrg - bOrg;
|
||||
});
|
||||
}
|
||||
|
||||
get module() {
|
||||
return this.moduleCallback();
|
||||
}
|
||||
}
|
||||
|
||||
DependencyReference.NO_IMPORTED_NAMES = [];
|
||||
|
|
|
@ -55,8 +55,6 @@ class ExportMode {
|
|||
this.ignored = null;
|
||||
/** @type {Set<string>|null} */
|
||||
this.checked = null;
|
||||
/** @type {null | function(): Module} */
|
||||
this.getModule = null;
|
||||
/** @type {string|null} */
|
||||
this.userRequest = null;
|
||||
}
|
||||
|
@ -177,14 +175,12 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
);
|
||||
|
||||
mode.name = name;
|
||||
mode.getModule = () => moduleGraph.getModule(this);
|
||||
|
||||
return mode;
|
||||
} else if (importedModule.buildMeta.exportsType === "named") {
|
||||
const mode = new ExportMode("reexport-named-default");
|
||||
|
||||
mode.name = name;
|
||||
mode.getModule = () => moduleGraph.getModule(this);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
@ -227,8 +223,6 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
}
|
||||
}
|
||||
|
||||
mode.getModule = () => moduleGraph.getModule(this);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
@ -254,8 +248,6 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
const mode = new ExportMode("dynamic-reexport");
|
||||
mode.ignored = ignoredExports;
|
||||
|
||||
mode.getModule = () => moduleGraph.getModule(this);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
@ -303,8 +295,6 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
if (merged.size === 0) {
|
||||
const mode = new ExportMode("empty-star");
|
||||
|
||||
mode.getModule = () => moduleGraph.getModule(this);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
@ -316,13 +306,24 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
|
||||
const mode = new ExportMode("normal-reexport");
|
||||
|
||||
mode.getModule = () => moduleGraph.getModule(this);
|
||||
mode.map = map;
|
||||
mode.checked = checked;
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {function(): boolean} function to determine if the connection is active
|
||||
*/
|
||||
getCondition(moduleGraph) {
|
||||
return () => {
|
||||
const mode = this.getMode(moduleGraph);
|
||||
|
||||
return mode.type !== "unused" && mode.type !== "empty-star";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the referenced module and export
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
|
@ -339,11 +340,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
|
||||
case "reexport-non-harmony-default":
|
||||
case "reexport-named-default":
|
||||
return new DependencyReference(
|
||||
mode.getModule,
|
||||
[["default"]],
|
||||
this.sourceOrder
|
||||
);
|
||||
return new DependencyReference([["default"]], this.sourceOrder);
|
||||
|
||||
case "reexport-partial-namespace-object": {
|
||||
/** @type {string[][]} */
|
||||
|
@ -365,11 +362,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
}
|
||||
};
|
||||
processExportsInfo([], mode.partialNamespaceExportsInfo);
|
||||
return new DependencyReference(
|
||||
mode.getModule,
|
||||
importedNames,
|
||||
this.sourceOrder
|
||||
);
|
||||
return new DependencyReference(importedNames, this.sourceOrder);
|
||||
}
|
||||
|
||||
case "reexport-namespace-object":
|
||||
|
@ -378,14 +371,12 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
case "reexport-non-harmony-undefined":
|
||||
case "dynamic-reexport":
|
||||
return new DependencyReference(
|
||||
mode.getModule,
|
||||
DependencyReference.NS_OBJECT_IMPORTED,
|
||||
this.sourceOrder
|
||||
);
|
||||
|
||||
case "normal-reexport":
|
||||
return new DependencyReference(
|
||||
mode.getModule,
|
||||
Array.from(mode.map.values()),
|
||||
this.sourceOrder
|
||||
);
|
||||
|
@ -439,21 +430,21 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
return {
|
||||
exports: true,
|
||||
// TODO: consider passing `ignored` from `dynamic-reexport`
|
||||
dependencies: [mode.getModule()]
|
||||
dependencies: [moduleGraph.getModule(this)]
|
||||
};
|
||||
case "empty-star":
|
||||
return {
|
||||
exports: [],
|
||||
dependencies: [mode.getModule()]
|
||||
dependencies: [moduleGraph.getModule(this)]
|
||||
};
|
||||
case "normal-reexport":
|
||||
return {
|
||||
exports: Array.from(mode.map.keys()).map(name => ({
|
||||
name,
|
||||
from: mode.getModule(),
|
||||
from: moduleGraph.getModule(this),
|
||||
export: mode.map.get(name)
|
||||
})),
|
||||
dependencies: [mode.getModule()]
|
||||
dependencies: [moduleGraph.getModule(this)]
|
||||
};
|
||||
case "reexport-fake-namespace-object":
|
||||
case "reexport-non-harmony-default":
|
||||
|
@ -462,7 +453,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
case "reexport-named-default":
|
||||
return {
|
||||
exports: [mode.name],
|
||||
dependencies: [mode.getModule()]
|
||||
dependencies: [moduleGraph.getModule(this)]
|
||||
};
|
||||
case "reexport-namespace-object":
|
||||
case "reexport-partial-namespace-object":
|
||||
|
@ -470,11 +461,11 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
exports: [
|
||||
{
|
||||
name: mode.name,
|
||||
from: mode.getModule(),
|
||||
from: moduleGraph.getModule(this),
|
||||
export: null
|
||||
}
|
||||
],
|
||||
dependencies: [mode.getModule()]
|
||||
dependencies: [moduleGraph.getModule(this)]
|
||||
};
|
||||
default:
|
||||
throw new Error(`Unknown mode ${mode.type}`);
|
||||
|
|
|
@ -41,9 +41,7 @@ class HarmonyImportDependency extends ModuleDependency {
|
|||
* @returns {DependencyReference} reference
|
||||
*/
|
||||
getReference(moduleGraph) {
|
||||
if (!moduleGraph.getModule(this)) return null;
|
||||
return new DependencyReference(
|
||||
() => moduleGraph.getModule(this),
|
||||
DependencyReference.NO_IMPORTED_NAMES,
|
||||
this.sourceOrder
|
||||
);
|
||||
|
@ -205,7 +203,10 @@ HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends
|
|||
const dep = /** @type {HarmonyImportDependency} */ (dependency);
|
||||
const { module, moduleGraph } = templateContext;
|
||||
|
||||
const referencedModule = moduleGraph.getModule(dep);
|
||||
const connection = moduleGraph.getConnection(dep);
|
||||
if (connection && !connection.active) return;
|
||||
|
||||
const referencedModule = connection && connection.module;
|
||||
const moduleKey = referencedModule
|
||||
? referencedModule.identifier()
|
||||
: dep.request;
|
||||
|
|
|
@ -21,21 +21,6 @@ class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
|
|||
super(request, sourceOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the referenced module and export
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {DependencyReference} reference
|
||||
*/
|
||||
getReference(moduleGraph) {
|
||||
const module = moduleGraph.getModule(this);
|
||||
|
||||
if (module && module.factoryMeta.sideEffectFree) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return super.getReference(moduleGraph);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "harmony side effect evaluation";
|
||||
}
|
||||
|
@ -46,21 +31,6 @@ makeSerializable(
|
|||
"webpack/lib/dependencies/HarmonyImportSideEffectDependency"
|
||||
);
|
||||
|
||||
HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDependencyTemplate extends HarmonyImportDependency.Template {
|
||||
/**
|
||||
* @param {Dependency} dependency the dependency for which the template should be applied
|
||||
* @param {ReplaceSource} source the current replace source which can be modified
|
||||
* @param {DependencyTemplateContext} templateContext the context object
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(dependency, source, templateContext) {
|
||||
const dep = /** @type {HarmonyImportSideEffectDependency} */ (dependency);
|
||||
const { moduleGraph } = templateContext;
|
||||
const module = moduleGraph.getModule(dep);
|
||||
if (!module || !module.factoryMeta.sideEffectFree) {
|
||||
super.apply(dependency, source, templateContext);
|
||||
}
|
||||
}
|
||||
};
|
||||
HarmonyImportSideEffectDependency.Template = HarmonyImportDependency.Template;
|
||||
|
||||
module.exports = HarmonyImportSideEffectDependency;
|
||||
|
|
|
@ -73,6 +73,14 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|||
moduleGraph.getMeta(this)[idsSymbol] = ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleGraph} moduleGraph module graph
|
||||
* @returns {function(): boolean} function to determine if the connection is active
|
||||
*/
|
||||
getCondition(moduleGraph) {
|
||||
return () => this.checkUsedByExports(moduleGraph);
|
||||
}
|
||||
|
||||
checkUsedByExports(moduleGraph) {
|
||||
if (this.usedByExports === false) return false;
|
||||
if (this.usedByExports !== true && this.usedByExports !== undefined) {
|
||||
|
@ -94,12 +102,8 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|||
* @returns {DependencyReference} reference
|
||||
*/
|
||||
getReference(moduleGraph) {
|
||||
if (!this.checkUsedByExports(moduleGraph)) return null;
|
||||
const module = moduleGraph.getModule(this);
|
||||
if (!module) return null;
|
||||
const ids = this.getIds(moduleGraph);
|
||||
return new DependencyReference(
|
||||
() => moduleGraph.getModule(this),
|
||||
[this.namespaceObjectAsContext ? ids.slice(0, -1) : ids],
|
||||
this.sourceOrder
|
||||
);
|
||||
|
@ -223,10 +227,12 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen
|
|||
apply(dependency, source, templateContext) {
|
||||
const dep = /** @type {HarmonyImportSpecifierDependency} */ (dependency);
|
||||
const { moduleGraph } = templateContext;
|
||||
const connection = moduleGraph.getConnection(dep);
|
||||
// Skip rendering depending when dependency is conditional
|
||||
if (!dep.checkUsedByExports(moduleGraph)) return null;
|
||||
if (connection && !connection.active) return;
|
||||
|
||||
super.apply(dependency, source, templateContext);
|
||||
|
||||
const { runtimeTemplate, module, runtimeRequirements } = templateContext;
|
||||
const ids = dep.getIds(moduleGraph);
|
||||
const exportExpr = runtimeTemplate.exportFromImport({
|
||||
|
|
|
@ -28,13 +28,8 @@ class RequireIncludeDependency extends ModuleDependency {
|
|||
* @returns {DependencyReference} reference
|
||||
*/
|
||||
getReference(moduleGraph) {
|
||||
const module = moduleGraph.getModule(this);
|
||||
if (!module) return null;
|
||||
// This doesn't use any export
|
||||
return new DependencyReference(
|
||||
() => moduleGraph.getModule(this),
|
||||
DependencyReference.NO_IMPORTED_NAMES
|
||||
);
|
||||
return new DependencyReference(DependencyReference.NO_IMPORTED_NAMES);
|
||||
}
|
||||
|
||||
get type() {
|
||||
|
|
|
@ -28,13 +28,7 @@ class WebAssemblyExportImportedDependency extends ModuleDependency {
|
|||
* @returns {DependencyReference} reference
|
||||
*/
|
||||
getReference(moduleGraph) {
|
||||
const module = moduleGraph.getModule(this);
|
||||
|
||||
if (!module) return null;
|
||||
|
||||
return new DependencyReference(() => moduleGraph.getModule(this), [
|
||||
[this.name]
|
||||
]);
|
||||
return new DependencyReference([[this.name]]);
|
||||
}
|
||||
|
||||
get type() {
|
||||
|
|
|
@ -37,13 +37,7 @@ class WebAssemblyImportDependency extends ModuleDependency {
|
|||
* @returns {DependencyReference} reference
|
||||
*/
|
||||
getReference(moduleGraph) {
|
||||
const module = moduleGraph.getModule(this);
|
||||
|
||||
if (!module) return null;
|
||||
|
||||
return new DependencyReference(() => moduleGraph.getModule(this), [
|
||||
[this.name]
|
||||
]);
|
||||
return new DependencyReference([[this.name]]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -99,6 +99,7 @@ class OccurrenceModuleIdsPlugin {
|
|||
const result =
|
||||
moduleGraph
|
||||
.getIncomingConnections(m)
|
||||
.filter(c => c.active)
|
||||
.reduce(countOccursInEntry, 0) +
|
||||
initialChunkChunkMap.get(m) +
|
||||
entryCountMap.get(m);
|
||||
|
@ -108,7 +109,10 @@ class OccurrenceModuleIdsPlugin {
|
|||
|
||||
for (const m of modules) {
|
||||
const result =
|
||||
moduleGraph.getIncomingConnections(m).reduce(countOccurs, 0) +
|
||||
moduleGraph
|
||||
.getIncomingConnections(m)
|
||||
.filter(c => c.active)
|
||||
.reduce(countOccurs, 0) +
|
||||
chunkGraph.getNumberOfModuleChunks(m) +
|
||||
entryCountMap.get(m);
|
||||
occursInAllChunksMap.set(m, result);
|
||||
|
|
|
@ -731,7 +731,7 @@ class JavascriptModulesPlugin {
|
|||
result.allowInlineStartup &&
|
||||
moduleGraph
|
||||
.getIncomingConnections(entryModule)
|
||||
.some(c => c.originModule)
|
||||
.some(c => c.originModule && c.active)
|
||||
) {
|
||||
buf2.push(
|
||||
"// This entry module is referenced by other modules so it can't be inlined"
|
||||
|
|
|
@ -706,6 +706,8 @@ class ConcatenatedModule extends Module {
|
|||
* @returns {ConcatenationEntry[]} concatenation list
|
||||
*/
|
||||
static _createConcatenationList(rootModule, modulesSet, compilation) {
|
||||
const { moduleGraph } = compilation;
|
||||
|
||||
const list = [];
|
||||
const set = new Set();
|
||||
|
||||
|
@ -715,12 +717,17 @@ class ConcatenatedModule extends Module {
|
|||
*/
|
||||
const getConcatenatedImports = module => {
|
||||
const references = module.dependencies
|
||||
.filter(dep => dep instanceof HarmonyImportDependency)
|
||||
.map(dep => compilation.getDependencyReference(dep))
|
||||
.filter(ref => ref !== null);
|
||||
DependencyReference.sort(references);
|
||||
return references.map(ref => {
|
||||
return () => ref.module;
|
||||
.filter(dep => {
|
||||
if (!(dep instanceof HarmonyImportDependency)) return false;
|
||||
const connection = moduleGraph.getConnection(dep);
|
||||
return connection && connection.module && connection.active;
|
||||
})
|
||||
.map(dep => ({ dep, ref: compilation.getDependencyReference(dep) }))
|
||||
.filter(({ ref }) => ref !== null);
|
||||
// TODO improve this
|
||||
DependencyReference.sort(references, x => x.ref);
|
||||
return references.map(({ dep }) => {
|
||||
return () => moduleGraph.getModule(dep);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -298,10 +298,15 @@ class InnerGraphPlugin {
|
|||
};
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/auto")
|
||||
.tap("HarmonyModulesPlugin", handler);
|
||||
.tap("InnerGraphPlugin", handler);
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/esm")
|
||||
.tap("HarmonyModulesPlugin", handler);
|
||||
.tap("InnerGraphPlugin", handler);
|
||||
|
||||
compilation.hooks.optimizeDependencies.tap(
|
||||
"InnerGraphPlugin",
|
||||
modules => {}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -175,12 +175,7 @@ class ModuleConcatenationPlugin {
|
|||
|
||||
const incomingConnections = moduleGraph
|
||||
.getIncomingConnections(module)
|
||||
.filter(connection => {
|
||||
return (
|
||||
!connection.originModule ||
|
||||
connection.originModule.isModuleUsed(moduleGraph)
|
||||
);
|
||||
});
|
||||
.filter(connection => connection.active);
|
||||
|
||||
// Module must only be used by Harmony Imports
|
||||
const nonHarmonyConnections = incomingConnections.filter(
|
||||
|
@ -381,30 +376,28 @@ class ModuleConcatenationPlugin {
|
|||
*/
|
||||
_getImports(compilation, module) {
|
||||
const moduleGraph = compilation.moduleGraph;
|
||||
return new Set(
|
||||
module.dependencies
|
||||
const set = new Set();
|
||||
for (const dep of module.dependencies) {
|
||||
// Get reference info only for harmony Dependencies
|
||||
if (!(dep instanceof HarmonyImportDependency)) continue;
|
||||
|
||||
// Get reference info only for harmony Dependencies
|
||||
.map(dep => {
|
||||
if (!(dep instanceof HarmonyImportDependency)) return null;
|
||||
if (!compilation) return dep.getReference(moduleGraph);
|
||||
return compilation.getDependencyReference(dep);
|
||||
})
|
||||
const connection = moduleGraph.getConnection(dep);
|
||||
// Reference is valid and has a module
|
||||
if (!connection || !connection.module || !connection.active) continue;
|
||||
|
||||
// Reference is valid and has a module
|
||||
// Dependencies are simple enough to concat them
|
||||
.filter(
|
||||
ref =>
|
||||
ref &&
|
||||
ref.module &&
|
||||
((Array.isArray(ref.importedNames) &&
|
||||
ref.importedNames.every(i => i.length > 0)) ||
|
||||
Array.isArray(moduleGraph.getProvidedExports(ref.module)))
|
||||
)
|
||||
const ref = compilation.getDependencyReference(dep);
|
||||
if (!ref) continue;
|
||||
|
||||
// Take the imported module
|
||||
.map(ref => ref.module)
|
||||
);
|
||||
const importedNames = ref.importedNames;
|
||||
if (
|
||||
(Array.isArray(importedNames) &&
|
||||
importedNames.every(i => i.length > 0)) ||
|
||||
Array.isArray(moduleGraph.getProvidedExports(module))
|
||||
) {
|
||||
set.add(connection.module);
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -443,7 +436,7 @@ class ModuleConcatenationPlugin {
|
|||
// Every module which depends on the added module must be in the configuration too.
|
||||
for (const connection of moduleGraph.getIncomingConnections(module)) {
|
||||
// Modules that are not used can be ignored
|
||||
if (!connection.originModule.isModuleUsed(moduleGraph)) continue;
|
||||
if (!connection.active) continue;
|
||||
|
||||
const problem = this._tryToAdd(
|
||||
compilation,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
const glob2regexp = require("glob-to-regexp");
|
||||
const { STAGE_DEFAULT } = require("../OptimizationStages");
|
||||
const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
|
||||
const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
|
||||
const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
|
||||
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
|
@ -107,13 +108,21 @@ class SideEffectsFlagPlugin {
|
|||
for (const [key, ids] of mode.map) {
|
||||
if (ids.length > 0 && !mode.checked.has(key)) {
|
||||
map.set(key, {
|
||||
module: mode.getModule(),
|
||||
module: moduleGraph.getModule(dep),
|
||||
exportName: ids[0]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (dep instanceof HarmonyImportSideEffectDependency) {
|
||||
const connection = moduleGraph.getConnection(dep);
|
||||
if (connection) {
|
||||
connection.addCondition(() => {
|
||||
const refModule = moduleGraph.getModule(dep);
|
||||
return !refModule || !refModule.factoryMeta.sideEffectFree;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -739,6 +739,7 @@ const SIMPLE_EXTRACTORS = {
|
|||
? reason.resolvedOriginModule.readableIdentifier(requestShortener)
|
||||
: null,
|
||||
type: reason.dependency ? reason.dependency.type : null,
|
||||
active: reason.active,
|
||||
explanation: reason.explanation,
|
||||
userRequest:
|
||||
depAsAny && "userRequest" in depAsAny ? depAsAny.userRequest : null
|
||||
|
|
|
@ -273,6 +273,8 @@ const SIMPLE_PRINTERS = {
|
|||
"moduleReason.module": (module, { magenta }) => magenta(module),
|
||||
"moduleReason.loc": loc => loc,
|
||||
"moduleReason.explanation": (explanation, { cyan }) => cyan(explanation),
|
||||
"moduleReason.active": (active, { formatFlag }) =>
|
||||
active ? undefined : formatFlag("inactive"),
|
||||
"moduleReason.resolvedModule": (module, { magenta }) => magenta(module),
|
||||
|
||||
"module.profile.total": (value, { formatTime }) => formatTime(value),
|
||||
|
@ -594,6 +596,7 @@ const PREFERED_ORDERS = {
|
|||
"modules"
|
||||
],
|
||||
moduleReason: [
|
||||
"active",
|
||||
"type",
|
||||
"userRequest",
|
||||
"moduleId",
|
||||
|
|
|
@ -33,10 +33,11 @@ class WasmFinalizeExportsPlugin {
|
|||
for (const connection of compilation.moduleGraph.getIncomingConnections(
|
||||
module
|
||||
)) {
|
||||
// 2. is referenced by a non-WebAssembly module
|
||||
// 2. is active and referenced by a non-WebAssembly module
|
||||
if (
|
||||
connection.active &&
|
||||
connection.originModule.type.startsWith("webassembly") ===
|
||||
false
|
||||
false
|
||||
) {
|
||||
const ref = compilation.getDependencyReference(
|
||||
connection.dependency
|
||||
|
|
|
@ -2550,8 +2550,8 @@ Entrypoint main = main.js
|
|||
./main.js + 1 modules 231 bytes [built]
|
||||
[no exports used]
|
||||
harmony side effect evaluation ./CompB ./components/src/CompAB/index.js 2:0-43
|
||||
harmony export imported specifier ./CompB ./components/src/CompAB/index.js 2:0-43
|
||||
harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules)
|
||||
[inactive] harmony export imported specifier ./CompB ./components/src/CompAB/index.js 2:0-43
|
||||
[inactive] harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules)
|
||||
entry ./main.js main
|
||||
| ./components/src/CompAB/CompB.js 77 bytes [built]
|
||||
| [only some exports used: default]
|
||||
|
@ -2560,33 +2560,33 @@ Entrypoint main = main.js
|
|||
| [no exports used]
|
||||
./components/src/CompAB/CompA.js 89 bytes [built]
|
||||
[only some exports used: default]
|
||||
harmony side effect evaluation ./CompA ./components/src/CompAB/index.js 1:0-43
|
||||
harmony export imported specifier ./CompA ./components/src/CompAB/index.js 1:0-43
|
||||
harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules)
|
||||
[inactive] harmony side effect evaluation ./CompA ./components/src/CompAB/index.js 1:0-43
|
||||
[inactive] harmony export imported specifier ./CompA ./components/src/CompAB/index.js 1:0-43
|
||||
[inactive] harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules)
|
||||
harmony import specifier ./components ./foo.js 3:20-25 (skipped side-effect-free modules)
|
||||
harmony import specifier ./components ./main.js + 1 modules ./main.js 3:15-20 (skipped side-effect-free modules)
|
||||
./foo.js 101 bytes [built]
|
||||
import() ./foo ./main.js + 1 modules ./main.js 6:0-15
|
||||
./components/src/index.js 84 bytes [orphan] [built]
|
||||
[module unused]
|
||||
harmony side effect evaluation ./components ./foo.js 1:0-37
|
||||
harmony side effect evaluation ./components ./main.js + 1 modules ./main.js 1:0-44
|
||||
[inactive] harmony side effect evaluation ./components ./foo.js 1:0-37
|
||||
[inactive] harmony side effect evaluation ./components ./main.js + 1 modules ./main.js 1:0-44
|
||||
./components/src/CompAB/utils.js 97 bytes [built]
|
||||
harmony side effect evaluation ./utils ./components/src/CompAB/CompA.js 1:0-35
|
||||
[inactive] harmony side effect evaluation ./utils ./components/src/CompAB/CompA.js 1:0-35
|
||||
harmony import specifier ./utils ./components/src/CompAB/CompA.js 5:5-12
|
||||
harmony side effect evaluation ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 1:0-30
|
||||
[inactive] harmony side effect evaluation ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 1:0-30
|
||||
harmony import specifier ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 5:2-5
|
||||
./components/src/CompAB/index.js 87 bytes [orphan] [built]
|
||||
[module unused]
|
||||
harmony side effect evaluation ./CompAB ./components/src/index.js 1:0-40
|
||||
[inactive] harmony side effect evaluation ./CompAB ./components/src/index.js 1:0-40
|
||||
./components/src/CompC/CompC.js 33 bytes [orphan] [built]
|
||||
[module unused]
|
||||
harmony side effect evaluation ./CompC ./components/src/CompC/index.js 1:0-34
|
||||
harmony export imported specifier ./CompC ./components/src/CompC/index.js 1:0-34
|
||||
harmony export imported specifier ./CompC ./components/src/index.js 2:0-43 (skipped side-effect-free modules)
|
||||
[inactive] harmony side effect evaluation ./CompC ./components/src/CompC/index.js 1:0-34
|
||||
[inactive] harmony export imported specifier ./CompC ./components/src/CompC/index.js 1:0-34
|
||||
[inactive] harmony export imported specifier ./CompC ./components/src/index.js 2:0-43 (skipped side-effect-free modules)
|
||||
./components/src/CompC/index.js 34 bytes [orphan] [built]
|
||||
[module unused]
|
||||
harmony side effect evaluation ./CompC ./components/src/index.js 2:0-43
|
||||
[inactive] harmony side effect evaluation ./CompC ./components/src/index.js 2:0-43
|
||||
+ 6 hidden modules"
|
||||
`;
|
||||
|
||||
|
@ -2600,27 +2600,27 @@ Entrypoint main = main.js
|
|||
./index.js + 2 modules 158 bytes [built]
|
||||
[no exports used]
|
||||
harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24
|
||||
harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24
|
||||
[inactive] harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24
|
||||
entry ./index main
|
||||
| ./node_modules/pmodule/index.js 75 bytes [built]
|
||||
| [only some exports used: default]
|
||||
| harmony side effect evaluation pmodule ./index.js 1:0-33
|
||||
| [inactive] harmony side effect evaluation pmodule ./index.js 1:0-33
|
||||
| harmony import specifier pmodule ./index.js 3:12-15
|
||||
| ./node_modules/pmodule/c.js 28 bytes [built]
|
||||
| [only some exports used: z]
|
||||
| harmony import specifier pmodule ./index.js 3:17-18 (skipped side-effect-free modules)
|
||||
| harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 (skipped side-effect-free modules)
|
||||
| [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 (skipped side-effect-free modules)
|
||||
| ./index.js 55 bytes [built]
|
||||
| [no exports used]
|
||||
./node_modules/pmodule/a.js 60 bytes [orphan] [built]
|
||||
[module unused]
|
||||
harmony side effect evaluation ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20
|
||||
harmony export imported specifier ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20
|
||||
[inactive] harmony side effect evaluation ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20
|
||||
[inactive] harmony export imported specifier ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20
|
||||
./node_modules/pmodule/b.js 69 bytes [orphan] [built]
|
||||
[module unused]
|
||||
harmony side effect evaluation ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
|
||||
harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
|
||||
harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30"
|
||||
[inactive] harmony side effect evaluation ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
|
||||
[inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
|
||||
[inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30"
|
||||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for simple 1`] = `
|
||||
|
|
|
@ -26,7 +26,8 @@ const explain = object => {
|
|||
value = JSON.stringify(value);
|
||||
}
|
||||
let msg = `${key} = ${value}`;
|
||||
if (key !== "stack" && msg.length > 100) msg = msg.slice(0, 97) + "...";
|
||||
if (key !== "stack" && key !== "details" && msg.length > 100)
|
||||
msg = msg.slice(0, 97) + "...";
|
||||
return msg;
|
||||
})
|
||||
.join("; ");
|
||||
|
|
|
@ -17,10 +17,11 @@ module.exports = {
|
|||
compilation => {
|
||||
compilation.hooks.dependencyReference.tap("Test", (ref, dep) => {
|
||||
const module = compilation.moduleGraph.getParentModule(dep);
|
||||
if (!module.identifier().endsWith("module.js")) return ref;
|
||||
const refModule = compilation.moduleGraph.getModule(dep);
|
||||
if (
|
||||
module.identifier().endsWith("module.js") &&
|
||||
ref.module &&
|
||||
ref.module.identifier().endsWith("reference.js") &&
|
||||
refModule &&
|
||||
refModule.identifier().endsWith("reference.js") &&
|
||||
Array.isArray(ref.importedNames) &&
|
||||
ref.importedNames.some(
|
||||
names => names.length === 1 && names[0] === "unused"
|
||||
|
@ -29,11 +30,7 @@ module.exports = {
|
|||
const newExports = ref.importedNames.filter(
|
||||
names => names.length !== 1 || names[0] !== "unused"
|
||||
);
|
||||
return new DependencyReference(
|
||||
() => ref.module,
|
||||
newExports,
|
||||
ref.order
|
||||
);
|
||||
return new DependencyReference(newExports, ref.order);
|
||||
}
|
||||
return ref;
|
||||
});
|
||||
|
|
|
@ -12,10 +12,11 @@ module.exports = {
|
|||
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")) return ref;
|
||||
const refModule = compilation.moduleGraph.getModule(dep);
|
||||
if (
|
||||
module.identifier().endsWith("module.js") &&
|
||||
ref.module &&
|
||||
ref.module.identifier().endsWith("reference.js") &&
|
||||
refModule &&
|
||||
refModule.identifier().endsWith("reference.js") &&
|
||||
Array.isArray(ref.importedNames) &&
|
||||
ref.importedNames.some(
|
||||
names => names.length === 1 && names[0] === "unused"
|
||||
|
@ -24,11 +25,7 @@ module.exports = {
|
|||
const newExports = ref.importedNames.filter(
|
||||
names => names.length !== 1 || names[0] !== "unused"
|
||||
);
|
||||
return new DependencyReference(
|
||||
() => ref.module,
|
||||
newExports,
|
||||
ref.order
|
||||
);
|
||||
return new DependencyReference(newExports, ref.order);
|
||||
}
|
||||
return ref;
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue