allow multiple entryModules per chunk

allow to specify ChunkGroup to depend on
move entry modules into ChunkGraph
This commit is contained in:
Tobias Koppers 2018-08-14 16:40:37 +02:00
parent 655d57f2d7
commit 6d5310fbd6
51 changed files with 827 additions and 903 deletions

View File

@ -66,8 +66,6 @@ class Chunk {
this.name = name;
/** @type {boolean} */
this.preventIntegration = false;
/** @type {Module=} */
this.entryModule = undefined;
/** @type {string?} */
this.filenameTemplate = undefined;
/** @private @type {SortableSet<ChunkGroup>} */
@ -125,13 +123,6 @@ class Chunk {
return true;
}
/**
* @returns {boolean} if this chunk contains the entry module
*/
hasEntryModule() {
return !!this.entryModule;
}
/**
* @param {ChunkGroup} chunkGroup the chunkGroup the chunk is being added
* @returns {boolean} returns true if chunk is not apart of chunkGroup and is added successfully
@ -168,7 +159,7 @@ class Chunk {
}
/**
* @returns {SortableSet<ChunkGroup>} the chunkGroups that said chunk is referenced in
* @returns {Iterable<ChunkGroup>} the chunkGroups that said chunk is referenced in
*/
get groupsIterable() {
return this._groups;
@ -209,40 +200,14 @@ class Chunk {
)) {
hash.update(m.hash);
}
}
canBeIntegrated(otherChunk) {
const isAvailable = (a, b) => {
const queue = new Set(b.groupsIterable);
for (const chunkGroup of queue) {
if (a.isInGroup(chunkGroup)) continue;
if (chunkGroup.isInitial()) return false;
for (const parent of chunkGroup.parentsIterable) {
queue.add(parent);
}
}
return true;
};
if (this.preventIntegration || otherChunk.preventIntegration) {
return false;
const entryModules = chunkGraph.getChunkEntryModulesWithChunkGroupIterable(
this
);
for (const [m, chunkGroup] of entryModules) {
hash.update("entry");
hash.update(m.hash);
hash.update(chunkGroup.id);
}
if (this.hasRuntime() !== otherChunk.hasRuntime()) {
if (this.hasRuntime()) {
return isAvailable(this, otherChunk);
} else if (otherChunk.hasRuntime()) {
return isAvailable(otherChunk, this);
} else {
return false;
}
}
if (this.hasEntryModule() || otherChunk.hasEntryModule()) {
return false;
}
return true;
}
/**
@ -284,7 +249,7 @@ class Chunk {
*/
/**
* @param {boolean} realHash should the full hash or the rendered hash be used
* @param {boolean=} realHash should the full hash or the rendered hash be used
* @returns {ChunkMaps} the chunk map information
*/
getChunkMaps(realHash) {

View File

@ -70,6 +70,8 @@ class ChunkGraphModule {
constructor() {
/** @type {SortableSet<Chunk>} */
this.chunks = new SortableSet();
/** @type {Set<Chunk>} */
this.entryInChunks = new Set();
}
}
@ -77,6 +79,8 @@ class ChunkGraphChunk {
constructor() {
/** @type {SortableSet<Module>} */
this.modules = new SortableSet();
/** @type {Map<Module, ChunkGroup>} */
this.entryModules = new Map();
}
}
@ -177,14 +181,30 @@ class ChunkGraph {
replaceModule(oldModule, newModule) {
const oldCgm = this._getChunkGraphModule(oldModule);
const newCgm = this._getChunkGraphModule(newModule);
const chunks = this.getModuleChunks(oldModule);
for (const chunk of chunks) {
for (const chunk of oldCgm.chunks) {
const cgc = this._getChunkGraphChunk(chunk);
cgc.modules.delete(oldModule);
cgc.modules.add(newModule);
oldCgm.chunks.delete(chunk);
newCgm.chunks.add(chunk);
}
oldCgm.chunks.clear();
for (const chunk of oldCgm.entryInChunks) {
const cgc = this._getChunkGraphChunk(chunk);
const old = cgc.entryModules.get(oldModule);
const newEntryModules = new Map();
for (const [m, cg] of cgc.entryModules) {
if (m === oldModule) {
newEntryModules.set(newModule, old);
} else {
newEntryModules.set(m, cg);
}
}
cgc.entryModules = newEntryModules;
newCgm.entryInChunks.add(chunk);
}
oldCgm.entryInChunks.clear();
}
/**
@ -215,10 +235,7 @@ class ChunkGraph {
*/
isEntryModule(module) {
const cgm = this._getChunkGraphModule(module);
for (const chunk of cgm.chunks) {
if (chunk.entryModule === module) return true;
}
return false;
return cgm.entryInChunks.size > 0;
}
/**
@ -501,7 +518,45 @@ class ChunkGraph {
* @returns {boolean} true, if chunks could be integrated
*/
canChunksBeIntegrated(chunkA, chunkB) {
return chunkA.canBeIntegrated(chunkB);
/**
* @param {Chunk} a chunk
* @param {Chunk} b chunk
* @returns {boolean} true, if a is always a parent of b
*/
const isAvailable = (a, b) => {
const queue = new Set(b.groupsIterable);
for (const chunkGroup of queue) {
if (a.isInGroup(chunkGroup)) continue;
if (chunkGroup.isInitial()) return false;
for (const parent of chunkGroup.parentsIterable) {
queue.add(parent);
}
}
return true;
};
if (chunkA.preventIntegration || chunkB.preventIntegration) {
return false;
}
if (chunkA.hasRuntime() !== chunkB.hasRuntime()) {
if (chunkA.hasRuntime()) {
return isAvailable(chunkA, chunkB);
} else if (chunkB.hasRuntime()) {
return isAvailable(chunkB, chunkA);
} else {
return false;
}
}
if (
this.getNumberOfEntryModules(chunkA) > 0 ||
this.getNumberOfEntryModules(chunkB) > 0
) {
return false;
}
return true;
}
/**
@ -532,6 +587,84 @@ class ChunkGraph {
}
}
}
/**
* @param {Module} module the checked module
* @param {Chunk} chunk the checked chunk
* @returns {boolean} true, if the chunk contains the module as entry
*/
isEntryModuleInChunk(module, chunk) {
const cgc = this._getChunkGraphChunk(chunk);
return cgc.entryModules.has(module);
}
/**
* @param {Chunk} chunk the new chunk
* @param {Module} module the entry module
* @param {ChunkGroup=} chunkGroup the chunk group which must be loaded before the module is executed
* @returns {void}
*/
connectChunkAndEntryModule(chunk, module, chunkGroup) {
const cgm = this._getChunkGraphModule(module);
const cgc = this._getChunkGraphChunk(chunk);
cgm.entryInChunks.add(chunk);
cgc.entryModules.set(module, chunkGroup);
}
/**
* @param {Module} module the entry module, it will no longer be entry
* @returns {void}
*/
disconnectEntryModule(module) {
const cgm = this._getChunkGraphModule(module);
for (const chunk of cgm.entryInChunks) {
const cgc = this._getChunkGraphChunk(chunk);
cgc.entryModules.delete(module);
}
cgm.entryInChunks.clear();
}
/**
* @param {Chunk} chunk the chunk, for which all entries will be removed
* @returns {void}
*/
disconnectEntries(chunk) {
const cgc = this._getChunkGraphChunk(chunk);
for (const module of cgc.entryModules.keys()) {
const cgm = this._getChunkGraphModule(module);
cgm.entryInChunks.delete(chunk);
}
cgc.entryModules.clear();
}
/**
* @param {Chunk} chunk the chunk
* @returns {number} the amount of entry modules in chunk
*/
getNumberOfEntryModules(chunk) {
const cgc = this._getChunkGraphChunk(chunk);
return cgc.entryModules.size;
}
/**
* @param {Chunk} chunk the chunk
* @returns {Iterable<Module>} iterable of modules (do not modify)
*/
getChunkEntryModulesIterable(chunk) {
const cgc = this._getChunkGraphChunk(chunk);
return cgc.entryModules.keys();
}
/** @typedef {[Module, ChunkGroup | undefined]} EntryModuleWithChunkGroup */
/**
* @param {Chunk} chunk the chunk
* @returns {Iterable<EntryModuleWithChunkGroup>} iterable of modules (do not modify)
*/
getChunkEntryModulesWithChunkGroupIterable(chunk) {
const cgc = this._getChunkGraphChunk(chunk);
return cgc.entryModules;
}
}
module.exports = ChunkGraph;

View File

@ -348,10 +348,9 @@ class ChunkGroup {
}
/**
* @param {string=} reason reason for removing ChunkGroup
* @returns {void}
*/
remove(reason) {
remove() {
// cleanup parents
for (const parentChunkGroup of this._parents) {
// remove this chunk from its parents

View File

@ -14,16 +14,8 @@ const { SyncWaterfallHook, SyncHook } = require("tapable");
/** @typedef {import("./DependencyTemplates")} DependencyTemplates} */
/** @typedef {import("webpack-sources").Source} Source} */
/** @typedef {import("./ModuleTemplate").RenderContext} RenderContext} */
/**
* @typedef {Object} RenderManifestOptions
* @property {Chunk} chunk the chunk used to render
* @property {string} hash
* @property {string} fullHash
* @property {TODO} outputOptions
* @property {{javascript: ModuleTemplate, webassembly: ModuleTemplate}} moduleTemplates
* @property {DependencyTemplates} dependencyTemplates
*/
/** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions} */
/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry} */
module.exports = class ChunkTemplate {
constructor(outputOptions) {
@ -52,7 +44,7 @@ module.exports = class ChunkTemplate {
/**
*
* @param {RenderManifestOptions} options render manifest options
* @returns {TODO[]} returns render manifest
* @returns {RenderManifestEntry[]} returns render manifest
*/
getRenderManifest(options) {
const result = [];

View File

@ -37,7 +37,6 @@ const ModuleTemplate = require("./ModuleTemplate");
const RuntimeTemplate = require("./RuntimeTemplate");
const Stats = require("./Stats");
const compareLocations = require("./compareLocations");
const ModuleDependency = require("./dependencies/ModuleDependency");
const Queue = require("./util/Queue");
const Semaphore = require("./util/Semaphore");
const SortableSet = require("./util/SortableSet");
@ -54,8 +53,7 @@ const createHash = require("./util/createHash");
/** @typedef {import("./WebpackError")} WebpackError */
/** @typedef {import("./dependencies/DependencyReference")} DependencyReference */
/** @typedef {import("./dependencies/DllEntryDependency")} DllEntryDependency */
/** @typedef {import("./dependencies/MultiEntryDependency")} MultiEntryDependency */
/** @typedef {import("./dependencies/SingleEntryDependency")} SingleEntryDependency */
/** @typedef {import("./dependencies/EntryDependency")} EntryDependency */
/** @typedef {import("./util/createHash").Hash} Hash */
// TODO use @callback
@ -383,6 +381,7 @@ class Compilation {
this.outputOptions,
this.requestShortener
);
/** @type {{javascript: ModuleTemplate, webassembly: ModuleTemplate}} */
this.moduleTemplates = {
javascript: new ModuleTemplate(this.runtimeTemplate, "javascript"),
webassembly: new ModuleTemplate(this.runtimeTemplate, "webassembly")
@ -393,10 +392,9 @@ class Compilation {
this.semaphore = new Semaphore(options.parallelism || 100);
this.entries = [];
/** @private @type {{name: string, request: string, module: Module}[]} */
this._preparedEntrypoints = [];
/** @private @type {Map<string, Entrypoint>} */
/** @type {Map<string, EntryDependency[]>} */
this.entryDependencies = new Map();
/** @type {Map<string, Entrypoint>} */
this.entrypoints = new Map();
/** @type {Chunk[]} */
this.chunks = [];
@ -931,6 +929,11 @@ class Compilation {
currentProfile.factory = afterFactory - start;
}
if (!module) {
this.semaphore.release();
return process.nextTick(callback);
}
const addModuleResult = this.addModule(module);
module = addModuleResult.module;
@ -987,53 +990,20 @@ class Compilation {
/**
*
* @param {string} context context path for entry
* @param {Dependency} entry entry dependency being created
* @param {EntryDependency} entry entry dependency being created
* @param {string} name name of entry
* @param {ModuleCallback} callback callback function
* @returns {void} returns
*/
addEntry(context, entry, name, callback) {
const slot = {
name: name,
// TODO webpack 5 remove `request`
request: null,
module: null
};
if (entry instanceof ModuleDependency) {
slot.request = entry.request;
let entriesArray = this.entryDependencies.get(name);
if (entriesArray === undefined) {
entriesArray = [];
this.entryDependencies.set(name, entriesArray);
}
entriesArray.push(entry);
// TODO webpack 5: merge modules instead when multiple entry modules are supported
const idx = this._preparedEntrypoints.findIndex(slot => slot.name === name);
if (idx >= 0) {
// Overwrite existing entrypoint
this._preparedEntrypoints[idx] = slot;
} else {
this._preparedEntrypoints.push(slot);
}
this._addModuleChain(
context,
entry,
module => {
this.entries.push(module);
},
(err, module) => {
if (err) {
return callback(err);
}
if (module) {
slot.module = module;
} else {
const idx = this._preparedEntrypoints.indexOf(slot);
if (idx >= 0) {
this._preparedEntrypoints.splice(idx, 1);
}
}
return callback(null, module);
}
);
this._addModuleChain(context, entry, module => {}, callback);
}
/**
@ -1138,24 +1108,26 @@ class Compilation {
this.hooks.afterOptimizeDependencies.call(this.modules);
this.hooks.beforeChunks.call();
for (const preparedEntrypoint of this._preparedEntrypoints) {
const module = preparedEntrypoint.module;
const name = preparedEntrypoint.name;
for (const [name, dependencies] of this.entryDependencies) {
const chunk = this.addChunk(name);
chunk.name = name;
const entrypoint = new Entrypoint(name);
entrypoint.setRuntimeChunk(chunk);
entrypoint.addOrigin(null, { name }, preparedEntrypoint.request);
this.namedChunkGroups.set(name, entrypoint);
this.entrypoints.set(name, entrypoint);
this.chunkGroups.push(entrypoint);
connectChunkGroupAndChunk(entrypoint, chunk);
chunkGraph.connectChunkAndModule(chunk, module);
chunk.entryModule = module;
chunk.name = name;
for (const dep of dependencies) {
entrypoint.addOrigin(null, { name }, dep.request);
this.assignDepth(module);
const module = this.moduleGraph.getModule(dep);
if (module) {
chunkGraph.connectChunkAndModule(chunk, module);
chunkGraph.connectChunkAndEntryModule(chunk, module, entrypoint);
this.assignDepth(module);
}
}
}
this.processDependenciesBlocksForChunkGroups(this.chunkGroups.slice());
this.sortModules(this.modules);
@ -1565,20 +1537,30 @@ class Compilation {
*/
/**
* @param {QueueItem[]} queue the queue array (will be mutated)
* @param {ChunkGroup} chunkGroup chunk group
* @returns {QueueItem} queue item
* @returns {QueueItem[]} the queue array again
*/
const chunkGroupToQueueItem = chunkGroup => ({
action: ENTER_MODULE,
block: chunkGroup.chunks[0].entryModule,
module: chunkGroup.chunks[0].entryModule,
chunk: chunkGroup.chunks[0],
chunkGroup
});
const reduceChunkGroupToQueueItem = (queue, chunkGroup) => {
for (const chunk of chunkGroup.chunks) {
for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
queue.push({
action: ENTER_MODULE,
block: module,
module,
chunk,
chunkGroup
});
}
}
return queue;
};
// Start with the provided modules/chunks
/** @type {QueueItem[]} */
let queue = inputChunkGroups.map(chunkGroupToQueueItem).reverse();
let queue = inputChunkGroups
.reduce(reduceChunkGroupToQueueItem, [])
.reverse();
/** @type {QueueItem[]} */
let queueDelayed = [];
@ -1853,7 +1835,7 @@ class Compilation {
if (idx >= 0) this.chunks.splice(idx, 1);
chunkGraph.disconnectChunk(chunk);
}
chunkGroup.remove("unconnected");
chunkGroup.remove();
}
}
}
@ -2254,7 +2236,10 @@ class Compilation {
fullHash: this.fullHash,
outputOptions,
moduleTemplates: this.moduleTemplates,
dependencyTemplates: this.dependencyTemplates
dependencyTemplates: this.dependencyTemplates,
chunkGraph: this.chunkGraph,
moduleGraph: this.moduleGraph,
runtimeTemplate: this.runtimeTemplate
}); // [{ render(), filenameTemplate, pathOptions, identifier, hash }]
for (const fileManifest of manifest) {
const cacheName = fileManifest.identifier;
@ -2364,6 +2349,8 @@ class Compilation {
}
checkConstraints() {
const chunkGraph = this.chunkGraph;
/** @type {Set<number|string>} */
const usedIds = new Set();
@ -2385,6 +2372,22 @@ class Compilation {
`checkConstraints: duplicate chunk in compilation ${chunk.debugId}`
);
}
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
if (this.modules.indexOf(module) < 0) {
throw new Error(
"checkConstraints: module in chunk but not in compilation " +
` ${chunk.debugId} ${module.debugId}`
);
}
}
for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
if (this.modules.indexOf(module) < 0) {
throw new Error(
"checkConstraints: entry module in chunk but not in compilation " +
` ${chunk.debugId} ${module.debugId}`
);
}
}
}
for (const chunkGroup of this.chunkGroups) {

View File

@ -7,7 +7,7 @@
const DllModuleFactory = require("./DllModuleFactory");
const DllEntryDependency = require("./dependencies/DllEntryDependency");
const SingleEntryDependency = require("./dependencies/SingleEntryDependency");
const EntryDependency = require("./dependencies/EntryDependency");
class DllEntryPlugin {
constructor(context, entries, name) {
@ -26,7 +26,7 @@ class DllEntryPlugin {
dllModuleFactory
);
compilation.dependencyFactories.set(
SingleEntryDependency,
EntryDependency,
normalModuleFactory
);
}
@ -36,7 +36,7 @@ class DllEntryPlugin {
this.context,
new DllEntryDependency(
this.entries.map((e, idx) => {
const dep = new SingleEntryDependency(e);
const dep = new EntryDependency(e);
dep.loc = {
name: this.name,
index: idx

View File

@ -5,11 +5,8 @@
"use strict";
const MultiEntryPlugin = require("./MultiEntryPlugin");
const MultiModuleFactory = require("./MultiModuleFactory");
const SingleEntryPlugin = require("./SingleEntryPlugin");
const MultiEntryDependency = require("./dependencies/MultiEntryDependency");
const SingleEntryDependency = require("./dependencies/SingleEntryDependency");
const EntryPlugin = require("./EntryPlugin");
const EntryDependency = require("./dependencies/EntryDependency");
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Compiler").EntryOptionValuesFunction} EntryOptionValuesFunction */
@ -32,14 +29,8 @@ class DynamicEntryPlugin {
compiler.hooks.compilation.tap(
"DynamicEntryPlugin",
(compilation, { normalModuleFactory }) => {
const multiModuleFactory = new MultiModuleFactory();
compilation.dependencyFactories.set(
MultiEntryDependency,
multiModuleFactory
);
compilation.dependencyFactories.set(
SingleEntryDependency,
EntryDependency,
normalModuleFactory
);
}
@ -51,29 +42,35 @@ class DynamicEntryPlugin {
/**
* @param {string|string[]} entry entry value or array of entry values
* @param {string} name name of entry
* @returns {Promise<any>} returns the promise resolving the Compilation#addEntry function
* @returns {Promise<void>} returns the promise resolving the Compilation#addEntry function
*/
const addEntry = (entry, name) => {
const dep = DynamicEntryPlugin.createDependency(entry, name);
const deps = DynamicEntryPlugin.createDependencies(entry, name);
return new Promise((resolve, reject) => {
compilation.addEntry(this.context, dep, name, err => {
if (err) return reject(err);
resolve();
});
for (const dep of deps) {
compilation.addEntry(this.context, dep, name, err => {
if (err) return reject(err);
resolve();
});
}
});
};
Promise.resolve(this.entry()).then(entry => {
if (typeof entry === "string" || Array.isArray(entry)) {
addEntry(entry, "main").then(() => callback(), callback);
addEntry(entry, "main").then(() => {
callback();
}, callback);
} else if (typeof entry === "object") {
Promise.all(
Object.keys(entry).map(name => {
return addEntry(entry[name], name);
})
).then(() => callback(), callback);
).then(() => {
callback();
}, callback);
}
});
}, callback);
}
);
}
@ -81,14 +78,11 @@ class DynamicEntryPlugin {
/**
* @param {string|string[]} entry entry value or array of entry paths
* @param {string} name name of entry
* @returns {SingleEntryDependency|MultiEntryDependency} returns dep
* @returns {EntryDependency[]} dependencies
*/
static createDependency(entry, name) {
if (Array.isArray(entry)) {
return MultiEntryPlugin.createDependency(entry, name);
} else {
return SingleEntryPlugin.createDependency(entry, name);
}
static createDependencies(entry, name) {
const entryArray = Array.isArray(entry) ? entry : [entry];
return entryArray.map(entry => EntryPlugin.createDependency(entry, name));
}
}

View File

@ -6,24 +6,10 @@
"use strict";
const DynamicEntryPlugin = require("./DynamicEntryPlugin");
const MultiEntryPlugin = require("./MultiEntryPlugin");
const SingleEntryPlugin = require("./SingleEntryPlugin");
const EntryPlugin = require("./EntryPlugin");
/** @typedef {import("./Compiler")} Compiler */
/**
* @param {string} context context path
* @param {string | string[]} item entry array or single path
* @param {string} name entry key name
* @returns {SingleEntryPlugin | MultiEntryPlugin} returns either a single or multi entry plugin
*/
const itemToPlugin = (context, item, name) => {
if (Array.isArray(item)) {
return new MultiEntryPlugin(context, item, name);
}
return new SingleEntryPlugin(context, item, name);
};
module.exports = class EntryOptionPlugin {
/**
* @param {Compiler} compiler the compiler instance one is tapping into
@ -31,11 +17,26 @@ module.exports = class EntryOptionPlugin {
*/
apply(compiler) {
compiler.hooks.entryOption.tap("EntryOptionPlugin", (context, entry) => {
/**
* @param {string | string[]} entry entry array or single path
* @param {string} name entry key name
* @returns {void}
*/
const applyEntryPlugins = (entry, name) => {
if (typeof entry === "string") {
new EntryPlugin(context, entry, name).apply(compiler);
} else if (Array.isArray(entry)) {
for (const item of entry) {
applyEntryPlugins(item, name);
}
}
};
if (typeof entry === "string" || Array.isArray(entry)) {
itemToPlugin(context, entry, "main").apply(compiler);
applyEntryPlugins(entry, "main");
} else if (typeof entry === "object") {
for (const name of Object.keys(entry)) {
itemToPlugin(context, entry[name], name).apply(compiler);
applyEntryPlugins(entry[name], name);
}
} else if (typeof entry === "function") {
new DynamicEntryPlugin(context, entry).apply(compiler);

View File

@ -5,14 +5,14 @@
"use strict";
const SingleEntryDependency = require("./dependencies/SingleEntryDependency");
const EntryDependency = require("./dependencies/EntryDependency");
/** @typedef {import("./Compiler")} Compiler */
class SingleEntryPlugin {
class EntryPlugin {
/**
* An entry plugin which will handle
* creation of the SingleEntryDependency
* creation of the EntryDependency
*
* @param {string} context context path
* @param {string} entry entry path
@ -30,36 +30,33 @@ class SingleEntryPlugin {
*/
apply(compiler) {
compiler.hooks.compilation.tap(
"SingleEntryPlugin",
"EntryPlugin",
(compilation, { normalModuleFactory }) => {
compilation.dependencyFactories.set(
SingleEntryDependency,
EntryDependency,
normalModuleFactory
);
}
);
compiler.hooks.make.tapAsync(
"SingleEntryPlugin",
(compilation, callback) => {
const { entry, name, context } = this;
compiler.hooks.make.tapAsync("EntryPlugin", (compilation, callback) => {
const { entry, name, context } = this;
const dep = SingleEntryPlugin.createDependency(entry, name);
compilation.addEntry(context, dep, name, callback);
}
);
const dep = EntryPlugin.createDependency(entry, name);
compilation.addEntry(context, dep, name, callback);
});
}
/**
* @param {string} entry entry request
* @param {string} name entry name
* @returns {SingleEntryDependency} the dependency
* @returns {EntryDependency} the dependency
*/
static createDependency(entry, name) {
const dep = new SingleEntryDependency(entry);
const dep = new EntryDependency(entry);
dep.loc = { name };
return dep;
}
}
module.exports = SingleEntryPlugin;
module.exports = EntryPlugin;

View File

@ -13,6 +13,8 @@ const NullFactory = require("./NullFactory");
const Template = require("./Template");
const ConstDependency = require("./dependencies/ConstDependency");
/** @typedef {import("./Compiler")} Compiler */
const REPLACEMENTS = {
// eslint-disable-next-line camelcase
__webpack_hash__: "__webpack_require__.h",
@ -27,6 +29,10 @@ const REPLACEMENT_TYPES = {
};
class ExtendedAPIPlugin {
/**
* @param {Compiler} compiler webpack compiler
* @returns {void}
*/
apply(compiler) {
compiler.hooks.compilation.tap(
"ExtendedAPIPlugin",
@ -40,7 +46,7 @@ class ExtendedAPIPlugin {
const mainTemplate = compilation.mainTemplate;
mainTemplate.hooks.requireExtensions.tap(
"ExtendedAPIPlugin",
(source, chunk, hash) => {
(source, { chunk, hash }) => {
const buf = [source];
buf.push("");
buf.push("// __webpack_hash__");

View File

@ -123,10 +123,11 @@ class ExternalModule extends Module {
/**
* @param {Chunk} chunk the chunk which condition should be checked
* @param {Compilation} compilation the compilation
* @returns {boolean} true, if the chunk is ok for the module
*/
chunkCondition(chunk) {
return chunk.hasEntryModule();
chunkCondition(chunk, { chunkGraph }) {
return chunkGraph.getNumberOfEntryModules(chunk) > 0;
}
/**

View File

@ -120,9 +120,13 @@ class FlagDependencyUsagePlugin {
/** @type {[Module, DependenciesBlock, UsedExports][]} */
const queue = [];
for (const preparedEntrypoint of compilation._preparedEntrypoints) {
if (preparedEntrypoint.module) {
processModule(preparedEntrypoint.module, true);
for (const [, deps] of compilation.entryDependencies) {
const lastDependency = deps[deps.length - 1];
if (lastDependency) {
const module = moduleGraph.getModule(lastDependency);
if (module) {
processModule(module, true);
}
}
}

View File

@ -380,7 +380,7 @@ module.exports = class HotModuleReplacementPlugin {
mainTemplate.hooks.bootstrap.tap(
"HotModuleReplacementPlugin",
(source, chunk, hash) => {
(source, moduleTemplate, { chunk, hash }) => {
source = mainTemplate.hooks.hotBootstrap.call(source, chunk, hash);
return Template.asString([
source,
@ -417,7 +417,7 @@ module.exports = class HotModuleReplacementPlugin {
mainTemplate.hooks.moduleObj.tap(
"HotModuleReplacementPlugin",
(source, chunk, hash, varModuleId) => {
(source, varModuleId) => {
return Template.asString([
`${source},`,
`hot: hotCreateModule(${varModuleId}),`,

View File

@ -101,12 +101,14 @@ class JavascriptModulesPlugin {
result.push({
render: () =>
compilation.mainTemplate.render(
compilation.mainTemplate.render(moduleTemplates.javascript, {
hash,
chunk,
moduleTemplates.javascript,
dependencyTemplates
),
dependencyTemplates,
runtimeTemplate: options.runtimeTemplate,
moduleGraph: options.moduleGraph,
chunkGraph: options.chunkGraph
}),
filenameTemplate,
pathOptions: {
noChunkHash: !useChunkHash,
@ -121,15 +123,9 @@ class JavascriptModulesPlugin {
);
compilation.mainTemplate.hooks.modules.tap(
"JavascriptModulesPlugin",
(source, chunk, hash, moduleTemplate, dependencyTemplates) => {
(source, moduleTemplate, renderContext) => {
return Template.renderChunkModules(
{
chunk,
dependencyTemplates,
runtimeTemplate: compilation.runtimeTemplate,
moduleGraph: compilation.moduleGraph,
chunkGraph: compilation.chunkGraph
},
renderContext,
m => typeof m.source === "function",
moduleTemplate,
"/******/ "
@ -233,7 +229,7 @@ class JavascriptModulesPlugin {
renderContext
);
const chunk = renderContext.chunk;
if (chunk.hasEntryModule()) {
if (renderContext.chunkGraph.getNumberOfEntryModules(chunk) > 0) {
source = chunkTemplate.hooks.renderWithEntry.call(source, chunk);
}
chunk.rendered = true;

View File

@ -7,7 +7,7 @@
const asyncLib = require("neo-async");
const path = require("path");
const SingleEntryDependency = require("./dependencies/SingleEntryDependency");
const EntryDependency = require("./dependencies/EntryDependency");
const { compareModulesById } = require("./util/comparators");
class LibManifestPlugin {
@ -50,7 +50,7 @@ class LibManifestPlugin {
this.options.entryOnly &&
!compilation.moduleGraph
.getIncomingConnections(module)
.some(c => c.dependency instanceof SingleEntryDependency)
.some(c => c.dependency instanceof EntryDependency)
) {
return;
}

View File

@ -21,15 +21,21 @@ const Template = require("./Template");
/** @typedef {import("./Module")} Module} */
/** @typedef {import("./util/createHash").Hash} Hash} */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates} */
/** @typedef {import("./ModuleTemplate").RenderContext} RenderContext} */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate} */
/** @typedef {import("./ModuleGraph")} ModuleGraph} */
/** @typedef {import("./ChunkGraph")} ChunkGraph} */
/** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions} */
/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry} */
/**
* @typedef {Object} RenderManifestOptions
* @property {Chunk} chunk the chunk used to render
* @property {string} hash
* @property {string} fullHash
* @property {TODO} outputOptions
* @property {{javascript: ModuleTemplate, webassembly: ModuleTemplate}} moduleTemplates
* @property {DependencyTemplates} dependencyTemplates
* @typedef {Object} MainRenderContext
* @property {Chunk} chunk the chunk
* @property {DependencyTemplates} dependencyTemplates the dependency templates
* @property {RuntimeTemplate} runtimeTemplate the runtime template
* @property {ModuleGraph} moduleGraph the module graph
* @property {ChunkGraph} chunkGraph the chunk graph
* @property {string} hash hash to be used for render call
*/
// require function shortcuts:
@ -60,45 +66,44 @@ module.exports = class MainTemplate {
this.hooks = Object.freeze({
/** @type {SyncWaterfallHook<TODO[], RenderManifestOptions>} */
renderManifest: new SyncWaterfallHook(["result", "options"]),
/** @type {SyncWaterfallHook<Source, ModuleTemplate, MainRenderContext>} */
modules: new SyncWaterfallHook([
"modules",
"chunk",
"hash",
"source",
"moduleTemplate",
"dependencyTemplates"
"renderContext"
]),
/** @type {SyncWaterfallHook<string, string, MainRenderContext>} */
moduleObj: new SyncWaterfallHook([
"source",
"chunk",
"hash",
"moduleIdExpression"
"moduleIdExpression",
"renderContext"
]),
/** @type {SyncWaterfallHook<string, string, MainRenderContext>} */
requireEnsure: new SyncWaterfallHook([
"source",
"chunk",
"hash",
"chunkIdExpression"
"chunkIdExpression",
"renderContext"
]),
/** @type {SyncWaterfallHook<string, ModuleTemplate, MainRenderContext>} */
bootstrap: new SyncWaterfallHook([
"source",
"chunk",
"hash",
"moduleTemplate",
"dependencyTemplates"
"renderContext"
]),
localVars: new SyncWaterfallHook(["source", "chunk", "hash"]),
require: new SyncWaterfallHook(["source", "chunk", "hash"]),
requireExtensions: new SyncWaterfallHook(["source", "chunk", "hash"]),
/** @type {SyncWaterfallHook<string, MainRenderContext>} */
require: new SyncWaterfallHook(["source", "renderContext"]),
/** @type {SyncWaterfallHook<string, MainRenderContext>} */
requireExtensions: new SyncWaterfallHook(["source", "renderContext"]),
/** @type {SyncWaterfallHook<string, Chunk, string>} */
beforeStartup: new SyncWaterfallHook(["source", "chunk", "hash"]),
/** @type {SyncWaterfallHook<string, Chunk, string>} */
startup: new SyncWaterfallHook(["source", "chunk", "hash"]),
/** @type {SyncWaterfallHook<string, MainRenderContext>} */
startup: new SyncWaterfallHook(["source", "renderContext"]),
/** @type {SyncWaterfallHook<Source, ModuleTemplate, MainRenderContext>} */
render: new SyncWaterfallHook([
"source",
"chunk",
"hash",
"moduleTemplate",
"dependencyTemplates"
"renderContext"
]),
renderWithEntry: new SyncWaterfallHook(["source", "chunk", "hash"]),
moduleRequire: new SyncWaterfallHook([
@ -107,12 +112,11 @@ module.exports = class MainTemplate {
"hash",
"moduleIdExpression"
]),
/** @type {SyncWaterfallHook<string, {moduleId: string, module: string}, MainRenderContext>} */
addModule: new SyncWaterfallHook([
"source",
"chunk",
"hash",
"moduleIdExpression",
"moduleExpression"
"expressions",
"renderContext"
]),
currentHash: new SyncWaterfallHook(["source", "requestedLength"]),
assetPath: new SyncWaterfallHook(["path", "options"]),
@ -125,24 +129,33 @@ module.exports = class MainTemplate {
// It's weird here
hotBootstrap: new SyncWaterfallHook(["source", "chunk", "hash"])
});
this.hooks.startup.tap("MainTemplate", (source, chunk, hash) => {
/** @type {string[]} */
const buf = [];
if (chunk.entryModule) {
buf.push("// Load entry module and return exports");
buf.push(
`return ${this.renderRequireFunctionForModule(
hash,
chunk,
JSON.stringify(chunk.entryModule.id)
)}(${this.requireFn}.s = ${JSON.stringify(chunk.entryModule.id)});`
);
this.hooks.startup.tap(
"MainTemplate",
(source, { chunk, hash, chunkGraph }) => {
/** @type {string[]} */
const buf = [];
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
buf.push("// Load entry module and return exports");
let i = chunkGraph.getNumberOfEntryModules(chunk);
for (const entryModule of chunkGraph.getChunkEntryModulesIterable(
chunk
)) {
const mayReturn = --i === 0 ? "return " : "";
buf.push(
`${mayReturn}${this.renderRequireFunctionForModule(
hash,
chunk,
JSON.stringify(entryModule.id)
)}(${this.requireFn}.s = ${JSON.stringify(entryModule.id)});`
);
}
}
return Template.asString(buf);
}
return Template.asString(buf);
});
);
this.hooks.render.tap(
"MainTemplate",
(bootstrapSource, chunk, hash, moduleTemplate, dependencyTemplates) => {
(bootstrapSource, moduleTemplate, renderContext) => {
const source = new ConcatSource();
source.add("/******/ (function(modules) { // webpackBootstrap\n");
source.add(new PrefixSource("/******/", bootstrapSource));
@ -154,10 +167,8 @@ module.exports = class MainTemplate {
source.add(
this.hooks.modules.call(
new RawSource(""),
chunk,
hash,
moduleTemplate,
dependencyTemplates
renderContext
)
);
source.add(")");
@ -171,7 +182,8 @@ module.exports = class MainTemplate {
"var installedModules = {};"
]);
});
this.hooks.require.tap("MainTemplate", (source, chunk, hash) => {
this.hooks.require.tap("MainTemplate", (source, renderContext) => {
const { chunk, hash } = renderContext;
return Template.asString([
source,
"// Check if module is in cache",
@ -180,7 +192,9 @@ module.exports = class MainTemplate {
"}",
"// Create a new module (and put it into the cache)",
"var module = installedModules[moduleId] = {",
Template.indent(this.hooks.moduleObj.call("", chunk, hash, "moduleId")),
Template.indent(
this.hooks.moduleObj.call("", "moduleId", renderContext)
),
"};",
"",
Template.asString(
@ -220,124 +234,125 @@ module.exports = class MainTemplate {
"return module.exports;"
]);
});
this.hooks.moduleObj.tap(
this.hooks.moduleObj.tap("MainTemplate", () => {
return Template.asString(["i: moduleId,", "l: false,", "exports: {}"]);
});
this.hooks.requireExtensions.tap(
"MainTemplate",
(source, chunk, hash, varModuleId) => {
return Template.asString(["i: moduleId,", "l: false,", "exports: {}"]);
(source, renderContext) => {
const { chunk, hash } = renderContext;
const buf = [];
const chunkMaps = chunk.getChunkMaps();
// Check if there are non initial chunks which need to be imported using require-ensure
if (Object.keys(chunkMaps.hash).length) {
buf.push("// This file contains only the entry chunk.");
buf.push("// The chunk loading function for additional chunks");
buf.push(`${this.requireFn}.e = function requireEnsure(chunkId) {`);
buf.push(Template.indent("var promises = [];"));
buf.push(
Template.indent(
this.hooks.requireEnsure.call("", "chunkId", renderContext)
)
);
buf.push(Template.indent("return Promise.all(promises);"));
buf.push("};");
}
buf.push("");
buf.push("// expose the modules object (__webpack_modules__)");
buf.push(`${this.requireFn}.m = modules;`);
buf.push("");
buf.push("// expose the module cache");
buf.push(`${this.requireFn}.c = installedModules;`);
buf.push("");
buf.push("// define getter function for harmony exports");
buf.push(`${this.requireFn}.d = function(exports, name, getter) {`);
buf.push(
Template.indent([
`if(!${this.requireFn}.o(exports, name)) {`,
Template.indent([
"Object.defineProperty(exports, name, { enumerable: true, get: getter });"
]),
"}"
])
);
buf.push("};");
buf.push("");
buf.push("// define __esModule on exports");
buf.push(`${this.requireFn}.r = function(exports) {`);
buf.push(
Template.indent([
"if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {",
Template.indent([
"Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });"
]),
"}",
"Object.defineProperty(exports, '__esModule', { value: true });"
])
);
buf.push("};");
buf.push("");
buf.push("// create a fake namespace object");
buf.push("// mode & 1: value is a module id, require it");
buf.push("// mode & 2: merge all properties of value into the ns");
buf.push("// mode & 4: return value when already ns object");
buf.push("// mode & 8|1: behave like require");
buf.push(`${this.requireFn}.t = function(value, mode) {`);
buf.push(
Template.indent([
`if(mode & 1) value = ${this.requireFn}(value);`,
`if(mode & 8) return value;`,
"if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;",
"var ns = Object.create(null);",
`${this.requireFn}.r(ns);`,
"Object.defineProperty(ns, 'default', { enumerable: true, value: value });",
"if(mode & 2 && typeof value != 'string') for(var key in value) " +
`${this.requireFn}.d(ns, key, function(key) { ` +
"return value[key]; " +
"}.bind(null, key));",
"return ns;"
])
);
buf.push("};");
buf.push("");
buf.push(
"// getDefaultExport function for compatibility with non-harmony modules"
);
buf.push(this.requireFn + ".n = function(module) {");
buf.push(
Template.indent([
"var getter = module && module.__esModule ?",
Template.indent([
"function getDefault() { return module['default']; } :",
"function getModuleExports() { return module; };"
]),
`${this.requireFn}.d(getter, 'a', getter);`,
"return getter;"
])
);
buf.push("};");
buf.push("");
buf.push("// Object.prototype.hasOwnProperty.call");
buf.push(
`${
this.requireFn
}.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };`
);
const publicPath = this.getPublicPath({
hash: hash
});
buf.push("");
buf.push("// __webpack_public_path__");
buf.push(`${this.requireFn}.p = ${JSON.stringify(publicPath)};`);
return Template.asString(buf);
}
);
this.hooks.requireExtensions.tap("MainTemplate", (source, chunk, hash) => {
const buf = [];
const chunkMaps = chunk.getChunkMaps();
// Check if there are non initial chunks which need to be imported using require-ensure
if (Object.keys(chunkMaps.hash).length) {
buf.push("// This file contains only the entry chunk.");
buf.push("// The chunk loading function for additional chunks");
buf.push(`${this.requireFn}.e = function requireEnsure(chunkId) {`);
buf.push(Template.indent("var promises = [];"));
buf.push(
Template.indent(
this.hooks.requireEnsure.call("", chunk, hash, "chunkId")
)
);
buf.push(Template.indent("return Promise.all(promises);"));
buf.push("};");
}
buf.push("");
buf.push("// expose the modules object (__webpack_modules__)");
buf.push(`${this.requireFn}.m = modules;`);
buf.push("");
buf.push("// expose the module cache");
buf.push(`${this.requireFn}.c = installedModules;`);
buf.push("");
buf.push("// define getter function for harmony exports");
buf.push(`${this.requireFn}.d = function(exports, name, getter) {`);
buf.push(
Template.indent([
`if(!${this.requireFn}.o(exports, name)) {`,
Template.indent([
"Object.defineProperty(exports, name, { enumerable: true, get: getter });"
]),
"}"
])
);
buf.push("};");
buf.push("");
buf.push("// define __esModule on exports");
buf.push(`${this.requireFn}.r = function(exports) {`);
buf.push(
Template.indent([
"if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {",
Template.indent([
"Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });"
]),
"}",
"Object.defineProperty(exports, '__esModule', { value: true });"
])
);
buf.push("};");
buf.push("");
buf.push("// create a fake namespace object");
buf.push("// mode & 1: value is a module id, require it");
buf.push("// mode & 2: merge all properties of value into the ns");
buf.push("// mode & 4: return value when already ns object");
buf.push("// mode & 8|1: behave like require");
buf.push(`${this.requireFn}.t = function(value, mode) {`);
buf.push(
Template.indent([
`if(mode & 1) value = ${this.requireFn}(value);`,
`if(mode & 8) return value;`,
"if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;",
"var ns = Object.create(null);",
`${this.requireFn}.r(ns);`,
"Object.defineProperty(ns, 'default', { enumerable: true, value: value });",
"if(mode & 2 && typeof value != 'string') for(var key in value) " +
`${this.requireFn}.d(ns, key, function(key) { ` +
"return value[key]; " +
"}.bind(null, key));",
"return ns;"
])
);
buf.push("};");
buf.push("");
buf.push(
"// getDefaultExport function for compatibility with non-harmony modules"
);
buf.push(this.requireFn + ".n = function(module) {");
buf.push(
Template.indent([
"var getter = module && module.__esModule ?",
Template.indent([
"function getDefault() { return module['default']; } :",
"function getModuleExports() { return module; };"
]),
`${this.requireFn}.d(getter, 'a', getter);`,
"return getter;"
])
);
buf.push("};");
buf.push("");
buf.push("// Object.prototype.hasOwnProperty.call");
buf.push(
`${
this.requireFn
}.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };`
);
const publicPath = this.getPublicPath({
hash: hash
});
buf.push("");
buf.push("// __webpack_public_path__");
buf.push(`${this.requireFn}.p = ${JSON.stringify(publicPath)};`);
return Template.asString(buf);
});
this.requireFn = "__webpack_require__";
}
@ -345,7 +360,7 @@ module.exports = class MainTemplate {
/**
*
* @param {RenderManifestOptions} options render manifest options
* @returns {TODO[]} returns render manifest
* @returns {RenderManifestEntry[]} returns render manifest
*/
getRenderManifest(options) {
const result = [];
@ -356,48 +371,36 @@ module.exports = class MainTemplate {
}
/**
*
* @param {string} hash hash to be used for render call
* @param {Chunk} chunk Chunk instance
* @param {ModuleTemplate} moduleTemplate ModuleTemplate instance for render
* @param {DependencyTemplates} dependencyTemplates dependency templates
* @param {MainRenderContext} renderContext options object
* @returns {ConcatSource} the newly generated source from rendering
*/
render(hash, chunk, moduleTemplate, dependencyTemplates) {
render(moduleTemplate, renderContext) {
const { hash, chunk, chunkGraph } = renderContext;
const buf = [];
buf.push(
this.hooks.bootstrap.call(
"",
chunk,
hash,
moduleTemplate,
dependencyTemplates
)
);
buf.push(this.hooks.bootstrap.call("", moduleTemplate, renderContext));
buf.push(this.hooks.localVars.call("", chunk, hash));
buf.push("");
buf.push("// The require function");
buf.push(`function ${this.requireFn}(moduleId) {`);
buf.push(Template.indent(this.hooks.require.call("", chunk, hash)));
buf.push(Template.indent(this.hooks.require.call("", renderContext)));
buf.push("}");
buf.push("");
buf.push(
Template.asString(this.hooks.requireExtensions.call("", chunk, hash))
Template.asString(this.hooks.requireExtensions.call("", renderContext))
);
buf.push("");
buf.push(Template.asString(this.hooks.beforeStartup.call("", chunk, hash)));
buf.push(Template.asString(this.hooks.startup.call("", chunk, hash)));
buf.push(Template.asString(this.hooks.startup.call("", renderContext)));
let source = this.hooks.render.call(
new OriginalSource(
Template.prefix(buf, " \t") + "\n",
"webpack/bootstrap"
),
chunk,
hash,
moduleTemplate,
dependencyTemplates
renderContext
);
if (chunk.hasEntryModule()) {
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
source = this.hooks.renderWithEntry.call(source, chunk, hash);
}
if (!source) {
@ -427,19 +430,19 @@ module.exports = class MainTemplate {
/**
*
* @param {string} hash hash for render add fn
* @param {Chunk} chunk Chunk instance for require add fn
* @param {(string|number)=} varModuleId module id
* @param {Module} varModule Module instance
* @param {string} varModuleId module id
* @param {string} varModule Module instance
* @param {MainRenderContext} renderContext the render context
* @returns {TODO} renderAddModule call
*/
renderAddModule(hash, chunk, varModuleId, varModule) {
renderAddModule(varModuleId, varModule, renderContext) {
return this.hooks.addModule.call(
`modules[${varModuleId}] = ${varModule};`,
chunk,
hash,
varModuleId,
varModule
{
moduleId: varModuleId,
module: varModule
},
renderContext
);
}

View File

@ -477,9 +477,10 @@ class Module extends DependenciesBlock {
/**
* @param {Chunk} chunk the chunk which condition should be checked
* @param {Compilation} compilation the compilation
* @returns {boolean} true, if the chunk is ok for the module
*/
chunkCondition(chunk) {
chunkCondition(chunk, compilation) {
return true;
}

View File

@ -1,79 +0,0 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const MultiModuleFactory = require("./MultiModuleFactory");
const MultiEntryDependency = require("./dependencies/MultiEntryDependency");
const SingleEntryDependency = require("./dependencies/SingleEntryDependency");
/** @typedef {import("./Compiler")} Compiler */
class MultiEntryPlugin {
/**
* The MultiEntryPlugin is invoked whenever this.options.entry value is an array of paths
* @param {string} context context path
* @param {string[]} entries array of entry paths
* @param {string} name entry key name
*/
constructor(context, entries, name) {
this.context = context;
this.entries = entries;
this.name = name;
}
/**
* @param {Compiler} compiler the compiler instance
* @returns {void}
*/
apply(compiler) {
compiler.hooks.compilation.tap(
"MultiEntryPlugin",
(compilation, { normalModuleFactory }) => {
compilation.dependencyFactories.set(
MultiEntryDependency,
new MultiModuleFactory()
);
compilation.dependencyFactories.set(
SingleEntryDependency,
normalModuleFactory
);
}
);
compiler.hooks.make.tapAsync(
"MultiEntryPlugin",
(compilation, callback) => {
const { context, entries, name } = this;
const dep = MultiEntryPlugin.createDependency(entries, name);
compilation.addEntry(context, dep, name, callback);
}
);
}
/**
* @param {string[]} entries each entry path string
* @param {string} name name of the entry
* @returns {MultiEntryDependency} returns a constructed Dependency
*/
static createDependency(entries, name) {
return new MultiEntryDependency(
entries.map((e, idx) => {
const dep = new SingleEntryDependency(e);
// Because entrypoints are not dependencies found in an
// existing module, we give it a synthetic id
dep.loc = {
name,
index: idx
};
return dep;
}),
name
);
}
}
module.exports = MultiEntryPlugin;

View File

@ -1,122 +0,0 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const { RawSource } = require("webpack-sources");
const Module = require("./Module");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./Module").SourceContext} SourceContext */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
/** @typedef {import("./util/createHash").Hash} Hash */
class MultiModule extends Module {
constructor(context, dependencies, name) {
super("javascript/dynamic", context);
// Info from Factory
this.dependencies = dependencies;
this.name = name;
this._identifier = `multi ${this.dependencies
.map(d => d.request)
.join(" ")}`;
}
/**
* @returns {string} a unique identifier of the module
*/
identifier() {
return this._identifier;
}
/**
* @param {RequestShortener} requestShortener the request shortener
* @returns {string} a user readable identifier of the module
*/
readableIdentifier(requestShortener) {
return `multi ${this.dependencies
.map(d => requestShortener.shorten(d.request))
.join(" ")}`;
}
/**
* @param {TODO} options TODO
* @param {Compilation} compilation the compilation
* @param {TODO} resolver TODO
* @param {TODO} fs the file system
* @param {function(Error=): void} callback callback function
* @returns {void}
*/
build(options, compilation, resolver, fs, callback) {
this.built = true;
this.buildMeta = {};
this.buildInfo = {};
return callback();
}
/**
* @param {TODO} fileTimestamps timestamps of files
* @param {TODO} contextTimestamps timestamps of directories
* @returns {boolean} true, if the module needs a rebuild
*/
needRebuild(fileTimestamps, contextTimestamps) {
return false;
}
/**
* @returns {number} the estimated size of the module
*/
size() {
return 16 + this.dependencies.length * 12;
}
/**
* @param {Hash} hash the hash used to track dependencies
* @param {Compilation} compilation the compilation
* @returns {void}
*/
updateHash(hash, compilation) {
hash.update("multi module");
hash.update(this.name || "");
super.updateHash(hash, compilation);
}
/**
* @param {SourceContext} sourceContext source context
* @returns {Source} generated source
*/
source({ runtimeTemplate, moduleGraph }) {
const str = [];
let idx = 0;
for (const dep of this.dependencies) {
if (moduleGraph.getModule(dep)) {
if (idx === this.dependencies.length - 1) {
str.push("module.exports = ");
}
str.push(
runtimeTemplate.moduleRaw({
module: moduleGraph.getModule(dep),
request: dep.request
})
);
} else {
str.push(
runtimeTemplate.missingModule({
request: dep.request
})
);
}
str.push(";\n");
idx++;
}
return new RawSource(str.join(""));
}
}
module.exports = MultiModule;

View File

@ -1,22 +0,0 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const MultiModule = require("./MultiModule");
module.exports = class MultiModuleFactory {
constructor() {
this.hooks = Object.freeze({});
}
create(data, callback) {
const dependency = data.dependencies[0];
callback(
null,
new MultiModule(data.context, dependency.dependencies, dependency.name)
);
}
};

View File

@ -11,6 +11,7 @@ const HotUpdateChunk = require("./HotUpdateChunk");
/** @typedef {import("webpack-sources").ConcatSource} ConcatSource */
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./Module")} Module */
/** @typedef {import("./ModuleGraph")} ModuleGraph */
@ -30,6 +31,28 @@ const COMMENT_END_REGEX = /\*\//g;
const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-zA-Z0-9_!§$()=\-^°]+/g;
const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
/**
* @typedef {Object} RenderManifestOptions
* @property {Chunk} chunk the chunk used to render
* @property {string} hash
* @property {string} fullHash
* @property {TODO} outputOptions
* @property {{javascript: ModuleTemplate, webassembly: ModuleTemplate}} moduleTemplates
* @property {DependencyTemplates} dependencyTemplates
* @property {RuntimeTemplate} runtimeTemplate
* @property {ModuleGraph} moduleGraph
* @property {ChunkGraph} chunkGraph
*/
/**
* @typedef {Object} RenderManifestEntry
* @property {function(): Source} render
* @property {string=} filenameTemplate
* @property {TODO=} pathOptions
* @property {TODO} identifier
* @property {TODO=} hash
*/
/**
* @typedef {Object} HasId
* @property {number | string} id

View File

@ -7,7 +7,7 @@
const ModuleDependency = require("./ModuleDependency");
class SingleEntryDependency extends ModuleDependency {
class EntryDependency extends ModuleDependency {
/**
* @param {string} request request path for entry
*/
@ -16,8 +16,8 @@ class SingleEntryDependency extends ModuleDependency {
}
get type() {
return "single entry";
return "entry";
}
}
module.exports = SingleEntryDependency;
module.exports = EntryDependency;

View File

@ -1,28 +0,0 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const Dependency = require("../Dependency");
/** @typedef {import("./SingleEntryDependency")} SingleEntryDependency */
class MultiEntryDependency extends Dependency {
/**
* @param {SingleEntryDependency[]} dependencies an array of SingleEntryDependencies
* @param {string} name entry name
*/
constructor(dependencies, name) {
super();
this.dependencies = dependencies;
this.name = name;
}
get type() {
return "multi entry";
}
}
module.exports = MultiEntryDependency;

View File

@ -7,11 +7,17 @@
const Template = require("../Template");
/** @typedef {import("../MainTemplate")} MainTemplate */
module.exports = class NodeMainTemplatePlugin {
constructor(asyncChunkLoading) {
this.asyncChunkLoading = asyncChunkLoading;
}
/**
* @param {MainTemplate} mainTemplate the main template
* @returns {void}
*/
apply(mainTemplate) {
const needChunkOnDemandLoadingCode = chunk => {
for (const chunkGroup of chunk.groupsIterable) {
@ -41,7 +47,7 @@ module.exports = class NodeMainTemplatePlugin {
);
mainTemplate.hooks.requireExtensions.tap(
"NodeMainTemplatePlugin",
(source, chunk) => {
(source, { chunk }) => {
if (needChunkOnDemandLoadingCode(chunk)) {
return Template.asString([
source,
@ -63,7 +69,9 @@ module.exports = class NodeMainTemplatePlugin {
);
mainTemplate.hooks.requireEnsure.tap(
"NodeMainTemplatePlugin",
(source, chunk, hash) => {
(source, chunkIdExpression, renderContext) => {
// TODO use chunkIdExpression instead of hard-coded chunkId
const { chunk, hash } = renderContext;
const chunkFilename = mainTemplate.outputOptions.chunkFilename;
const chunkMaps = chunk.getChunkMaps();
const insertMoreModules = [
@ -71,10 +79,9 @@ module.exports = class NodeMainTemplatePlugin {
"for(var moduleId in moreModules) {",
Template.indent(
mainTemplate.renderAddModule(
hash,
chunk,
"moduleId",
"moreModules[moduleId]"
"moreModules[moduleId]",
renderContext
)
),
"}"

View File

@ -12,7 +12,9 @@ const { compareModulesById } = require("../util/comparators");
const identifierUtils = require("../util/identifier");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
const moveModuleBetween = (chunkGraph, oldChunk, newChunk) => {
return module => {
@ -21,9 +23,14 @@ const moveModuleBetween = (chunkGraph, oldChunk, newChunk) => {
};
};
const isNotAEntryModule = entryModule => {
/**
* @param {ChunkGraph} chunkGraph the chunk graph
* @param {Chunk} chunk the chunk
* @returns {function(Module): boolean} filter for entry module
*/
const isNotAEntryModule = (chunkGraph, chunk) => {
return module => {
return entryModule !== module;
return !chunkGraph.isEntryModuleInChunk(module, chunk);
};
};
@ -217,7 +224,7 @@ class AggressiveSplittingPlugin {
) {
const modules = chunkGraph
.getChunkModules(chunk)
.filter(isNotAEntryModule(chunk.entryModule))
.filter(isNotAEntryModule(chunkGraph, chunk))
.sort((a, b) => {
const aIdentifer = a.identifier();
const bIdentifer = b.identifier();

View File

@ -19,7 +19,7 @@ class EnsureChunkConditionsPlugin {
const chunkGroups = new Set();
for (const module of compilation.modules) {
for (const chunk of chunkGraph.getModuleChunksIterable(module)) {
if (!module.chunkCondition(chunk)) {
if (!module.chunkCondition(chunk, compilation)) {
sourceChunks.add(chunk);
for (const group of chunk.groupsIterable) {
chunkGroups.add(group);
@ -31,7 +31,7 @@ class EnsureChunkConditionsPlugin {
chunkGroupLoop: for (const chunkGroup of chunkGroups) {
// Can module be placed in a chunk of this group?
for (const chunk of chunkGroup.chunks) {
if (module.chunkCondition(chunk)) {
if (module.chunkCondition(chunk, compilation)) {
targetChunks.add(chunk);
continue chunkGroupLoop;
}

View File

@ -332,9 +332,6 @@ class ModuleConcatenationPlugin {
.getOptimizationBailout(moduleGraph)
.push(formatBailoutWarning(warning[0], warning[1]));
}
const chunks = chunkGraph.getModuleChunks(
concatConfiguration.rootModule
);
for (const m of modules) {
usedModules.add(m);
// remove module from chunk
@ -348,12 +345,6 @@ class ModuleConcatenationPlugin {
);
});
}
// add concatenated module to the chunks
for (const chunk of chunks) {
if (chunk.entryModule === concatConfiguration.rootModule) {
chunk.entryModule = newModule;
}
}
// add concatenated module to the compilation
compilation.modules.push(newModule);
}
@ -464,14 +455,23 @@ class ModuleConcatenationPlugin {
}
class ConcatConfiguration {
/**
*
* @param {Module} rootModule the root module
* @param {ConcatConfiguration=} cloneFrom base config
*/
constructor(rootModule, cloneFrom) {
this.rootModule = rootModule;
if (cloneFrom) {
this.modules = cloneFrom.modules.createChild(5);
this.warnings = cloneFrom.warnings.createChild(5);
/** @type {StackedSetMap} */
this.modules = cloneFrom.modules.createChild();
/** @type {StackedSetMap} */
this.warnings = cloneFrom.warnings.createChild();
} else {
/** @type {StackedSetMap} */
this.modules = new StackedSetMap();
this.modules.add(rootModule);
/** @type {StackedSetMap} */
this.warnings = new StackedSetMap();
}
}
@ -504,6 +504,9 @@ class ConcatConfiguration {
);
}
/**
* @returns {Set<Module>} modules as set
*/
getModules() {
return this.modules.asSet();
}

View File

@ -42,7 +42,7 @@ class OccurrenceOrderModuleIdsPlugin {
let entry = 0;
for (const c of chunkGraph.getModuleChunksIterable(m)) {
if (c.canBeInitial()) initial++;
if (c.entryModule === m) entry++;
if (chunkGraph.isEntryModuleInChunk(m, c)) entry++;
}
initialChunkChunkMap.set(m, initial);
entryCountMap.set(m, entry);

View File

@ -26,7 +26,7 @@ class RemoveEmptyChunksPlugin {
if (
chunkGraph.getNumberOfChunkModules(chunk) === 0 &&
!chunk.hasRuntime() &&
!chunk.hasEntryModule()
chunkGraph.getNumberOfEntryModules(chunk) === 0
) {
compilation.chunkGraph.disconnectChunk(chunk);
chunks.splice(i, 1);

View File

@ -658,7 +658,7 @@ module.exports = class SplitChunksPlugin {
item.modules.size
)
continue;
if (chunk.hasEntryModule()) continue;
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) continue;
for (const module of item.modules) {
if (!chunkGraph.isModuleInChunk(module, chunk))
continue outer;
@ -742,7 +742,7 @@ module.exports = class SplitChunksPlugin {
if (entrypoint) {
compilation.entrypoints.delete(chunkName);
entrypoint.remove();
newChunk.entryModule = undefined;
chunkGraph.disconnectEntries(newChunk);
}
}
if (item.cacheGroup.filename) {
@ -759,7 +759,7 @@ module.exports = class SplitChunksPlugin {
if (!isReused) {
// Add all modules to the new chunk
for (const module of item.modules) {
if (!module.chunkCondition(newChunk)) continue;
if (!module.chunkCondition(newChunk, compilation)) continue;
// Add module to new chunk
chunkGraph.connectChunkAndModule(newChunk, module);
// Remove module from used chunks
@ -866,7 +866,7 @@ module.exports = class SplitChunksPlugin {
newPart.chunkReason = chunk.chunkReason;
// Add all modules to the new chunk
for (const module of group.items) {
if (!module.chunkCondition(newPart)) continue;
if (!module.chunkCondition(newPart, compilation)) continue;
// Add module to new chunk
chunkGraph.connectChunkAndModule(newPart, module);
// Remove module from used chunks

View File

@ -223,7 +223,7 @@ class WasmMainTemplatePlugin {
);
mainTemplate.hooks.requireEnsure.tap(
"WasmMainTemplatePlugin",
(source, chunk, hash) => {
(source, chunkIdExpression, { chunk, hash }) => {
const webassemblyModuleFilename =
mainTemplate.outputOptions.webassemblyModuleFilename;
@ -272,7 +272,7 @@ class WasmMainTemplatePlugin {
"",
`var wasmModules = ${JSON.stringify(
chunkModuleMaps.id
)}[chunkId] || [];`,
)}[${chunkIdExpression}] || [];`,
"",
"wasmModules.forEach(function(wasmModuleId) {",
Template.indent([
@ -351,7 +351,7 @@ class WasmMainTemplatePlugin {
);
mainTemplate.hooks.requireExtensions.tap(
"WasmMainTemplatePlugin",
(source, chunk) => {
(source, { chunk }) => {
const chunkGraph = this.compilation.chunkGraph;
if (
!chunkGraph.hasModuleInGraph(chunk, m =>

View File

@ -6,20 +6,12 @@
"use strict";
const { ConcatSource } = require("webpack-sources");
const getEntryInfo = require("./JsonpHelpers").getEntryInfo;
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkTemplate")} ChunkTemplate */
/** @typedef {import("../Compilation")} Compilation */
const getEntryInfo = chunk => {
return [chunk.entryModule].filter(Boolean).map(m =>
[m.id].concat(
Array.from(chunk.groupsIterable)[0]
.chunks.filter(c => c !== chunk)
.map(c => c.id)
)
);
};
class JsonpChunkTemplatePlugin {
/**
* @param {Compilation} compilation the compilation
@ -48,7 +40,7 @@ class JsonpChunkTemplatePlugin {
)}] || []).push([${JSON.stringify(chunk.ids)},`
);
source.add(modules);
const entries = getEntryInfo(chunk);
const entries = getEntryInfo(chunkGraph, chunk);
if (entries.length > 0) {
source.add(`,${JSON.stringify(entries)}`);
} else if (prefetchChunks && prefetchChunks.length) {
@ -72,7 +64,7 @@ class JsonpChunkTemplatePlugin {
"JsonpChunkTemplatePlugin",
(hash, chunk) => {
const chunkGraph = this.compilation.chunkGraph;
hash.update(JSON.stringify(getEntryInfo(chunk)));
hash.update(JSON.stringify(getEntryInfo(chunkGraph, chunk)));
hash.update(
JSON.stringify(chunk.getChildIdsByOrders(chunkGraph).prefetch) || ""
);

26
lib/web/JsonpHelpers.js Normal file
View File

@ -0,0 +1,26 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {(string|number)[]} EntryItem */
/**
* @param {ChunkGraph} chunkGraph the chunk graph
* @param {Chunk} chunk the chunk
* @returns {EntryItem[]} serialized entry info:
* inner arrays have this format [module id, ...chunk ids]
*/
exports.getEntryInfo = (chunkGraph, chunk) => {
return Array.from(
chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
).map(([module, chunkGroup]) =>
[module.id].concat(
chunkGroup.chunks.filter(c => c !== chunk).map(c => c.id)
)
);
};

View File

@ -8,8 +8,10 @@
const { SyncWaterfallHook } = require("tapable");
const MainTemplate = require("../MainTemplate");
const Template = require("../Template");
const getEntryInfo = require("./JsonpHelpers").getEntryInfo;
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../MainTemplate")} MainTemplate */
const mainTemplateHooksMap = new WeakMap();
@ -39,6 +41,10 @@ class JsonpMainTemplatePlugin {
return hooks;
}
/**
* @param {MainTemplate} mainTemplate the main template
* @returns {void}
*/
apply(mainTemplate) {
const needChunkOnDemandLoadingCode = chunk => {
for (const chunkGroup of chunk.groupsIterable) {
@ -283,13 +289,13 @@ class JsonpMainTemplatePlugin {
);
mainTemplate.hooks.requireEnsure.tap(
"JsonpMainTemplatePlugin load",
(source, chunk, hash) => {
(source, chunkIdExpression, { chunk, hash }) => {
return Template.asString([
source,
"",
"// JSONP chunk loading for javascript",
"",
"var installedChunkData = installedChunks[chunkId];",
`var installedChunkData = installedChunks[${chunkIdExpression}];`,
'if(installedChunkData !== 0) { // 0 means "already installed".',
Template.indent([
"",
@ -301,7 +307,7 @@ class JsonpMainTemplatePlugin {
"// setup Promise in chunk cache",
"var promise = new Promise(function(resolve, reject) {",
Template.indent([
"installedChunkData = installedChunks[chunkId] = [resolve, reject];"
`installedChunkData = installedChunks[${chunkIdExpression}] = [resolve, reject];`
]),
"});",
"promises.push(installedChunkData[2] = promise);",
@ -318,11 +324,12 @@ class JsonpMainTemplatePlugin {
}
);
mainTemplate.hooks.requireEnsure.tap(
{
// TODO typing are broken
/** @type {any} */ ({
name: "JsonpMainTemplatePlugin preload",
stage: 10
},
(source, chunk, hash) => {
}),
(source, chunkIdExpression, { chunk, hash }) => {
const chunkMap = chunk.getChildIdsByOrdersMap(
this.compilation.chunkGraph
).preload;
@ -334,7 +341,7 @@ class JsonpMainTemplatePlugin {
"",
`var chunkPreloadMap = ${JSON.stringify(chunkMap, null, "\t")};`,
"",
"var chunkPreloadData = chunkPreloadMap[chunkId];",
`var chunkPreloadData = chunkPreloadMap[${chunkIdExpression}];`,
"if(chunkPreloadData) {",
Template.indent([
"var head = document.getElementsByTagName('head')[0];",
@ -356,7 +363,7 @@ class JsonpMainTemplatePlugin {
);
mainTemplate.hooks.requireExtensions.tap(
"JsonpMainTemplatePlugin",
(source, chunk) => {
(source, { chunk }) => {
if (!needChunkOnDemandLoadingCode(chunk)) return source;
return Template.asString([
@ -371,7 +378,8 @@ class JsonpMainTemplatePlugin {
);
mainTemplate.hooks.bootstrap.tap(
"JsonpMainTemplatePlugin",
(source, chunk, hash) => {
(source, moduleTemplate, renderContext) => {
const { chunk, hash } = renderContext;
if (needChunkLoadingCode(chunk)) {
const withDefer = needEntryDeferringCode(chunk);
const withPrefetch = needPrefetchingCode(chunk);
@ -402,10 +410,9 @@ class JsonpMainTemplatePlugin {
"if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {",
Template.indent(
mainTemplate.renderAddModule(
hash,
chunk,
"moduleId",
"moreModules[moduleId]"
"moreModules[moduleId]",
renderContext
)
),
"}"
@ -525,16 +532,10 @@ class JsonpMainTemplatePlugin {
);
mainTemplate.hooks.startup.tap(
"JsonpMainTemplatePlugin",
(source, chunk, hash) => {
(source, { chunk, chunkGraph }) => {
if (needEntryDeferringCode(chunk)) {
if (chunk.hasEntryModule()) {
const entries = [chunk.entryModule].filter(Boolean).map(m =>
[m.id].concat(
Array.from(chunk.groupsIterable)[0]
.chunks.filter(c => c !== chunk)
.map(c => c.id)
)
);
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
const entries = getEntryInfo(chunkGraph, chunk);
return Template.asString([
"// add entry module to deferred list",
`deferredModules.push(${entries

View File

@ -94,6 +94,7 @@ exportPlugins(exports, {
Dependency: () => require("./Dependency"),
DllPlugin: () => require("./DllPlugin"),
DllReferencePlugin: () => require("./DllReferencePlugin"),
EntryPlugin: () => require("./EntryPlugin"),
EnvironmentPlugin: () => require("./EnvironmentPlugin"),
EvalDevToolModulePlugin: () => require("./EvalDevToolModulePlugin"),
EvalSourceMapDevToolPlugin: () => require("./EvalSourceMapDevToolPlugin"),
@ -117,7 +118,6 @@ exportPlugins(exports, {
ProgressPlugin: () => require("./ProgressPlugin"),
ProvidePlugin: () => require("./ProvidePlugin"),
SetVarMainTemplatePlugin: () => require("./SetVarMainTemplatePlugin"),
SingleEntryPlugin: () => require("./SingleEntryPlugin"),
SourceMapDevToolPlugin: () => require("./SourceMapDevToolPlugin"),
Stats: () => require("./Stats"),
Template: () => require("./Template"),

View File

@ -7,7 +7,13 @@
const Template = require("../Template");
/** @typedef {import("../MainTemplate")} MainTemplate */
class WebWorkerMainTemplatePlugin {
/**
* @param {MainTemplate} mainTemplate the main template
* @returns {void}
*/
apply(mainTemplate) {
const needChunkOnDemandLoadingCode = chunk => {
for (const chunkGroup of chunk.groupsIterable) {
@ -36,7 +42,8 @@ class WebWorkerMainTemplatePlugin {
);
mainTemplate.hooks.requireEnsure.tap(
"WebWorkerMainTemplatePlugin",
(_, chunk, hash) => {
(_, chunkIdExpression, { chunk, hash }) => {
// TODO use chunkIdExpression instead of chunkId
const chunkFilename = mainTemplate.outputOptions.chunkFilename;
const chunkMaps = chunk.getChunkMaps();
return Template.asString([
@ -106,7 +113,8 @@ class WebWorkerMainTemplatePlugin {
);
mainTemplate.hooks.bootstrap.tap(
"WebWorkerMainTemplatePlugin",
(source, chunk, hash) => {
(source, moduleTemplate, renderContext) => {
const { chunk } = renderContext;
if (needChunkOnDemandLoadingCode(chunk)) {
const chunkCallbackName =
mainTemplate.outputOptions.chunkCallbackName;
@ -120,10 +128,9 @@ class WebWorkerMainTemplatePlugin {
"for(var moduleId in moreModules) {",
Template.indent(
mainTemplate.renderAddModule(
hash,
chunk,
"moduleId",
"moreModules[moduleId]"
"moreModules[moduleId]",
renderContext
)
),
"}",

View File

@ -68,6 +68,20 @@ describe("StatsTestCases", () => {
])
);
};
c.hooks.compilation.tap("StatsTestCasesTest", compilation => {
[
"optimize",
"optimizeModulesBasic",
"optimizeChunksBasic",
"afterOptimizeTree",
"afterOptimizeAssets",
"beforeHash"
].forEach(hook => {
compilation.hooks[hook].tap("TestCasesTest", () =>
compilation.checkConstraints()
);
});
});
});
c.run((err, stats) => {
if (err) return done(err);

View File

@ -1,17 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`StatsTestCases should print correct stats for aggressive-splitting-entry 1`] = `
"Hash: 44a278e3b0741b9b5da644a278e3b0741b9b5da6
"Hash: 5071403fab92cdd591e25071403fab92cdd591e2
Child fitting:
Hash: 44a278e3b0741b9b5da6
Hash: 5071403fab92cdd591e2
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
d4b551c6319035df2898.js 1.05 KiB 0 [emitted]
7029d2a129d88406bdea.js 1.94 KiB 1 [emitted]
9d3d08d313ade4d2c47a.js 11.1 KiB 2 [emitted]
ebed0abd0a2953a40be0.js 11.1 KiB 2 [emitted]
5d5aae6ca1af5d6e6ea4.js 1.94 KiB 3 [emitted]
Entrypoint main = 5d5aae6ca1af5d6e6ea4.js 7029d2a129d88406bdea.js 9d3d08d313ade4d2c47a.js
Entrypoint main = 5d5aae6ca1af5d6e6ea4.js 7029d2a129d88406bdea.js ebed0abd0a2953a40be0.js
chunk {0} d4b551c6319035df2898.js 916 bytes <{1}> <{2}> <{3}>
> ./g [4] ./index.js 7:0-13
[7] ./g.js 916 bytes {0} [built]
@ -19,7 +19,7 @@ Child fitting:
> ./index main
[1] ./c.js 899 bytes {1} [built]
[2] ./d.js 899 bytes {1} [built]
chunk {2} 9d3d08d313ade4d2c47a.js 1.87 KiB ={1}= ={3}= >{0}< [entry] [rendered]
chunk {2} ebed0abd0a2953a40be0.js 1.87 KiB ={1}= ={3}= >{0}< [entry] [rendered]
> ./index main
[3] ./e.js 899 bytes {2} [built]
[4] ./index.js 111 bytes {2} [built]
@ -29,15 +29,15 @@ Child fitting:
[0] ./b.js 899 bytes {3} [built]
[5] ./a.js 899 bytes {3} [built]
Child content-change:
Hash: 44a278e3b0741b9b5da6
Hash: 5071403fab92cdd591e2
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
d4b551c6319035df2898.js 1.05 KiB 0 [emitted]
7029d2a129d88406bdea.js 1.94 KiB 1 [emitted]
9d3d08d313ade4d2c47a.js 11.1 KiB 2 [emitted]
ebed0abd0a2953a40be0.js 11.1 KiB 2 [emitted]
5d5aae6ca1af5d6e6ea4.js 1.94 KiB 3 [emitted]
Entrypoint main = 5d5aae6ca1af5d6e6ea4.js 7029d2a129d88406bdea.js 9d3d08d313ade4d2c47a.js
Entrypoint main = 5d5aae6ca1af5d6e6ea4.js 7029d2a129d88406bdea.js ebed0abd0a2953a40be0.js
chunk {0} d4b551c6319035df2898.js 916 bytes <{1}> <{2}> <{3}>
> ./g [4] ./index.js 7:0-13
[7] ./g.js 916 bytes {0} [built]
@ -45,7 +45,7 @@ Child content-change:
> ./index main
[1] ./c.js 899 bytes {1} [built]
[2] ./d.js 899 bytes {1} [built]
chunk {2} 9d3d08d313ade4d2c47a.js 1.87 KiB ={1}= ={3}= >{0}< [entry] [rendered]
chunk {2} ebed0abd0a2953a40be0.js 1.87 KiB ={1}= ={3}= >{0}< [entry] [rendered]
> ./index main
[3] ./e.js 899 bytes {2} [built]
[4] ./index.js 111 bytes {2} [built]
@ -57,7 +57,7 @@ Child content-change:
`;
exports[`StatsTestCases should print correct stats for aggressive-splitting-on-demand 1`] = `
"Hash: 02a058acce1bfbcd9896
"Hash: 9418f05bd974463160e9
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -71,9 +71,9 @@ c99c160aba2d9a94e5d1.js 1.94 KiB 5 [emitted]
6a8e74d82c35e3f013d2.js 1 KiB 7 [emitted]
ee043b525cd899e33ec0.js 1.94 KiB 8 [emitted]
01a8254701931adbf278.js 1.01 KiB 9 [emitted]
57253719544987787b40.js 9.7 KiB 10 [emitted] main
9162e370d5b0e4d1fe70.js 9.7 KiB 10 [emitted] main
ba9fedb7aa0c69201639.js 1.94 KiB 11 [emitted]
Entrypoint main = 57253719544987787b40.js
Entrypoint main = 9162e370d5b0e4d1fe70.js
chunk {0} 2736cf9d79233cd0a9b6.js 1.76 KiB <{10}> ={2}= ={3}= ={4}= ={5}= ={7}= [recorded] aggressive splitted
> ./b ./d ./e ./f ./g [11] ./index.js 5:0-44
> ./b ./d ./e ./f ./g ./h ./i ./j ./k [11] ./index.js 6:0-72
@ -115,7 +115,7 @@ chunk {8} ee043b525cd899e33ec0.js 1.76 KiB <{10}> ={4}= [recorded] aggressive
chunk {9} 01a8254701931adbf278.js 899 bytes <{10}>
> ./a [11] ./index.js 1:0-16
[10] ./a.js 899 bytes {9} [built]
chunk {10} 57253719544987787b40.js (main) 248 bytes >{0}< >{1}< >{2}< >{3}< >{4}< >{5}< >{6}< >{7}< >{8}< >{9}< >{11}< [entry] [rendered]
chunk {10} 9162e370d5b0e4d1fe70.js (main) 248 bytes >{0}< >{1}< >{2}< >{3}< >{4}< >{5}< >{6}< >{7}< >{8}< >{9}< >{11}< [entry] [rendered]
> ./index main
[11] ./index.js 248 bytes {10} [built]
chunk {11} ba9fedb7aa0c69201639.js 1.76 KiB <{10}> ={2}= ={6}= [rendered] [recorded] aggressive splitted
@ -467,7 +467,7 @@ Child all:
`;
exports[`StatsTestCases should print correct stats for chunk-module-id-range 1`] = `
"Hash: 8683bda4416097d173ee
"Hash: 04aadacf6417d157d7a8
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -492,7 +492,7 @@ chunk {1} main1.js (main1) 136 bytes [entry] [rendered]
`;
exports[`StatsTestCases should print correct stats for chunks 1`] = `
"Hash: bb90fc9e61205a066fee
"Hash: 9557124dd322802a4580
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -504,7 +504,7 @@ Entrypoint main = bundle.js
chunk {0} bundle.js (main) 73 bytes >{1}< >{2}< [entry] [rendered]
> ./index main
[0] ./index.js 51 bytes {0} [built]
single entry ./index main
entry ./index main
factory:Xms building:Xms = Xms
[1] ./a.js 22 bytes {0} [built]
cjs require ./a [0] ./index.js 1:0-14
@ -530,7 +530,7 @@ chunk {3} 3.bundle.js 44 bytes <{2}> [rendered]
`;
exports[`StatsTestCases should print correct stats for chunks-development 1`] = `
"Hash: 83bf92a94bc3834801e8
"Hash: b66c6464f88d39a97070
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -564,7 +564,7 @@ chunk {main} bundle.js (main) 73 bytes >{0}< >{1}< [entry] [rendered]
cjs require ./a [./index.js] 1:0-14
[./index.js] Xms -> factory:Xms building:Xms = Xms
[./index.js] 51 bytes {main} [built]
single entry ./index main
entry ./index main
factory:Xms building:Xms = Xms"
`;
@ -581,7 +581,7 @@ chunk {3} 3.bundle.js (c) 98 bytes <{1}> <{2}> >{1}< >{2}< [rendered]
`;
exports[`StatsTestCases should print correct stats for color-disabled 1`] = `
"Hash: c5ad40363e9aee54c089
"Hash: 703cfa0463cb3c00055c
Time: Xms
Built at: Thu Jan 01 1970 <CLR=BOLD>00:00:00</CLR> GMT
Asset Size Chunks Chunk Names
@ -591,7 +591,7 @@ Entrypoint main = main.js
`;
exports[`StatsTestCases should print correct stats for color-enabled 1`] = `
"Hash: <CLR=BOLD>c5ad40363e9aee54c089</CLR>
"Hash: <CLR=BOLD>703cfa0463cb3c00055c</CLR>
Time: <CLR=BOLD>X</CLR>ms
Built at: Thu Jan 01 1970 <CLR=BOLD>00:00:00</CLR> GMT
<CLR=BOLD>Asset</CLR> <CLR=BOLD>Size</CLR> <CLR=BOLD>Chunks</CLR> <CLR=39,BOLD><CLR=22> <CLR=39,BOLD><CLR=22><CLR=BOLD>Chunk Names</CLR>
@ -601,7 +601,7 @@ Entrypoint <CLR=BOLD>main</CLR> = <CLR=32,BOLD>main.js</CLR>
`;
exports[`StatsTestCases should print correct stats for color-enabled-custom 1`] = `
"Hash: <CLR=BOLD>c5ad40363e9aee54c089</CLR>
"Hash: <CLR=BOLD>703cfa0463cb3c00055c</CLR>
Time: <CLR=BOLD>X</CLR>ms
Built at: Thu Jan 01 1970 <CLR=BOLD>00:00:00</CLR> GMT
<CLR=BOLD>Asset</CLR> <CLR=BOLD>Size</CLR> <CLR=BOLD>Chunks</CLR> <CLR=39,BOLD><CLR=22> <CLR=39,BOLD><CLR=22><CLR=BOLD>Chunk Names</CLR>
@ -611,7 +611,7 @@ Entrypoint <CLR=BOLD>main</CLR> = <CLR=32>main.js</CLR>
`;
exports[`StatsTestCases should print correct stats for commons-chunk-min-size-0 1`] = `
"Hash: 54d4e5458e5d48cb25ea
"Hash: 35dc5b4d12d551e4af91
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -628,7 +628,7 @@ Entrypoint entry-1 = vendor-1~entry-1.js entry-1.js
`;
exports[`StatsTestCases should print correct stats for commons-chunk-min-size-Infinity 1`] = `
"Hash: 275af2436329c6c382a9
"Hash: 5dd30065e34a02ecc6a8
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -645,9 +645,9 @@ Entrypoint entry-1 = vendor-1.js entry-1.js
`;
exports[`StatsTestCases should print correct stats for commons-plugin-issue-4980 1`] = `
"Hash: 137d627ba070d33cdda49a001f783027b840be9c
"Hash: 35f4c0b458700e5690125d578fbbda31da1fdadb
Child
Hash: 137d627ba070d33cdda4
Hash: 35f4c0b458700e569012
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -660,7 +660,7 @@ Child
| ./submodule-a.js 59 bytes [built]
| ./submodule-b.js 59 bytes [built]
Child
Hash: 9a001f783027b840be9c
Hash: 5d578fbbda31da1fdadb
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -692,9 +692,9 @@ exports[`StatsTestCases should print correct stats for concat-and-sideeffects 1`
`;
exports[`StatsTestCases should print correct stats for define-plugin 1`] = `
"Hash: cfe08d4450db77f81610f4228fcb997ec81e2aa6bb43e7d151657ea2b793
"Hash: d137985c3dc6e1d36484ae900f5ab7a1699250503bca3a1a2ed59b322b45
Child
Hash: cfe08d4450db77f81610
Hash: d137985c3dc6e1d36484
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -702,7 +702,7 @@ Child
Entrypoint main = main.js
[0] ./index.js 24 bytes {0} [built]
Child
Hash: f4228fcb997ec81e2aa6
Hash: ae900f5ab7a169925050
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -710,7 +710,7 @@ Child
Entrypoint main = main.js
[0] ./index.js 24 bytes {0} [built]
Child
Hash: bb43e7d151657ea2b793
Hash: 3bca3a1a2ed59b322b45
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -720,7 +720,7 @@ Child
`;
exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624 1`] = `
"Hash: 29b62432962bce4c54c0
"Hash: b103d43f856eb3a1c997
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -730,7 +730,7 @@ Entrypoint main = bundle.js
`;
exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624-error 1`] = `
"Hash: 701dcf62b26d0347b899
"Hash: 4a2b1eec4a4806b9dc12
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -743,7 +743,7 @@ Unexpected end of JSON input while parsing near ''"
`;
exports[`StatsTestCases should print correct stats for exclude-with-loader 1`] = `
"Hash: 52eadc5de721f000106b
"Hash: 83fac664b3322d053bd8
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -756,7 +756,7 @@ Entrypoint main = bundle.js
`;
exports[`StatsTestCases should print correct stats for external 1`] = `
"Hash: 7a4bb5500ee0eddeee44
"Hash: dbb8d2da46449d2bfe85
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -767,9 +767,9 @@ Entrypoint main = main.js
`;
exports[`StatsTestCases should print correct stats for filter-warnings 1`] = `
"Hash: 0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed
"Hash: 88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d
Child undefined:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -798,49 +798,49 @@ Child undefined:
WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child UglifyJs:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js
Child /UglifyJs/:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js
Child warnings => true:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js
Child [UglifyJs]:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js
Child [/UglifyJs/]:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js
Child [warnings => true]:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js
Child should not filter:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -869,7 +869,7 @@ Child should not filter:
WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child /should not filter/:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -898,7 +898,7 @@ Child /should not filter/:
WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child warnings => false:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -927,7 +927,7 @@ Child warnings => false:
WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child [should not filter]:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -956,7 +956,7 @@ Child [should not filter]:
WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child [/should not filter/]:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -985,7 +985,7 @@ Child [/should not filter/]:
WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child [warnings => false]:
Hash: 0f57e2bad314fb37b8ed
Hash: 88aed3fe1afcb496898d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1020,10 +1020,10 @@ exports[`StatsTestCases should print correct stats for graph-correctness-entries
Entrypoint e2 = e2.js
chunk {0} e1.js (e1) 49 bytes >{2}< [entry] [rendered]
[0] ./e1.js 49 bytes {0} [built]
single entry ./e1 e1
entry ./e1 e1
chunk {1} e2.js (e2) 49 bytes >{3}< [entry] [rendered]
[1] ./e2.js 49 bytes {1} [built]
single entry ./e2 e2
entry ./e2 e2
chunk {2} a.js (a) 49 bytes <{0}> <{3}> >{4}< [rendered]
[2] ./module-a.js 49 bytes {2} [built]
import() ./module-a [0] ./e1.js 1:0-47
@ -1042,7 +1042,7 @@ exports[`StatsTestCases should print correct stats for graph-correctness-modules
Entrypoint e2 = e2.js
chunk {0} e1.js (e1) 119 bytes >{2}< >{3}< [entry] [rendered]
[0] ./e1.js 70 bytes {0} [built]
single entry ./e1 e1
entry ./e1 e1
[1] ./module-x.js 49 bytes {0} {1} [built]
harmony side effect evaluation ./module-x [0] ./e1.js 1:0-20
harmony side effect evaluation ./module-x [2] ./e2.js 1:0-20
@ -1053,7 +1053,7 @@ chunk {1} e2.js (e2) 119 bytes >{3}< >{4}< [entry] [rendered]
harmony side effect evaluation ./module-x [2] ./e2.js 1:0-20
import() ./module-x [6] ./module-b.js 2:0-20
[2] ./e2.js 70 bytes {1} [built]
single entry ./e2 e2
entry ./e2 e2
chunk {2} a.js (a) 49 bytes <{0}> <{4}> >{5}< [rendered]
[3] ./module-a.js 49 bytes {2} [built]
import() ./module-a [0] ./e1.js 2:0-47
@ -1071,7 +1071,7 @@ chunk {5} b.js (b) 179 bytes <{2}> >{4}< [rendered]
`;
exports[`StatsTestCases should print correct stats for import-context-filter 1`] = `
"Hash: 7ad77a3e9e3d661cd55e
"Hash: 00093e0065918fc6beca
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1088,7 +1088,7 @@ Entrypoint entry = entry.js
`;
exports[`StatsTestCases should print correct stats for import-weak 1`] = `
"Hash: a4a61ec24e06498a1f58
"Hash: 020bd304e43a2b2f22bb
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1123,49 +1123,49 @@ Compilation error while processing magic comment(-s): /* webpackPrefetch: true,
`;
exports[`StatsTestCases should print correct stats for issue-7577 1`] = `
"Hash: 343642fcbd3799129ba3c304c0cf29920d9747260bd6e5e36b1ff9a17678
"Hash: 85309305fa40259fb1ebc74e886ded34938c99afb793a0bac9d49c018eb7
Child
Hash: 343642fcbd3799129ba3
Hash: 85309305fa40259fb1eb
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
a-all~main-0034bb84916bcade4cc7.js 154 bytes all~main [emitted] all~main
a-main-14ee9c594789bd77b887.js 108 bytes main [emitted] main
a-main-9407860001b0bf9acb00.js 108 bytes main [emitted] main
a-runtime~main-aa303e56a90b4559481f.js 6.05 KiB runtime~main [emitted] runtime~main
Entrypoint main = a-runtime~main-aa303e56a90b4559481f.js a-all~main-0034bb84916bcade4cc7.js a-main-14ee9c594789bd77b887.js
Entrypoint main = a-runtime~main-aa303e56a90b4559481f.js a-all~main-0034bb84916bcade4cc7.js a-main-9407860001b0bf9acb00.js
[0] ./a.js 18 bytes {all~main} [built]
Child
Hash: c304c0cf29920d974726
Hash: c74e886ded34938c99af
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
b-all~main-a293363005660974db22.js 459 bytes all~main [emitted] all~main
b-main-1dc1f5a633a7b6c2376f.js 123 bytes main [emitted] main
b-main-ad8a5f8b02d5a200d778.js 123 bytes main [emitted] main
b-runtime~main-937400e6bee421a9af47.js 6.05 KiB runtime~main [emitted] runtime~main
b-vendors~main-13c0fc262f08dee65613.js 172 bytes vendors~main [emitted] vendors~main
Entrypoint main = b-runtime~main-937400e6bee421a9af47.js b-vendors~main-13c0fc262f08dee65613.js b-all~main-a293363005660974db22.js b-main-1dc1f5a633a7b6c2376f.js
Entrypoint main = b-runtime~main-937400e6bee421a9af47.js b-vendors~main-13c0fc262f08dee65613.js b-all~main-a293363005660974db22.js b-main-ad8a5f8b02d5a200d778.js
[0] ./b.js 17 bytes {all~main} [built]
[1] ./node_modules/vendor.js 23 bytes {vendors~main} [built]
Child
Hash: 0bd6e5e36b1ff9a17678
Hash: b793a0bac9d49c018eb7
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
c-main-5eaed336f1da9c475636.js 114 bytes main [emitted] main
c-main-395ed4acf6a1f211e7f1.js 114 bytes main [emitted] main
c-0-598d23de6ad7df2ab6e4.js 153 bytes 0 [emitted]
c-1-9039f4a1a11a97f28320.js 459 bytes 1 [emitted]
c-all~main-166656d0ac46d1a19871.js 296 bytes all~main [emitted] all~main
c-runtime~main-54fe8e7231733bcf484a.js 8.84 KiB runtime~main [emitted] runtime~main
Entrypoint main = c-runtime~main-54fe8e7231733bcf484a.js c-all~main-166656d0ac46d1a19871.js c-main-5eaed336f1da9c475636.js (prefetch: c-0-598d23de6ad7df2ab6e4.js c-1-9039f4a1a11a97f28320.js)
Entrypoint main = c-runtime~main-54fe8e7231733bcf484a.js c-all~main-166656d0ac46d1a19871.js c-main-395ed4acf6a1f211e7f1.js (prefetch: c-0-598d23de6ad7df2ab6e4.js c-1-9039f4a1a11a97f28320.js)
[0] ./c.js 61 bytes {all~main} [built]
[1] ./b.js 17 bytes {1} [built]
[2] ./node_modules/vendor.js 23 bytes {0} [built]"
`;
exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = `
"Hash: 3f682d19df3a78cc355bea647ea3fd883ece89243ab5b7fed36cc043302dfa02c84a4a470a27c245
"Hash: 107c243d2f4948779db6faef5739a00d90343e7d46e1640f099b398451adcc962a224e99bbf022c3
Child 1 chunks:
Hash: 3f682d19df3a78cc355b
Hash: 107c243d2f4948779db6
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1179,7 +1179,7 @@ Child 1 chunks:
[4] ./d.js 22 bytes {0} [built]
[5] ./e.js 22 bytes {0} [built]
Child 2 chunks:
Hash: ea647ea3fd883ece8924
Hash: faef5739a00d90343e7d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1195,7 +1195,7 @@ Child 2 chunks:
[4] ./d.js 22 bytes {1} [built]
[5] ./e.js 22 bytes {1} [built]
Child 3 chunks:
Hash: 3ab5b7fed36cc043302d
Hash: 46e1640f099b398451ad
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1213,7 +1213,7 @@ Child 3 chunks:
[2] ./b.js 22 bytes {2} [built]
[5] ./e.js 22 bytes {2} [built]
Child 4 chunks:
Hash: fa02c84a4a470a27c245
Hash: cc962a224e99bbf022c3
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1235,7 +1235,7 @@ Child 4 chunks:
`;
exports[`StatsTestCases should print correct stats for max-modules 1`] = `
"Hash: ce942cd1353f7d6fc01e
"Hash: e8b18f1cf5f95cf5a285
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1265,7 +1265,7 @@ Entrypoint main = main.js
`;
exports[`StatsTestCases should print correct stats for max-modules-default 1`] = `
"Hash: ce942cd1353f7d6fc01e
"Hash: e8b18f1cf5f95cf5a285
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1290,7 +1290,7 @@ Entrypoint main = main.js
`;
exports[`StatsTestCases should print correct stats for module-assets 1`] = `
"Hash: 0aa43ba74041bc65bc0a
"Hash: 8ae1dea4bce18528f657
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Entrypoint main = main.js
@ -1472,7 +1472,7 @@ Child
`;
exports[`StatsTestCases should print correct stats for named-chunks-plugin 1`] = `
"Hash: 0c5756674e2dda021828
"Hash: 65cd83ae5b2980359572
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1486,7 +1486,7 @@ Entrypoint entry = vendor.js entry.js
`;
exports[`StatsTestCases should print correct stats for named-chunks-plugin-async 1`] = `
"Hash: 8517d17cf111f52660cd
"Hash: 421934d6424eb810e1a8
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1500,7 +1500,7 @@ Entrypoint entry = entry.js
`;
exports[`StatsTestCases should print correct stats for no-emit-on-errors-plugin-with-child-error 1`] = `
"Hash: 6a246e5dec75240f30bf
"Hash: 0d1fa1c56ef4d2b16cdd
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1522,7 +1522,7 @@ Child child:
`;
exports[`StatsTestCases should print correct stats for optimize-chunks 1`] = `
"Hash: 1f0728f6992d48535826
"Hash: 2c343cbbb1c034dcc13d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1593,9 +1593,9 @@ You may need an appropriate loader to handle this file type.
`;
exports[`StatsTestCases should print correct stats for performance-different-mode-and-target 1`] = `
"Hash: b27a7019f90a13ead012bb84b396eb1e98365d94fb930f6aa3329ab03a278deb0030bfebe86abb37a1cddcae25eb52f3112b62c8b61bc84829d26b13ae06efe5f0099a11af36
"Hash: 27afa870ea890dcb8d211cf632c77c707c36d94b810d87a0ecb3d46fb6472b646a1947dce27d2c2ca90600658140ce9be0af7e07124a239ee933822c55b9d2204250eb77a29a
Child
Hash: b27a7019f90a13ead012
Hash: 27afa870ea890dcb8d21
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1618,7 +1618,7 @@ Child
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/
Child
Hash: bb84b396eb1e98365d94
Hash: 1cf632c77c707c36d94b
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1641,7 +1641,7 @@ Child
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/
Child
Hash: fb930f6aa3329ab03a27
Hash: 810d87a0ecb3d46fb647
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1649,7 +1649,7 @@ Child
Entrypoint main = no-warning.pro-node.js
[0] ./index.js 293 KiB {0} [built]
Child
Hash: 8deb0030bfebe86abb37
Hash: 2b646a1947dce27d2c2c
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1657,7 +1657,7 @@ Child
Entrypoint main = no-warning.dev-web.js
[./index.js] 293 KiB {main} [built]
Child
Hash: a1cddcae25eb52f3112b
Hash: a90600658140ce9be0af
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1665,7 +1665,7 @@ Child
Entrypoint main = no-warning.dev-node.js
[./index.js] 293 KiB {main} [built]
Child
Hash: 62c8b61bc84829d26b13
Hash: 7e07124a239ee933822c
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1673,7 +1673,7 @@ Child
Entrypoint main [big] = no-warning.dev-web-with-limit-set.js
[./index.js] 293 KiB {main} [built]
Child
Hash: ae06efe5f0099a11af36
Hash: 55b9d2204250eb77a29a
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1874,7 +1874,7 @@ chunk {6} inner2.js (inner2) 0 bytes <{1}> [rendered]"
`;
exports[`StatsTestCases should print correct stats for preset-detailed 1`] = `
"Hash: 437c9384ca68c9e15b6c
"Hash: 3b3a7ec8ed8bc5030c9b
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -1933,7 +1933,7 @@ exports[`StatsTestCases should print correct stats for preset-none-array 1`] = `
exports[`StatsTestCases should print correct stats for preset-none-error 1`] = `""`;
exports[`StatsTestCases should print correct stats for preset-normal 1`] = `
"Hash: 437c9384ca68c9e15b6c
"Hash: 3b3a7ec8ed8bc5030c9b
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -2011,7 +2011,7 @@ Entrypoints:
`;
exports[`StatsTestCases should print correct stats for preset-verbose 1`] = `
"Hash: 437c9384ca68c9e15b6c
"Hash: 3b3a7ec8ed8bc5030c9b
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -2024,7 +2024,7 @@ chunk {0} main.js (main) 73 bytes >{1}< >{2}< [entry] [rendered]
> ./index main
[0] ./index.js 51 bytes {0} [depth 0] [built]
ModuleConcatenation bailout: Module is not an ECMAScript module
single entry ./index main
entry ./index main
factory:Xms building:Xms = Xms
[1] ./a.js 22 bytes {0} [depth 1] [built]
ModuleConcatenation bailout: Module is not an ECMAScript module
@ -2055,7 +2055,7 @@ chunk {3} 3.js 44 bytes <{2}> [rendered]
`;
exports[`StatsTestCases should print correct stats for resolve-plugin-context 1`] = `
"Hash: 2e97eaab59275aaa8d93
"Hash: 4ca4f81607549b34ea70
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -2069,7 +2069,7 @@ Entrypoint main = bundle.js
`;
exports[`StatsTestCases should print correct stats for reverse-sort-modules 1`] = `
"Hash: ce942cd1353f7d6fc01e
"Hash: e8b18f1cf5f95cf5a285
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -2139,7 +2139,7 @@ Entrypoint e2 = runtime.js e2.js"
`;
exports[`StatsTestCases should print correct stats for scope-hoisting-bailouts 1`] = `
"Hash: a0a30b6e8932d0227376
"Hash: 6ceacb948e0119070c3d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Entrypoint index = index.js
@ -2170,9 +2170,9 @@ Entrypoint entry = entry.js
`;
exports[`StatsTestCases should print correct stats for scope-hoisting-multi 1`] = `
"Hash: d1e41fb7099e132879ee438a93ced10bfac3b362
"Hash: e170f18d73c88b7b7d9ac46fd70f754a5383c1b7
Child
Hash: d1e41fb7099e132879ee
Hash: e170f18d73c88b7b7d9a
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Entrypoint first = vendor.js first.js
@ -2189,7 +2189,7 @@ Child
[9] ./lazy_shared.js 31 bytes {5} [built]
[10] ./lazy_second.js 55 bytes {4} [built]
Child
Hash: 438a93ced10bfac3b362
Hash: c46fd70f754a5383c1b7
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Entrypoint first = vendor.js first.js
@ -2219,7 +2219,7 @@ Child
`;
exports[`StatsTestCases should print correct stats for side-effects-issue-7428 1`] = `
"Hash: 4f5d38944616c15bd399
"Hash: 8f2bd5e4f61d541b2803
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -2242,7 +2242,7 @@ Entrypoint main = main.js
[3] ./main.js + 1 modules 231 bytes {0} [built]
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
single entry ./main.js main
entry ./main.js main
| ./main.js 144 bytes [built]
| ./components/src/CompAB/CompB.js 77 bytes [built]
| [only some exports used: default]
@ -2267,7 +2267,7 @@ Entrypoint main = main.js
`;
exports[`StatsTestCases should print correct stats for side-effects-simple-unused 1`] = `
"Hash: c7b680da5c0d869389e8
"Hash: 2aad9ba482cb71fcd705
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -2276,7 +2276,7 @@ Entrypoint main = main.js
[0] ./index.js + 2 modules 158 bytes {0} [built]
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
single entry ./index main
entry ./index main
| ./index.js 55 bytes [built]
| ./node_modules/pmodule/index.js 75 bytes [built]
| [only some exports used: default]
@ -2298,7 +2298,7 @@ Entrypoint main = main.js
`;
exports[`StatsTestCases should print correct stats for simple 1`] = `
"Hash: 06cc914b885215f96c5a
"Hash: 0d863bcfaf259a5eba10
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -2308,14 +2308,14 @@ Entrypoint main = bundle.js
`;
exports[`StatsTestCases should print correct stats for simple-more-info 1`] = `
"Hash: c8c226a954f967e61630
"Hash: 64de01465a28fb4267d8
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
bundle.js 3.57 KiB 0 [emitted] main
Entrypoint main = bundle.js
[0] ./index.js 0 bytes {0} [built]
single entry ./index main
entry ./index main
factory:Xms building:Xms = Xms"
`;
@ -2486,17 +2486,17 @@ Child manual:
[6] ./c.js 72 bytes {3} {4} [built]
chunk {5} default/a.js (a) 176 bytes ={7}= >{8}< [entry] [rendered]
> ./a a
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[10] ./a.js + 1 modules 156 bytes {5} {6} [built]
| ./a.js 121 bytes [built]
| ./e.js 20 bytes [built]
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[9] ./a.js + 1 modules 156 bytes {5} {6} [built]
| ./a.js 121 bytes [built]
| ./e.js 20 bytes [built]
chunk {6} default/async-a.js (async-a) 176 bytes <{0}> ={7}= >{8}< [rendered]
> ./a [0] ./index.js 1:0-47
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[10] ./a.js + 1 modules 156 bytes {5} {6} [built]
| ./a.js 121 bytes [built]
| ./e.js 20 bytes [built]
chunk {7} default/vendors.js (vendors) 112 bytes <{0}> ={1}= ={2}= ={3}= ={4}= ={5}= ={6}= >{8}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors)
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[9] ./a.js + 1 modules 156 bytes {5} {6} [built]
| ./a.js 121 bytes [built]
| ./e.js 20 bytes [built]
chunk {7} default/vendors.js (vendors) 60 bytes <{0}> ={1}= ={2}= ={3}= ={4}= ={5}= ={6}= >{8}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors)
> ./a a
> ./b b
> ./c c
@ -2506,12 +2506,11 @@ Child manual:
[2] ./node_modules/x.js 20 bytes {7} [built]
[3] ./node_modules/y.js 20 bytes {7} [built]
[7] ./node_modules/z.js 20 bytes {7} [built]
[8] multi x y z 52 bytes {7} [built]
chunk {8} default/async-g.js (async-g) 54 bytes <{5}> <{6}> <{7}> [rendered]
> ./g [] 6:0-47
> ./g [] 6:0-47
[5] ./f.js 20 bytes {1} {2} {3} {4} {8} [built]
[9] ./g.js 34 bytes {8} [built]
[8] ./g.js 34 bytes {8} [built]
Child name-too-long:
Entrypoint main = main.js
Entrypoint aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = vendors~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~async-a~async-b~async-c~bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb~cccccc~50ebc41f.js vendors~aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~async-a~async-b~bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.js aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa~async-a~async-b~async-c~bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb~cccccccccccccc~18066793.js async-a.js aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.js
@ -2656,12 +2655,12 @@ Child custom-chunks-filter-in-cache-groups:
[0] ./index.js 147 bytes {0} [built]
chunk {1} default/a.js (a) 216 bytes >{8}< [entry] [rendered]
> ./a a
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[2] ./node_modules/x.js 20 bytes {1} {7} [built]
[3] ./node_modules/y.js 20 bytes {1} {7} [built]
[10] ./a.js + 1 modules 156 bytes {1} {6} [built]
| ./a.js 121 bytes [built]
| ./e.js 20 bytes [built]
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[2] ./node_modules/x.js 20 bytes {1} {7} [built]
[3] ./node_modules/y.js 20 bytes {1} {7} [built]
[9] ./a.js + 1 modules 156 bytes {1} {6} [built]
| ./a.js 121 bytes [built]
| ./e.js 20 bytes [built]
chunk {2} default/b.js (b) 112 bytes ={7}= [entry] [rendered]
> ./b b
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
@ -2684,11 +2683,11 @@ Child custom-chunks-filter-in-cache-groups:
[6] ./c.js 72 bytes {4} {5} [built]
chunk {6} default/async-a.js (async-a) 176 bytes <{0}> ={7}= >{8}< [rendered]
> ./a [0] ./index.js 1:0-47
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[10] ./a.js + 1 modules 156 bytes {1} {6} [built]
| ./a.js 121 bytes [built]
| ./e.js 20 bytes [built]
chunk {7} default/vendors.js (vendors) 112 bytes <{0}> ={2}= ={3}= ={4}= ={5}= ={6}= >{8}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors)
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[9] ./a.js + 1 modules 156 bytes {1} {6} [built]
| ./a.js 121 bytes [built]
| ./e.js 20 bytes [built]
chunk {7} default/vendors.js (vendors) 60 bytes <{0}> ={2}= ={3}= ={4}= ={5}= ={6}= >{8}< [initial] [rendered] split chunk (cache group: vendors) (name: vendors)
> ./b b
> ./c c
> ./a [0] ./index.js 1:0-47
@ -2697,12 +2696,11 @@ Child custom-chunks-filter-in-cache-groups:
[2] ./node_modules/x.js 20 bytes {1} {7} [built]
[3] ./node_modules/y.js 20 bytes {1} {7} [built]
[7] ./node_modules/z.js 20 bytes {7} [built]
[8] multi x y z 52 bytes {7} [built]
chunk {8} default/async-g.js (async-g) 54 bytes <{1}> <{6}> <{7}> [rendered]
> ./g [] 6:0-47
> ./g [] 6:0-47
[5] ./f.js 20 bytes {2} {3} {4} {5} {8} [built]
[9] ./g.js 34 bytes {8} [built]"
[8] ./g.js 34 bytes {8} [built]"
`;
exports[`StatsTestCases should print correct stats for split-chunks-automatic-name 1`] = `
@ -3015,7 +3013,7 @@ chunk {4} default/async-c.js (async-c) 48 bytes <{0}> ={2}= [rendered]
`;
exports[`StatsTestCases should print correct stats for tree-shaking 1`] = `
"Hash: 40df5eaa38b35883e99e
"Hash: a66ca410afc2eb29b31d
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -3052,7 +3050,7 @@ Entrypoint main = bundle.js
`;
exports[`StatsTestCases should print correct stats for warnings-uglifyjs 1`] = `
"Hash: ed8a6765253160add1c8
"Hash: 3663bd94f10ad20afb9e
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names

View File

@ -1,6 +1,5 @@
require("./common");
it("should have the correct main flag for multi first module", function() {
var multiModule = __webpack_require__.c[module.parents[0]];
expect(multiModule.hot._main).toBe(true);
expect(module.hot._main).toBe(true);
});

View File

@ -1,6 +1,5 @@
require("./common");
it("should have the correct main flag for multi second module", function() {
var multiModule = __webpack_require__.c[module.parents[0]];
expect(multiModule.hot._main).toBe(true);
expect(module.hot._main).toBe(true);
});

View File

@ -3,6 +3,5 @@ require("./common");
module.exports = "vendor";
it("should have the correct main flag for multi vendor module", function() {
var multiModule = __webpack_require__.c[module.parents[0]];
expect(multiModule.hot._main).toBe(true);
expect(module.hot._main).toBe(true);
});

View File

@ -0,0 +1 @@
// no test here, this will fail when only this entry is loaded

View File

@ -0,0 +1,17 @@
const EntryPlugin = require("../../../../lib/EntryPlugin");
module.exports = {
entry: () => ({}),
optimization: {
runtimeChunk: true
},
output: {
filename: "[name].js",
chunkFilename: "[name].chunk.js"
},
target: "web",
plugins: [
new EntryPlugin(__dirname, "./fail", "main"),
new EntryPlugin(__dirname, "./ok", "main"),
new EntryPlugin(__dirname, "./fail", "main")
]
};

View File

@ -1,3 +0,0 @@
it("should load correct entry", function() {
throw new Error("This entrypoint should not be used");
});

View File

@ -1,16 +0,0 @@
const SingleEntryPlugin = require("../../../../lib/SingleEntryPlugin");
module.exports = {
entry: () => ({}),
optimization: {
runtimeChunk: true
},
output: {
filename: "[name].js",
chunkFilename: "[name].chunk.js"
},
target: "web",
plugins: [
new SingleEntryPlugin(__dirname, "./fail", "main"),
new SingleEntryPlugin(__dirname, "./ok", "main")
]
};

View File

@ -1,9 +1,8 @@
it("Should use WebpackMissingModule when module is missing with multiple entry setup", function() {
var fs = require("fs");
var path = require("path");
var source = fs.readFileSync(path.join(__dirname, "b.js"), "utf-8");
expect(source).toMatch("!(function webpackMissingModule() { var e = new Error(\"Cannot find module './intentionally-missing-module.js'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }());");
it("should ignore missing modules as entries", function() {
// a.js and b.js should be evaulated correctly
});
it("should use WebpackMissingModule when evaluating missing modules", function() {
expect(function() {
require("./intentionally-missing-module");
}).toThrowError("Cannot find module './intentionally-missing-module'");

View File

@ -0,0 +1,9 @@
module.exports = {
findBundle: function() {
return [
"./a.js",
"./b.js",
"./bundle0.js"
]
}
};

View File

@ -1,14 +1,12 @@
const IgnorePlugin = require("../../../../lib/IgnorePlugin");
module.exports = {
entry: {
a: "./intentionally-missing-module.js",
b: ["./intentionally-missing-module.js"],
bundle0: ["./index"]
},
output: {
filename: "[name].js"
},
plugins: [new IgnorePlugin(new RegExp(/intentionally-missing-module/))],
node: {
__dirname: false
}
plugins: [new IgnorePlugin(new RegExp(/intentionally-missing-module/))]
};

View File

@ -1,6 +1,6 @@
"use strict";
var SingleEntryPlugin = require("../../../lib/SingleEntryPlugin");
var EntryPlugin = require("../../../lib/EntryPlugin");
/**
* Runs a child compilation which produces an error in order to test that NoEmitErrorsPlugin
@ -18,7 +18,7 @@ module.exports = class TestChildCompilationFailurePlugin {
child.hooks.compilation.tap("TestChildCompilationFailurePlugin", childCompilation => {
childCompilation.errors.push(new Error("forced error"));
});
new SingleEntryPlugin(compiler.options.context, compiler.options.entry, "child").apply(child);
new EntryPlugin(compiler.options.context, compiler.options.entry, "child").apply(child);
child.runAsChild(cb);
});
}