add backward-compat layer for ModuleGraph and ChunkGraph

This commit is contained in:
Tobias Koppers 2018-08-21 16:15:48 +02:00
parent 42167db4af
commit 5a78e96dc9
6 changed files with 440 additions and 7 deletions

View File

@ -5,13 +5,13 @@
"use strict";
const ChunkGraph = require("./ChunkGraph");
const Entrypoint = require("./Entrypoint");
const { intersect } = require("./util/SetHelpers");
const SortableSet = require("./util/SortableSet");
const { compareModulesById } = require("./util/comparators");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./ChunkGroup")} ChunkGroup */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./Module")} Module */
@ -89,6 +89,169 @@ class Chunk {
this.removedModules = undefined;
}
// TODO remove in webpack 6
// BACKWARD-COMPAT START
get entryModule() {
const entryModules = Array.from(
ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.entryModule"
).getChunkEntryModulesIterable(this)
);
if (entryModules.length === 0) {
return undefined;
} else if (entryModules.length === 1) {
return entryModules[0];
} else {
throw new Error(
"Module.entryModule: Multiple entry modules are not supported by the deprecated API (Use the new ChunkGroup API)"
);
}
}
hasEntryModule() {
return (
ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.hasEntryModule"
).getNumberOfEntryModules(this) > 0
);
}
addModule(module) {
return ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.addModule"
).connectChunkAndModule(this, module);
}
removeModule(module) {
return ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.removeModule"
).disconnectChunkAndModule(this, module);
}
getNumberOfModules() {
return ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.getNumberOfModules"
).getNumberOfChunkModules(this);
}
get modulesIterable() {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.modulesIterable"
);
return chunkGraph.getOrderedChunkModulesIterable(
this,
compareModulesById(chunkGraph._moduleGraph)
);
}
compareTo(otherChunk) {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.compareTo"
);
return chunkGraph.compareChunks(chunkGraph._moduleGraph, this, otherChunk);
}
containsModule(module) {
return ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.containsModule"
).isModuleInChunk(module, this);
}
getModules() {
return ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.getModules"
).getChunkModules(this);
}
remove() {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(this, "Chunk.remove");
chunkGraph.disconnectChunk(this);
this.disconnectFromGroups();
}
moveModule(module, otherChunk) {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.moveModule"
);
chunkGraph.disconnectChunkAndModule(this, module);
chunkGraph.connectChunkAndModule(otherChunk, module);
}
integrate(otherChunk) {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.integrate"
);
if (!chunkGraph.canChunksBeIntegrated(this, otherChunk)) return false;
chunkGraph.integrateChunks(this, otherChunk);
return true;
}
canBeIntegrated(otherChunk) {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.canBeIntegrated"
);
return chunkGraph.canChunksBeIntegrated(this, otherChunk);
}
isEmpty() {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(this, "Chunk.isEmpty");
return chunkGraph.getNumberOfChunkModules(this) === 0;
}
modulesSize() {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.modulesSize"
);
return chunkGraph.getChunkModulesSize(this);
}
size(options) {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(this, "Chunk.size");
return chunkGraph.getChunkSize(this, options);
}
integratedSize(otherChunk, options) {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.integratedSize"
);
return chunkGraph.getIntegratedChunksSize(this, otherChunk, options);
}
getChunkModuleMaps(filterFn) {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.getChunkModuleMaps"
);
return chunkGraph.getChunkModuleMaps(
chunkGraph._moduleGraph,
this,
filterFn
);
}
hasModuleInGraph(filterFn, filterChunkFn) {
const chunkGraph = ChunkGraph.getChunkGraphForChunk(
this,
"Chunk.hasModuleInGraph"
);
return chunkGraph.hasModuleInGraph(this, filterFn, filterChunkFn);
}
// BACKWARD-COMPAT END
/**
* @returns {boolean} whether or not the Chunk will have a runtime
*/

View File

@ -5,6 +5,7 @@
"use strict";
const util = require("util");
const SortableSet = require("./util/SortableSet");
const { compareModulesById } = require("./util/comparators");
@ -86,11 +87,16 @@ class ChunkGraphChunk {
}
class ChunkGraph {
constructor() {
/**
* @param {ModuleGraph} moduleGraph the module graph
*/
constructor(moduleGraph) {
/** @private @type {WeakMap<Module, ChunkGraphModule>} */
this._modules = new WeakMap();
/** @private @type {WeakMap<Chunk, ChunkGraphChunk>} */
this._chunks = new WeakMap();
/** @private @type {ModuleGraph} */
this._moduleGraph = moduleGraph;
}
/**
@ -669,6 +675,100 @@ class ChunkGraph {
const cgc = this._getChunkGraphChunk(chunk);
return cgc.entryModules;
}
// TODO remove in webpack 6
/**
* @param {Module} module the module
* @param {string} deprecateMessage message for the deprecation message
* @returns {ChunkGraph} the chunk graph
*/
static getChunkGraphForModule(module, deprecateMessage) {
const fn = deprecateGetChunkGraphForModuleMap.get(deprecateMessage);
if (fn) return fn(module);
const newFn = util.deprecate(
/**
* @param {Module} module the module
* @returns {ChunkGraph} the chunk graph
*/
module => {
const chunkGraph = chunkGraphForModuleMap.get(module);
if (!chunkGraph)
throw new Error(
deprecateMessage +
": There was no ChunkGraph assigned to the Module for backward-compat (Use the new API)"
);
return chunkGraph;
},
deprecateMessage + ": Use new ChunkGraph API"
);
deprecateGetChunkGraphForModuleMap.set(deprecateMessage, newFn);
return newFn(module);
}
// TODO remove in webpack 6
/**
* @param {Module} module the module
* @param {ChunkGraph} chunkGraph the chunk graph
* @returns {void}
*/
static setChunkGraphForModule(module, chunkGraph) {
chunkGraphForModuleMap.set(module, chunkGraph);
}
// TODO remove in webpack 6
/**
* @param {Chunk} chunk the chunk
* @param {string} deprecateMessage message for the deprecation message
* @returns {ChunkGraph} the chunk graph
*/
static getChunkGraphForChunk(chunk, deprecateMessage) {
const fn = deprecateGetChunkGraphForChunkMap.get(deprecateMessage);
if (fn) return fn(chunk);
const newFn = util.deprecate(
/**
* @param {Chunk} chunk the chunk
* @returns {ChunkGraph} the chunk graph
*/
chunk => {
const chunkGraph = chunkGraphForChunkMap.get(chunk);
if (!chunkGraph)
throw new Error(
deprecateMessage +
"There was no ChunkGraph assigned to the Chunk for backward-compat (Use the new API)"
);
return chunkGraph;
},
deprecateMessage + ": Use new ChunkGraph API"
);
deprecateGetChunkGraphForChunkMap.set(deprecateMessage, newFn);
return newFn(chunk);
}
// TODO remove in webpack 6
/**
* @param {Chunk} chunk the chunk
* @param {ChunkGraph} chunkGraph the chunk graph
* @returns {void}
*/
static setChunkGraphForChunk(chunk, chunkGraph) {
chunkGraphForChunkMap.set(chunk, chunkGraph);
}
}
// TODO remove in webpack 6
/** @type {WeakMap<Module, ChunkGraph>} */
const chunkGraphForModuleMap = new WeakMap();
// TODO remove in webpack 6
/** @type {WeakMap<Chunk, ChunkGraph>} */
const chunkGraphForChunkMap = new WeakMap();
// TODO remove in webpack 6
/** @type {Map<string, (module: Module) => ChunkGraph>} */
const deprecateGetChunkGraphForModuleMap = new Map();
// TODO remove in webpack 6
/** @type {Map<string, (chunk: Chunk) => ChunkGraph>} */
const deprecateGetChunkGraphForChunkMap = new Map();
module.exports = ChunkGraph;

View File

@ -1064,9 +1064,13 @@ class Compilation {
* @returns {void}
*/
seal(callback) {
const chunkGraph = new ChunkGraph();
const chunkGraph = new ChunkGraph(this.moduleGraph);
this.chunkGraph = chunkGraph;
for (const module of this.modules) {
ChunkGraph.setChunkGraphForModule(module, chunkGraph);
}
this.hooks.seal.call();
while (this.hooks.optimizeDependencies.call(this.modules)) {
@ -1295,6 +1299,7 @@ class Compilation {
}
const chunk = new Chunk(name);
this.chunks.push(chunk);
ChunkGraph.setChunkGraphForChunk(chunk, this.chunkGraph);
if (name) {
this.namedChunks.set(name, chunk);
}

View File

@ -5,17 +5,18 @@
"use strict";
const ChunkGraph = require("./ChunkGraph");
const DependenciesBlock = require("./DependenciesBlock");
const ModuleGraph = require("./ModuleGraph");
const Template = require("./Template");
const { compareChunksById } = require("./util/comparators");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./ChunkGroup")} ChunkGroup */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./ModuleGraph")} ModuleGraph */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("./WebpackError")} WebpackError */
@ -115,14 +116,126 @@ class Module extends DependenciesBlock {
this.useSourceMap = false;
}
// TODO remove in webpack 6
// BACKWARD-COMPAT START
get index() {
throw new Error();
return ModuleGraph.getModuleGraphForModule(
this,
"Module.index"
).getPreOrderIndex(this);
}
set index(value) {
ModuleGraph.getModuleGraphForModule(this, "Module.index").setPreOrderIndex(
this,
value
);
}
get index2() {
throw new Error();
return ModuleGraph.getModuleGraphForModule(
this,
"Module.index2"
).getPostOrderIndex(this);
}
set index2(value) {
ModuleGraph.getModuleGraphForModule(
this,
"Module.index2"
).setPostOrderIndex(this, value);
}
get issuer() {
return ModuleGraph.getModuleGraphForModule(this, "Module.issuer").getIssuer(
this
);
}
set issuer(value) {
ModuleGraph.getModuleGraphForModule(this, "Module.issuer").setIssuer(
this,
value
);
}
get usedExports() {
return ModuleGraph.getModuleGraphForModule(
this,
"Module.usedExports"
).getUsedExports(this);
}
set usedExports(value) {
ModuleGraph.getModuleGraphForModule(
this,
"Module.usedExports"
).setUsedExports(this, value);
}
get optimizationBailout() {
return ModuleGraph.getModuleGraphForModule(
this,
"Module.optimizationBailout"
).getOptimizationBailout(this);
}
get optional() {
return this.isOptional(
ModuleGraph.getModuleGraphForModule(this, "Module.optional")
);
}
addChunk(chunk) {
return ChunkGraph.getChunkGraphForModule(
this,
"Module.addChunk"
).connectChunkAndModule(chunk, this);
}
removeChunk(chunk) {
return ChunkGraph.getChunkGraphForModule(
this,
"Module.removeChunk"
).disconnectChunkAndModule(chunk, this);
}
isInChunk(chunk) {
return ChunkGraph.getChunkGraphForModule(
this,
"Module.isInChunk"
).isModuleInChunk(this, chunk);
}
isEntryModule() {
return ChunkGraph.getChunkGraphForModule(
this,
"Module.isEntryModule"
).isEntryModule(this);
}
getChunks() {
return ChunkGraph.getChunkGraphForModule(
this,
"Module.getChunks"
).getModuleChunks(this);
}
getNumberOfChunks() {
return ChunkGraph.getChunkGraphForModule(
this,
"Module.getNumberOfChunks"
).getNumberOfModuleChunks(this);
}
get chunksIterable() {
return ChunkGraph.getChunkGraphForModule(
this,
"Module.chunksIterable"
).getOrderedModuleChunksIterable(this, compareChunksById);
}
// BACKWARD-COMPAT END
/**
* @deprecated moved to .buildInfo.exportsArgument
* @returns {string} name of the exports argument

View File

@ -5,6 +5,7 @@
"use strict";
const util = require("util");
const ModuleGraphConnection = require("./ModuleGraphConnection");
/** @typedef {import("./DependenciesBlock")} DependenciesBlock */
@ -428,7 +429,54 @@ class ModuleGraph {
}
return meta;
}
// TODO remove in webpack 6
/**
* @param {Module} module the module
* @param {string} deprecateMessage message for the deprecation message
* @returns {ModuleGraph} the module graph
*/
static getModuleGraphForModule(module, deprecateMessage) {
const fn = deprecateMap.get(deprecateMessage);
if (fn) return fn(module);
const newFn = util.deprecate(
/**
* @param {Module} module the module
* @returns {ModuleGraph} the module graph
*/
module => {
const moduleGraph = moduleGraphForModuleMap.get(module);
if (!moduleGraph)
throw new Error(
deprecateMessage +
"There was no ModuleGraph assigned to the Module for backward-compat (Use the new API)"
);
return moduleGraph;
},
deprecateMessage + ": Use new ModuleGraph API"
);
deprecateMap.set(deprecateMessage, newFn);
return newFn(module);
}
// TODO remove in webpack 6
/**
* @param {Module} module the module
* @param {ModuleGraph} moduleGraph the module graph
* @returns {void}
*/
static setModuleGraphForModule(module, moduleGraph) {
moduleGraphForModuleMap.set(module, moduleGraph);
}
}
// TODO remove in webpack 6
/** @type {WeakMap<Module, ModuleGraph>} */
const moduleGraphForModuleMap = new WeakMap();
// TODO remove in webpack 6
/** @type {Map<string, (module: Module) => ModuleGraph>} */
const deprecateMap = new Map();
module.exports = ModuleGraph;
module.exports.ModuleGraphConnection = ModuleGraphConnection;

View File

@ -5,6 +5,8 @@
"use strict";
const ChunkGraph = require("../ChunkGraph");
const ModuleGraph = require("../ModuleGraph");
const { STAGE_DEFAULT } = require("../OptimizationStages");
const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency");
const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
@ -331,6 +333,8 @@ class ModuleConcatenationPlugin {
modules,
compilation
);
ChunkGraph.setChunkGraphForModule(newModule, chunkGraph);
ModuleGraph.setModuleGraphForModule(newModule, moduleGraph);
for (const warning of concatConfiguration.getWarningsSorted()) {
moduleGraph
.getOptimizationBailout(newModule)