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; this.name = name;
/** @type {boolean} */ /** @type {boolean} */
this.preventIntegration = false; this.preventIntegration = false;
/** @type {Module=} */
this.entryModule = undefined;
/** @type {string?} */ /** @type {string?} */
this.filenameTemplate = undefined; this.filenameTemplate = undefined;
/** @private @type {SortableSet<ChunkGroup>} */ /** @private @type {SortableSet<ChunkGroup>} */
@ -125,13 +123,6 @@ class Chunk {
return true; 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 * @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 * @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() { get groupsIterable() {
return this._groups; return this._groups;
@ -209,40 +200,14 @@ class Chunk {
)) { )) {
hash.update(m.hash); hash.update(m.hash);
} }
} const entryModules = chunkGraph.getChunkEntryModulesWithChunkGroupIterable(
this
canBeIntegrated(otherChunk) { );
const isAvailable = (a, b) => { for (const [m, chunkGroup] of entryModules) {
const queue = new Set(b.groupsIterable); hash.update("entry");
for (const chunkGroup of queue) { hash.update(m.hash);
if (a.isInGroup(chunkGroup)) continue; hash.update(chunkGroup.id);
if (chunkGroup.isInitial()) return false;
for (const parent of chunkGroup.parentsIterable) {
queue.add(parent);
}
}
return true;
};
if (this.preventIntegration || otherChunk.preventIntegration) {
return false;
} }
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 * @returns {ChunkMaps} the chunk map information
*/ */
getChunkMaps(realHash) { getChunkMaps(realHash) {

View File

@ -70,6 +70,8 @@ class ChunkGraphModule {
constructor() { constructor() {
/** @type {SortableSet<Chunk>} */ /** @type {SortableSet<Chunk>} */
this.chunks = new SortableSet(); this.chunks = new SortableSet();
/** @type {Set<Chunk>} */
this.entryInChunks = new Set();
} }
} }
@ -77,6 +79,8 @@ class ChunkGraphChunk {
constructor() { constructor() {
/** @type {SortableSet<Module>} */ /** @type {SortableSet<Module>} */
this.modules = new SortableSet(); this.modules = new SortableSet();
/** @type {Map<Module, ChunkGroup>} */
this.entryModules = new Map();
} }
} }
@ -177,14 +181,30 @@ class ChunkGraph {
replaceModule(oldModule, newModule) { replaceModule(oldModule, newModule) {
const oldCgm = this._getChunkGraphModule(oldModule); const oldCgm = this._getChunkGraphModule(oldModule);
const newCgm = this._getChunkGraphModule(newModule); 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); const cgc = this._getChunkGraphChunk(chunk);
cgc.modules.delete(oldModule); cgc.modules.delete(oldModule);
cgc.modules.add(newModule); cgc.modules.add(newModule);
oldCgm.chunks.delete(chunk);
newCgm.chunks.add(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) { isEntryModule(module) {
const cgm = this._getChunkGraphModule(module); const cgm = this._getChunkGraphModule(module);
for (const chunk of cgm.chunks) { return cgm.entryInChunks.size > 0;
if (chunk.entryModule === module) return true;
}
return false;
} }
/** /**
@ -501,7 +518,45 @@ class ChunkGraph {
* @returns {boolean} true, if chunks could be integrated * @returns {boolean} true, if chunks could be integrated
*/ */
canChunksBeIntegrated(chunkA, chunkB) { 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; module.exports = ChunkGraph;

View File

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

View File

@ -14,16 +14,8 @@ const { SyncWaterfallHook, SyncHook } = require("tapable");
/** @typedef {import("./DependencyTemplates")} DependencyTemplates} */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates} */
/** @typedef {import("webpack-sources").Source} Source} */ /** @typedef {import("webpack-sources").Source} Source} */
/** @typedef {import("./ModuleTemplate").RenderContext} RenderContext} */ /** @typedef {import("./ModuleTemplate").RenderContext} RenderContext} */
/** @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
*/
module.exports = class ChunkTemplate { module.exports = class ChunkTemplate {
constructor(outputOptions) { constructor(outputOptions) {
@ -52,7 +44,7 @@ module.exports = class ChunkTemplate {
/** /**
* *
* @param {RenderManifestOptions} options render manifest options * @param {RenderManifestOptions} options render manifest options
* @returns {TODO[]} returns render manifest * @returns {RenderManifestEntry[]} returns render manifest
*/ */
getRenderManifest(options) { getRenderManifest(options) {
const result = []; const result = [];

View File

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

View File

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

View File

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

View File

@ -6,24 +6,10 @@
"use strict"; "use strict";
const DynamicEntryPlugin = require("./DynamicEntryPlugin"); const DynamicEntryPlugin = require("./DynamicEntryPlugin");
const MultiEntryPlugin = require("./MultiEntryPlugin"); const EntryPlugin = require("./EntryPlugin");
const SingleEntryPlugin = require("./SingleEntryPlugin");
/** @typedef {import("./Compiler")} Compiler */ /** @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 { module.exports = class EntryOptionPlugin {
/** /**
* @param {Compiler} compiler the compiler instance one is tapping into * @param {Compiler} compiler the compiler instance one is tapping into
@ -31,11 +17,26 @@ module.exports = class EntryOptionPlugin {
*/ */
apply(compiler) { apply(compiler) {
compiler.hooks.entryOption.tap("EntryOptionPlugin", (context, entry) => { 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)) { if (typeof entry === "string" || Array.isArray(entry)) {
itemToPlugin(context, entry, "main").apply(compiler); applyEntryPlugins(entry, "main");
} else if (typeof entry === "object") { } else if (typeof entry === "object") {
for (const name of Object.keys(entry)) { for (const name of Object.keys(entry)) {
itemToPlugin(context, entry[name], name).apply(compiler); applyEntryPlugins(entry[name], name);
} }
} else if (typeof entry === "function") { } else if (typeof entry === "function") {
new DynamicEntryPlugin(context, entry).apply(compiler); new DynamicEntryPlugin(context, entry).apply(compiler);

View File

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

View File

@ -13,6 +13,8 @@ const NullFactory = require("./NullFactory");
const Template = require("./Template"); const Template = require("./Template");
const ConstDependency = require("./dependencies/ConstDependency"); const ConstDependency = require("./dependencies/ConstDependency");
/** @typedef {import("./Compiler")} Compiler */
const REPLACEMENTS = { const REPLACEMENTS = {
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
__webpack_hash__: "__webpack_require__.h", __webpack_hash__: "__webpack_require__.h",
@ -27,6 +29,10 @@ const REPLACEMENT_TYPES = {
}; };
class ExtendedAPIPlugin { class ExtendedAPIPlugin {
/**
* @param {Compiler} compiler webpack compiler
* @returns {void}
*/
apply(compiler) { apply(compiler) {
compiler.hooks.compilation.tap( compiler.hooks.compilation.tap(
"ExtendedAPIPlugin", "ExtendedAPIPlugin",
@ -40,7 +46,7 @@ class ExtendedAPIPlugin {
const mainTemplate = compilation.mainTemplate; const mainTemplate = compilation.mainTemplate;
mainTemplate.hooks.requireExtensions.tap( mainTemplate.hooks.requireExtensions.tap(
"ExtendedAPIPlugin", "ExtendedAPIPlugin",
(source, chunk, hash) => { (source, { chunk, hash }) => {
const buf = [source]; const buf = [source];
buf.push(""); buf.push("");
buf.push("// __webpack_hash__"); 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 {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 * @returns {boolean} true, if the chunk is ok for the module
*/ */
chunkCondition(chunk) { chunkCondition(chunk, { chunkGraph }) {
return chunk.hasEntryModule(); return chunkGraph.getNumberOfEntryModules(chunk) > 0;
} }
/** /**

View File

@ -120,9 +120,13 @@ class FlagDependencyUsagePlugin {
/** @type {[Module, DependenciesBlock, UsedExports][]} */ /** @type {[Module, DependenciesBlock, UsedExports][]} */
const queue = []; const queue = [];
for (const preparedEntrypoint of compilation._preparedEntrypoints) { for (const [, deps] of compilation.entryDependencies) {
if (preparedEntrypoint.module) { const lastDependency = deps[deps.length - 1];
processModule(preparedEntrypoint.module, true); 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( mainTemplate.hooks.bootstrap.tap(
"HotModuleReplacementPlugin", "HotModuleReplacementPlugin",
(source, chunk, hash) => { (source, moduleTemplate, { chunk, hash }) => {
source = mainTemplate.hooks.hotBootstrap.call(source, chunk, hash); source = mainTemplate.hooks.hotBootstrap.call(source, chunk, hash);
return Template.asString([ return Template.asString([
source, source,
@ -417,7 +417,7 @@ module.exports = class HotModuleReplacementPlugin {
mainTemplate.hooks.moduleObj.tap( mainTemplate.hooks.moduleObj.tap(
"HotModuleReplacementPlugin", "HotModuleReplacementPlugin",
(source, chunk, hash, varModuleId) => { (source, varModuleId) => {
return Template.asString([ return Template.asString([
`${source},`, `${source},`,
`hot: hotCreateModule(${varModuleId}),`, `hot: hotCreateModule(${varModuleId}),`,

View File

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

View File

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

View File

@ -21,15 +21,21 @@ const Template = require("./Template");
/** @typedef {import("./Module")} Module} */ /** @typedef {import("./Module")} Module} */
/** @typedef {import("./util/createHash").Hash} Hash} */ /** @typedef {import("./util/createHash").Hash} Hash} */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates} */ /** @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 * @typedef {Object} MainRenderContext
* @property {Chunk} chunk the chunk used to render * @property {Chunk} chunk the chunk
* @property {string} hash * @property {DependencyTemplates} dependencyTemplates the dependency templates
* @property {string} fullHash * @property {RuntimeTemplate} runtimeTemplate the runtime template
* @property {TODO} outputOptions * @property {ModuleGraph} moduleGraph the module graph
* @property {{javascript: ModuleTemplate, webassembly: ModuleTemplate}} moduleTemplates * @property {ChunkGraph} chunkGraph the chunk graph
* @property {DependencyTemplates} dependencyTemplates * @property {string} hash hash to be used for render call
*/ */
// require function shortcuts: // require function shortcuts:
@ -60,45 +66,44 @@ module.exports = class MainTemplate {
this.hooks = Object.freeze({ this.hooks = Object.freeze({
/** @type {SyncWaterfallHook<TODO[], RenderManifestOptions>} */ /** @type {SyncWaterfallHook<TODO[], RenderManifestOptions>} */
renderManifest: new SyncWaterfallHook(["result", "options"]), renderManifest: new SyncWaterfallHook(["result", "options"]),
/** @type {SyncWaterfallHook<Source, ModuleTemplate, MainRenderContext>} */
modules: new SyncWaterfallHook([ modules: new SyncWaterfallHook([
"modules", "source",
"chunk",
"hash",
"moduleTemplate", "moduleTemplate",
"dependencyTemplates" "renderContext"
]), ]),
/** @type {SyncWaterfallHook<string, string, MainRenderContext>} */
moduleObj: new SyncWaterfallHook([ moduleObj: new SyncWaterfallHook([
"source", "source",
"chunk", "moduleIdExpression",
"hash", "renderContext"
"moduleIdExpression"
]), ]),
/** @type {SyncWaterfallHook<string, string, MainRenderContext>} */
requireEnsure: new SyncWaterfallHook([ requireEnsure: new SyncWaterfallHook([
"source", "source",
"chunk", "chunkIdExpression",
"hash", "renderContext"
"chunkIdExpression"
]), ]),
/** @type {SyncWaterfallHook<string, ModuleTemplate, MainRenderContext>} */
bootstrap: new SyncWaterfallHook([ bootstrap: new SyncWaterfallHook([
"source", "source",
"chunk",
"hash",
"moduleTemplate", "moduleTemplate",
"dependencyTemplates" "renderContext"
]), ]),
localVars: new SyncWaterfallHook(["source", "chunk", "hash"]), localVars: new SyncWaterfallHook(["source", "chunk", "hash"]),
require: new SyncWaterfallHook(["source", "chunk", "hash"]), /** @type {SyncWaterfallHook<string, MainRenderContext>} */
requireExtensions: new SyncWaterfallHook(["source", "chunk", "hash"]), require: new SyncWaterfallHook(["source", "renderContext"]),
/** @type {SyncWaterfallHook<string, MainRenderContext>} */
requireExtensions: new SyncWaterfallHook(["source", "renderContext"]),
/** @type {SyncWaterfallHook<string, Chunk, string>} */ /** @type {SyncWaterfallHook<string, Chunk, string>} */
beforeStartup: new SyncWaterfallHook(["source", "chunk", "hash"]), beforeStartup: new SyncWaterfallHook(["source", "chunk", "hash"]),
/** @type {SyncWaterfallHook<string, Chunk, string>} */ /** @type {SyncWaterfallHook<string, MainRenderContext>} */
startup: new SyncWaterfallHook(["source", "chunk", "hash"]), startup: new SyncWaterfallHook(["source", "renderContext"]),
/** @type {SyncWaterfallHook<Source, ModuleTemplate, MainRenderContext>} */
render: new SyncWaterfallHook([ render: new SyncWaterfallHook([
"source", "source",
"chunk",
"hash",
"moduleTemplate", "moduleTemplate",
"dependencyTemplates" "renderContext"
]), ]),
renderWithEntry: new SyncWaterfallHook(["source", "chunk", "hash"]), renderWithEntry: new SyncWaterfallHook(["source", "chunk", "hash"]),
moduleRequire: new SyncWaterfallHook([ moduleRequire: new SyncWaterfallHook([
@ -107,12 +112,11 @@ module.exports = class MainTemplate {
"hash", "hash",
"moduleIdExpression" "moduleIdExpression"
]), ]),
/** @type {SyncWaterfallHook<string, {moduleId: string, module: string}, MainRenderContext>} */
addModule: new SyncWaterfallHook([ addModule: new SyncWaterfallHook([
"source", "source",
"chunk", "expressions",
"hash", "renderContext"
"moduleIdExpression",
"moduleExpression"
]), ]),
currentHash: new SyncWaterfallHook(["source", "requestedLength"]), currentHash: new SyncWaterfallHook(["source", "requestedLength"]),
assetPath: new SyncWaterfallHook(["path", "options"]), assetPath: new SyncWaterfallHook(["path", "options"]),
@ -125,24 +129,33 @@ module.exports = class MainTemplate {
// It's weird here // It's weird here
hotBootstrap: new SyncWaterfallHook(["source", "chunk", "hash"]) hotBootstrap: new SyncWaterfallHook(["source", "chunk", "hash"])
}); });
this.hooks.startup.tap("MainTemplate", (source, chunk, hash) => { this.hooks.startup.tap(
/** @type {string[]} */ "MainTemplate",
const buf = []; (source, { chunk, hash, chunkGraph }) => {
if (chunk.entryModule) { /** @type {string[]} */
buf.push("// Load entry module and return exports"); const buf = [];
buf.push( if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
`return ${this.renderRequireFunctionForModule( buf.push("// Load entry module and return exports");
hash, let i = chunkGraph.getNumberOfEntryModules(chunk);
chunk, for (const entryModule of chunkGraph.getChunkEntryModulesIterable(
JSON.stringify(chunk.entryModule.id) chunk
)}(${this.requireFn}.s = ${JSON.stringify(chunk.entryModule.id)});` )) {
); 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( this.hooks.render.tap(
"MainTemplate", "MainTemplate",
(bootstrapSource, chunk, hash, moduleTemplate, dependencyTemplates) => { (bootstrapSource, moduleTemplate, renderContext) => {
const source = new ConcatSource(); const source = new ConcatSource();
source.add("/******/ (function(modules) { // webpackBootstrap\n"); source.add("/******/ (function(modules) { // webpackBootstrap\n");
source.add(new PrefixSource("/******/", bootstrapSource)); source.add(new PrefixSource("/******/", bootstrapSource));
@ -154,10 +167,8 @@ module.exports = class MainTemplate {
source.add( source.add(
this.hooks.modules.call( this.hooks.modules.call(
new RawSource(""), new RawSource(""),
chunk,
hash,
moduleTemplate, moduleTemplate,
dependencyTemplates renderContext
) )
); );
source.add(")"); source.add(")");
@ -171,7 +182,8 @@ module.exports = class MainTemplate {
"var installedModules = {};" "var installedModules = {};"
]); ]);
}); });
this.hooks.require.tap("MainTemplate", (source, chunk, hash) => { this.hooks.require.tap("MainTemplate", (source, renderContext) => {
const { chunk, hash } = renderContext;
return Template.asString([ return Template.asString([
source, source,
"// Check if module is in cache", "// Check if module is in cache",
@ -180,7 +192,9 @@ module.exports = class MainTemplate {
"}", "}",
"// Create a new module (and put it into the cache)", "// Create a new module (and put it into the cache)",
"var module = installedModules[moduleId] = {", "var module = installedModules[moduleId] = {",
Template.indent(this.hooks.moduleObj.call("", chunk, hash, "moduleId")), Template.indent(
this.hooks.moduleObj.call("", "moduleId", renderContext)
),
"};", "};",
"", "",
Template.asString( Template.asString(
@ -220,124 +234,125 @@ module.exports = class MainTemplate {
"return module.exports;" "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", "MainTemplate",
(source, chunk, hash, varModuleId) => { (source, renderContext) => {
return Template.asString(["i: moduleId,", "l: false,", "exports: {}"]); 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__"; this.requireFn = "__webpack_require__";
} }
@ -345,7 +360,7 @@ module.exports = class MainTemplate {
/** /**
* *
* @param {RenderManifestOptions} options render manifest options * @param {RenderManifestOptions} options render manifest options
* @returns {TODO[]} returns render manifest * @returns {RenderManifestEntry[]} returns render manifest
*/ */
getRenderManifest(options) { getRenderManifest(options) {
const result = []; 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 {ModuleTemplate} moduleTemplate ModuleTemplate instance for render
* @param {DependencyTemplates} dependencyTemplates dependency templates * @param {MainRenderContext} renderContext options object
* @returns {ConcatSource} the newly generated source from rendering * @returns {ConcatSource} the newly generated source from rendering
*/ */
render(hash, chunk, moduleTemplate, dependencyTemplates) { render(moduleTemplate, renderContext) {
const { hash, chunk, chunkGraph } = renderContext;
const buf = []; const buf = [];
buf.push( buf.push(this.hooks.bootstrap.call("", moduleTemplate, renderContext));
this.hooks.bootstrap.call(
"",
chunk,
hash,
moduleTemplate,
dependencyTemplates
)
);
buf.push(this.hooks.localVars.call("", chunk, hash)); buf.push(this.hooks.localVars.call("", chunk, hash));
buf.push(""); buf.push("");
buf.push("// The require function"); buf.push("// The require function");
buf.push(`function ${this.requireFn}(moduleId) {`); 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(""); 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("");
buf.push(Template.asString(this.hooks.beforeStartup.call("", chunk, hash))); 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( let source = this.hooks.render.call(
new OriginalSource( new OriginalSource(
Template.prefix(buf, " \t") + "\n", Template.prefix(buf, " \t") + "\n",
"webpack/bootstrap" "webpack/bootstrap"
), ),
chunk,
hash,
moduleTemplate, moduleTemplate,
dependencyTemplates renderContext
); );
if (chunk.hasEntryModule()) { if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
source = this.hooks.renderWithEntry.call(source, chunk, hash); source = this.hooks.renderWithEntry.call(source, chunk, hash);
} }
if (!source) { if (!source) {
@ -427,19 +430,19 @@ module.exports = class MainTemplate {
/** /**
* *
* @param {string} hash hash for render add fn * @param {string} varModuleId module id
* @param {Chunk} chunk Chunk instance for require add fn * @param {string} varModule Module instance
* @param {(string|number)=} varModuleId module id * @param {MainRenderContext} renderContext the render context
* @param {Module} varModule Module instance
* @returns {TODO} renderAddModule call * @returns {TODO} renderAddModule call
*/ */
renderAddModule(hash, chunk, varModuleId, varModule) { renderAddModule(varModuleId, varModule, renderContext) {
return this.hooks.addModule.call( return this.hooks.addModule.call(
`modules[${varModuleId}] = ${varModule};`, `modules[${varModuleId}] = ${varModule};`,
chunk, {
hash, moduleId: varModuleId,
varModuleId, module: varModule
varModule },
renderContext
); );
} }

View File

@ -477,9 +477,10 @@ class Module extends DependenciesBlock {
/** /**
* @param {Chunk} chunk the chunk which condition should be checked * @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 * @returns {boolean} true, if the chunk is ok for the module
*/ */
chunkCondition(chunk) { chunkCondition(chunk, compilation) {
return true; 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").ConcatSource} ConcatSource */
/** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("./Chunk")} Chunk */ /** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */ /** @typedef {import("./DependencyTemplates")} DependencyTemplates */
/** @typedef {import("./Module")} Module */ /** @typedef {import("./Module")} Module */
/** @typedef {import("./ModuleGraph")} ModuleGraph */ /** @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 PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-zA-Z0-9_!§$()=\-^°]+/g;
const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/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 * @typedef {Object} HasId
* @property {number | string} id * @property {number | string} id

View File

@ -7,7 +7,7 @@
const ModuleDependency = require("./ModuleDependency"); const ModuleDependency = require("./ModuleDependency");
class SingleEntryDependency extends ModuleDependency { class EntryDependency extends ModuleDependency {
/** /**
* @param {string} request request path for entry * @param {string} request request path for entry
*/ */
@ -16,8 +16,8 @@ class SingleEntryDependency extends ModuleDependency {
} }
get type() { 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"); const Template = require("../Template");
/** @typedef {import("../MainTemplate")} MainTemplate */
module.exports = class NodeMainTemplatePlugin { module.exports = class NodeMainTemplatePlugin {
constructor(asyncChunkLoading) { constructor(asyncChunkLoading) {
this.asyncChunkLoading = asyncChunkLoading; this.asyncChunkLoading = asyncChunkLoading;
} }
/**
* @param {MainTemplate} mainTemplate the main template
* @returns {void}
*/
apply(mainTemplate) { apply(mainTemplate) {
const needChunkOnDemandLoadingCode = chunk => { const needChunkOnDemandLoadingCode = chunk => {
for (const chunkGroup of chunk.groupsIterable) { for (const chunkGroup of chunk.groupsIterable) {
@ -41,7 +47,7 @@ module.exports = class NodeMainTemplatePlugin {
); );
mainTemplate.hooks.requireExtensions.tap( mainTemplate.hooks.requireExtensions.tap(
"NodeMainTemplatePlugin", "NodeMainTemplatePlugin",
(source, chunk) => { (source, { chunk }) => {
if (needChunkOnDemandLoadingCode(chunk)) { if (needChunkOnDemandLoadingCode(chunk)) {
return Template.asString([ return Template.asString([
source, source,
@ -63,7 +69,9 @@ module.exports = class NodeMainTemplatePlugin {
); );
mainTemplate.hooks.requireEnsure.tap( mainTemplate.hooks.requireEnsure.tap(
"NodeMainTemplatePlugin", "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 chunkFilename = mainTemplate.outputOptions.chunkFilename;
const chunkMaps = chunk.getChunkMaps(); const chunkMaps = chunk.getChunkMaps();
const insertMoreModules = [ const insertMoreModules = [
@ -71,10 +79,9 @@ module.exports = class NodeMainTemplatePlugin {
"for(var moduleId in moreModules) {", "for(var moduleId in moreModules) {",
Template.indent( Template.indent(
mainTemplate.renderAddModule( mainTemplate.renderAddModule(
hash,
chunk,
"moduleId", "moduleId",
"moreModules[moduleId]" "moreModules[moduleId]",
renderContext
) )
), ),
"}" "}"

View File

@ -12,7 +12,9 @@ const { compareModulesById } = require("../util/comparators");
const identifierUtils = require("../util/identifier"); const identifierUtils = require("../util/identifier");
/** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
const moveModuleBetween = (chunkGraph, oldChunk, newChunk) => { const moveModuleBetween = (chunkGraph, oldChunk, newChunk) => {
return module => { 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 module => {
return entryModule !== module; return !chunkGraph.isEntryModuleInChunk(module, chunk);
}; };
}; };
@ -217,7 +224,7 @@ class AggressiveSplittingPlugin {
) { ) {
const modules = chunkGraph const modules = chunkGraph
.getChunkModules(chunk) .getChunkModules(chunk)
.filter(isNotAEntryModule(chunk.entryModule)) .filter(isNotAEntryModule(chunkGraph, chunk))
.sort((a, b) => { .sort((a, b) => {
const aIdentifer = a.identifier(); const aIdentifer = a.identifier();
const bIdentifer = b.identifier(); const bIdentifer = b.identifier();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,17 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`StatsTestCases should print correct stats for aggressive-splitting-entry 1`] = ` exports[`StatsTestCases should print correct stats for aggressive-splitting-entry 1`] = `
"Hash: 44a278e3b0741b9b5da644a278e3b0741b9b5da6 "Hash: 5071403fab92cdd591e25071403fab92cdd591e2
Child fitting: Child fitting:
Hash: 44a278e3b0741b9b5da6 Hash: 5071403fab92cdd591e2
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
d4b551c6319035df2898.js 1.05 KiB 0 [emitted] d4b551c6319035df2898.js 1.05 KiB 0 [emitted]
7029d2a129d88406bdea.js 1.94 KiB 1 [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] 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}> chunk {0} d4b551c6319035df2898.js 916 bytes <{1}> <{2}> <{3}>
> ./g [4] ./index.js 7:0-13 > ./g [4] ./index.js 7:0-13
[7] ./g.js 916 bytes {0} [built] [7] ./g.js 916 bytes {0} [built]
@ -19,7 +19,7 @@ Child fitting:
> ./index main > ./index main
[1] ./c.js 899 bytes {1} [built] [1] ./c.js 899 bytes {1} [built]
[2] ./d.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 > ./index main
[3] ./e.js 899 bytes {2} [built] [3] ./e.js 899 bytes {2} [built]
[4] ./index.js 111 bytes {2} [built] [4] ./index.js 111 bytes {2} [built]
@ -29,15 +29,15 @@ Child fitting:
[0] ./b.js 899 bytes {3} [built] [0] ./b.js 899 bytes {3} [built]
[5] ./a.js 899 bytes {3} [built] [5] ./a.js 899 bytes {3} [built]
Child content-change: Child content-change:
Hash: 44a278e3b0741b9b5da6 Hash: 5071403fab92cdd591e2
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
d4b551c6319035df2898.js 1.05 KiB 0 [emitted] d4b551c6319035df2898.js 1.05 KiB 0 [emitted]
7029d2a129d88406bdea.js 1.94 KiB 1 [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] 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}> chunk {0} d4b551c6319035df2898.js 916 bytes <{1}> <{2}> <{3}>
> ./g [4] ./index.js 7:0-13 > ./g [4] ./index.js 7:0-13
[7] ./g.js 916 bytes {0} [built] [7] ./g.js 916 bytes {0} [built]
@ -45,7 +45,7 @@ Child content-change:
> ./index main > ./index main
[1] ./c.js 899 bytes {1} [built] [1] ./c.js 899 bytes {1} [built]
[2] ./d.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 > ./index main
[3] ./e.js 899 bytes {2} [built] [3] ./e.js 899 bytes {2} [built]
[4] ./index.js 111 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`] = ` exports[`StatsTestCases should print correct stats for aggressive-splitting-on-demand 1`] = `
"Hash: 02a058acce1bfbcd9896 "Hash: 9418f05bd974463160e9
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -71,9 +71,9 @@ c99c160aba2d9a94e5d1.js 1.94 KiB 5 [emitted]
6a8e74d82c35e3f013d2.js 1 KiB 7 [emitted] 6a8e74d82c35e3f013d2.js 1 KiB 7 [emitted]
ee043b525cd899e33ec0.js 1.94 KiB 8 [emitted] ee043b525cd899e33ec0.js 1.94 KiB 8 [emitted]
01a8254701931adbf278.js 1.01 KiB 9 [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] 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 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 [11] ./index.js 5:0-44
> ./b ./d ./e ./f ./g ./h ./i ./j ./k [11] ./index.js 6:0-72 > ./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}> chunk {9} 01a8254701931adbf278.js 899 bytes <{10}>
> ./a [11] ./index.js 1:0-16 > ./a [11] ./index.js 1:0-16
[10] ./a.js 899 bytes {9} [built] [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 > ./index main
[11] ./index.js 248 bytes {10} [built] [11] ./index.js 248 bytes {10} [built]
chunk {11} ba9fedb7aa0c69201639.js 1.76 KiB <{10}> ={2}= ={6}= [rendered] [recorded] aggressive splitted 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`] = ` exports[`StatsTestCases should print correct stats for chunk-module-id-range 1`] = `
"Hash: 8683bda4416097d173ee "Hash: 04aadacf6417d157d7a8
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for chunks 1`] = `
"Hash: bb90fc9e61205a066fee "Hash: 9557124dd322802a4580
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -504,7 +504,7 @@ Entrypoint main = bundle.js
chunk {0} bundle.js (main) 73 bytes >{1}< >{2}< [entry] [rendered] chunk {0} bundle.js (main) 73 bytes >{1}< >{2}< [entry] [rendered]
> ./index main > ./index main
[0] ./index.js 51 bytes {0} [built] [0] ./index.js 51 bytes {0} [built]
single entry ./index main entry ./index main
factory:Xms building:Xms = Xms factory:Xms building:Xms = Xms
[1] ./a.js 22 bytes {0} [built] [1] ./a.js 22 bytes {0} [built]
cjs require ./a [0] ./index.js 1:0-14 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`] = ` exports[`StatsTestCases should print correct stats for chunks-development 1`] = `
"Hash: 83bf92a94bc3834801e8 "Hash: b66c6464f88d39a97070
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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 cjs require ./a [./index.js] 1:0-14
[./index.js] Xms -> factory:Xms building:Xms = Xms [./index.js] Xms -> factory:Xms building:Xms = Xms
[./index.js] 51 bytes {main} [built] [./index.js] 51 bytes {main} [built]
single entry ./index main entry ./index main
factory:Xms building:Xms = Xms" 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`] = ` exports[`StatsTestCases should print correct stats for color-disabled 1`] = `
"Hash: c5ad40363e9aee54c089 "Hash: 703cfa0463cb3c00055c
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 <CLR=BOLD>00:00:00</CLR> GMT Built at: Thu Jan 01 1970 <CLR=BOLD>00:00:00</CLR> GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -591,7 +591,7 @@ Entrypoint main = main.js
`; `;
exports[`StatsTestCases should print correct stats for color-enabled 1`] = ` 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 Time: <CLR=BOLD>X</CLR>ms
Built at: Thu Jan 01 1970 <CLR=BOLD>00:00:00</CLR> GMT 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> <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`] = ` 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 Time: <CLR=BOLD>X</CLR>ms
Built at: Thu Jan 01 1970 <CLR=BOLD>00:00:00</CLR> GMT 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> <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`] = ` exports[`StatsTestCases should print correct stats for commons-chunk-min-size-0 1`] = `
"Hash: 54d4e5458e5d48cb25ea "Hash: 35dc5b4d12d551e4af91
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for commons-chunk-min-size-Infinity 1`] = `
"Hash: 275af2436329c6c382a9 "Hash: 5dd30065e34a02ecc6a8
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for commons-plugin-issue-4980 1`] = `
"Hash: 137d627ba070d33cdda49a001f783027b840be9c "Hash: 35f4c0b458700e5690125d578fbbda31da1fdadb
Child Child
Hash: 137d627ba070d33cdda4 Hash: 35f4c0b458700e569012
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -660,7 +660,7 @@ Child
| ./submodule-a.js 59 bytes [built] | ./submodule-a.js 59 bytes [built]
| ./submodule-b.js 59 bytes [built] | ./submodule-b.js 59 bytes [built]
Child Child
Hash: 9a001f783027b840be9c Hash: 5d578fbbda31da1fdadb
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for define-plugin 1`] = `
"Hash: cfe08d4450db77f81610f4228fcb997ec81e2aa6bb43e7d151657ea2b793 "Hash: d137985c3dc6e1d36484ae900f5ab7a1699250503bca3a1a2ed59b322b45
Child Child
Hash: cfe08d4450db77f81610 Hash: d137985c3dc6e1d36484
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -702,7 +702,7 @@ Child
Entrypoint main = main.js Entrypoint main = main.js
[0] ./index.js 24 bytes {0} [built] [0] ./index.js 24 bytes {0} [built]
Child Child
Hash: f4228fcb997ec81e2aa6 Hash: ae900f5ab7a169925050
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -710,7 +710,7 @@ Child
Entrypoint main = main.js Entrypoint main = main.js
[0] ./index.js 24 bytes {0} [built] [0] ./index.js 24 bytes {0} [built]
Child Child
Hash: bb43e7d151657ea2b793 Hash: 3bca3a1a2ed59b322b45
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -720,7 +720,7 @@ Child
`; `;
exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624 1`] = ` exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624 1`] = `
"Hash: 29b62432962bce4c54c0 "Hash: b103d43f856eb3a1c997
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624-error 1`] = `
"Hash: 701dcf62b26d0347b899 "Hash: 4a2b1eec4a4806b9dc12
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for exclude-with-loader 1`] = `
"Hash: 52eadc5de721f000106b "Hash: 83fac664b3322d053bd8
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -756,7 +756,7 @@ Entrypoint main = bundle.js
`; `;
exports[`StatsTestCases should print correct stats for external 1`] = ` exports[`StatsTestCases should print correct stats for external 1`] = `
"Hash: 7a4bb5500ee0eddeee44 "Hash: dbb8d2da46449d2bfe85
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -767,9 +767,9 @@ Entrypoint main = main.js
`; `;
exports[`StatsTestCases should print correct stats for filter-warnings 1`] = ` exports[`StatsTestCases should print correct stats for filter-warnings 1`] = `
"Hash: 0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed0f57e2bad314fb37b8ed "Hash: 88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d88aed3fe1afcb496898d
Child undefined: Child undefined:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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 WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child UglifyJs: Child UglifyJs:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js Entrypoint main = bundle.js
Child /UglifyJs/: Child /UglifyJs/:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js Entrypoint main = bundle.js
Child warnings => true: Child warnings => true:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js Entrypoint main = bundle.js
Child [UglifyJs]: Child [UglifyJs]:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js Entrypoint main = bundle.js
Child [/UglifyJs/]: Child [/UglifyJs/]:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js Entrypoint main = bundle.js
Child [warnings => true]: Child [warnings => true]:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
bundle.js 2.84 KiB 0 [emitted] main bundle.js 2.84 KiB 0 [emitted] main
Entrypoint main = bundle.js Entrypoint main = bundle.js
Child should not filter: Child should not filter:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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 WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child /should not filter/: Child /should not filter/:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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 WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child warnings => false: Child warnings => false:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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 WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child [should not filter]: Child [should not filter]:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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 WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child [/should not filter/]: Child [/should not filter/]:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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 WARNING in UglifyJs Plugin: Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] in bundle.js
Child [warnings => false]: Child [warnings => false]:
Hash: 0f57e2bad314fb37b8ed Hash: 88aed3fe1afcb496898d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1020,10 +1020,10 @@ exports[`StatsTestCases should print correct stats for graph-correctness-entries
Entrypoint e2 = e2.js Entrypoint e2 = e2.js
chunk {0} e1.js (e1) 49 bytes >{2}< [entry] [rendered] chunk {0} e1.js (e1) 49 bytes >{2}< [entry] [rendered]
[0] ./e1.js 49 bytes {0} [built] [0] ./e1.js 49 bytes {0} [built]
single entry ./e1 e1 entry ./e1 e1
chunk {1} e2.js (e2) 49 bytes >{3}< [entry] [rendered] chunk {1} e2.js (e2) 49 bytes >{3}< [entry] [rendered]
[1] ./e2.js 49 bytes {1} [built] [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] chunk {2} a.js (a) 49 bytes <{0}> <{3}> >{4}< [rendered]
[2] ./module-a.js 49 bytes {2} [built] [2] ./module-a.js 49 bytes {2} [built]
import() ./module-a [0] ./e1.js 1:0-47 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 Entrypoint e2 = e2.js
chunk {0} e1.js (e1) 119 bytes >{2}< >{3}< [entry] [rendered] chunk {0} e1.js (e1) 119 bytes >{2}< >{3}< [entry] [rendered]
[0] ./e1.js 70 bytes {0} [built] [0] ./e1.js 70 bytes {0} [built]
single entry ./e1 e1 entry ./e1 e1
[1] ./module-x.js 49 bytes {0} {1} [built] [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 [0] ./e1.js 1:0-20
harmony side effect evaluation ./module-x [2] ./e2.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 harmony side effect evaluation ./module-x [2] ./e2.js 1:0-20
import() ./module-x [6] ./module-b.js 2:0-20 import() ./module-x [6] ./module-b.js 2:0-20
[2] ./e2.js 70 bytes {1} [built] [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] chunk {2} a.js (a) 49 bytes <{0}> <{4}> >{5}< [rendered]
[3] ./module-a.js 49 bytes {2} [built] [3] ./module-a.js 49 bytes {2} [built]
import() ./module-a [0] ./e1.js 2:0-47 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`] = ` exports[`StatsTestCases should print correct stats for import-context-filter 1`] = `
"Hash: 7ad77a3e9e3d661cd55e "Hash: 00093e0065918fc6beca
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1088,7 +1088,7 @@ Entrypoint entry = entry.js
`; `;
exports[`StatsTestCases should print correct stats for import-weak 1`] = ` exports[`StatsTestCases should print correct stats for import-weak 1`] = `
"Hash: a4a61ec24e06498a1f58 "Hash: 020bd304e43a2b2f22bb
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for issue-7577 1`] = `
"Hash: 343642fcbd3799129ba3c304c0cf29920d9747260bd6e5e36b1ff9a17678 "Hash: 85309305fa40259fb1ebc74e886ded34938c99afb793a0bac9d49c018eb7
Child Child
Hash: 343642fcbd3799129ba3 Hash: 85309305fa40259fb1eb
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
a-all~main-0034bb84916bcade4cc7.js 154 bytes all~main [emitted] all~main 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 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] [0] ./a.js 18 bytes {all~main} [built]
Child Child
Hash: c304c0cf29920d974726 Hash: c74e886ded34938c99af
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
b-all~main-a293363005660974db22.js 459 bytes all~main [emitted] all~main 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-runtime~main-937400e6bee421a9af47.js 6.05 KiB runtime~main [emitted] runtime~main
b-vendors~main-13c0fc262f08dee65613.js 172 bytes vendors~main [emitted] vendors~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] [0] ./b.js 17 bytes {all~main} [built]
[1] ./node_modules/vendor.js 23 bytes {vendors~main} [built] [1] ./node_modules/vendor.js 23 bytes {vendors~main} [built]
Child Child
Hash: 0bd6e5e36b1ff9a17678 Hash: b793a0bac9d49c018eb7
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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-0-598d23de6ad7df2ab6e4.js 153 bytes 0 [emitted]
c-1-9039f4a1a11a97f28320.js 459 bytes 1 [emitted] c-1-9039f4a1a11a97f28320.js 459 bytes 1 [emitted]
c-all~main-166656d0ac46d1a19871.js 296 bytes all~main [emitted] all~main 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 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] [0] ./c.js 61 bytes {all~main} [built]
[1] ./b.js 17 bytes {1} [built] [1] ./b.js 17 bytes {1} [built]
[2] ./node_modules/vendor.js 23 bytes {0} [built]" [2] ./node_modules/vendor.js 23 bytes {0} [built]"
`; `;
exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = ` exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = `
"Hash: 3f682d19df3a78cc355bea647ea3fd883ece89243ab5b7fed36cc043302dfa02c84a4a470a27c245 "Hash: 107c243d2f4948779db6faef5739a00d90343e7d46e1640f099b398451adcc962a224e99bbf022c3
Child 1 chunks: Child 1 chunks:
Hash: 3f682d19df3a78cc355b Hash: 107c243d2f4948779db6
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1179,7 +1179,7 @@ Child 1 chunks:
[4] ./d.js 22 bytes {0} [built] [4] ./d.js 22 bytes {0} [built]
[5] ./e.js 22 bytes {0} [built] [5] ./e.js 22 bytes {0} [built]
Child 2 chunks: Child 2 chunks:
Hash: ea647ea3fd883ece8924 Hash: faef5739a00d90343e7d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1195,7 +1195,7 @@ Child 2 chunks:
[4] ./d.js 22 bytes {1} [built] [4] ./d.js 22 bytes {1} [built]
[5] ./e.js 22 bytes {1} [built] [5] ./e.js 22 bytes {1} [built]
Child 3 chunks: Child 3 chunks:
Hash: 3ab5b7fed36cc043302d Hash: 46e1640f099b398451ad
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1213,7 +1213,7 @@ Child 3 chunks:
[2] ./b.js 22 bytes {2} [built] [2] ./b.js 22 bytes {2} [built]
[5] ./e.js 22 bytes {2} [built] [5] ./e.js 22 bytes {2} [built]
Child 4 chunks: Child 4 chunks:
Hash: fa02c84a4a470a27c245 Hash: cc962a224e99bbf022c3
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1235,7 +1235,7 @@ Child 4 chunks:
`; `;
exports[`StatsTestCases should print correct stats for max-modules 1`] = ` exports[`StatsTestCases should print correct stats for max-modules 1`] = `
"Hash: ce942cd1353f7d6fc01e "Hash: e8b18f1cf5f95cf5a285
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1265,7 +1265,7 @@ Entrypoint main = main.js
`; `;
exports[`StatsTestCases should print correct stats for max-modules-default 1`] = ` exports[`StatsTestCases should print correct stats for max-modules-default 1`] = `
"Hash: ce942cd1353f7d6fc01e "Hash: e8b18f1cf5f95cf5a285
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1290,7 +1290,7 @@ Entrypoint main = main.js
`; `;
exports[`StatsTestCases should print correct stats for module-assets 1`] = ` exports[`StatsTestCases should print correct stats for module-assets 1`] = `
"Hash: 0aa43ba74041bc65bc0a "Hash: 8ae1dea4bce18528f657
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Entrypoint main = main.js Entrypoint main = main.js
@ -1472,7 +1472,7 @@ Child
`; `;
exports[`StatsTestCases should print correct stats for named-chunks-plugin 1`] = ` exports[`StatsTestCases should print correct stats for named-chunks-plugin 1`] = `
"Hash: 0c5756674e2dda021828 "Hash: 65cd83ae5b2980359572
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for named-chunks-plugin-async 1`] = `
"Hash: 8517d17cf111f52660cd "Hash: 421934d6424eb810e1a8
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for no-emit-on-errors-plugin-with-child-error 1`] = `
"Hash: 6a246e5dec75240f30bf "Hash: 0d1fa1c56ef4d2b16cdd
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1522,7 +1522,7 @@ Child child:
`; `;
exports[`StatsTestCases should print correct stats for optimize-chunks 1`] = ` exports[`StatsTestCases should print correct stats for optimize-chunks 1`] = `
"Hash: 1f0728f6992d48535826 "Hash: 2c343cbbb1c034dcc13d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for performance-different-mode-and-target 1`] = `
"Hash: b27a7019f90a13ead012bb84b396eb1e98365d94fb930f6aa3329ab03a278deb0030bfebe86abb37a1cddcae25eb52f3112b62c8b61bc84829d26b13ae06efe5f0099a11af36 "Hash: 27afa870ea890dcb8d211cf632c77c707c36d94b810d87a0ecb3d46fb6472b646a1947dce27d2c2ca90600658140ce9be0af7e07124a239ee933822c55b9d2204250eb77a29a
Child Child
Hash: b27a7019f90a13ead012 Hash: 27afa870ea890dcb8d21
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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. 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/ For more info visit https://webpack.js.org/guides/code-splitting/
Child Child
Hash: bb84b396eb1e98365d94 Hash: 1cf632c77c707c36d94b
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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. 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/ For more info visit https://webpack.js.org/guides/code-splitting/
Child Child
Hash: fb930f6aa3329ab03a27 Hash: 810d87a0ecb3d46fb647
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1649,7 +1649,7 @@ Child
Entrypoint main = no-warning.pro-node.js Entrypoint main = no-warning.pro-node.js
[0] ./index.js 293 KiB {0} [built] [0] ./index.js 293 KiB {0} [built]
Child Child
Hash: 8deb0030bfebe86abb37 Hash: 2b646a1947dce27d2c2c
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1657,7 +1657,7 @@ Child
Entrypoint main = no-warning.dev-web.js Entrypoint main = no-warning.dev-web.js
[./index.js] 293 KiB {main} [built] [./index.js] 293 KiB {main} [built]
Child Child
Hash: a1cddcae25eb52f3112b Hash: a90600658140ce9be0af
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1665,7 +1665,7 @@ Child
Entrypoint main = no-warning.dev-node.js Entrypoint main = no-warning.dev-node.js
[./index.js] 293 KiB {main} [built] [./index.js] 293 KiB {main} [built]
Child Child
Hash: 62c8b61bc84829d26b13 Hash: 7e07124a239ee933822c
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -1673,7 +1673,7 @@ Child
Entrypoint main [big] = no-warning.dev-web-with-limit-set.js Entrypoint main [big] = no-warning.dev-web-with-limit-set.js
[./index.js] 293 KiB {main} [built] [./index.js] 293 KiB {main} [built]
Child Child
Hash: ae06efe5f0099a11af36 Hash: 55b9d2204250eb77a29a
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for preset-detailed 1`] = `
"Hash: 437c9384ca68c9e15b6c "Hash: 3b3a7ec8ed8bc5030c9b
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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-none-error 1`] = `""`;
exports[`StatsTestCases should print correct stats for preset-normal 1`] = ` exports[`StatsTestCases should print correct stats for preset-normal 1`] = `
"Hash: 437c9384ca68c9e15b6c "Hash: 3b3a7ec8ed8bc5030c9b
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -2011,7 +2011,7 @@ Entrypoints:
`; `;
exports[`StatsTestCases should print correct stats for preset-verbose 1`] = ` exports[`StatsTestCases should print correct stats for preset-verbose 1`] = `
"Hash: 437c9384ca68c9e15b6c "Hash: 3b3a7ec8ed8bc5030c9b
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -2024,7 +2024,7 @@ chunk {0} main.js (main) 73 bytes >{1}< >{2}< [entry] [rendered]
> ./index main > ./index main
[0] ./index.js 51 bytes {0} [depth 0] [built] [0] ./index.js 51 bytes {0} [depth 0] [built]
ModuleConcatenation bailout: Module is not an ECMAScript module ModuleConcatenation bailout: Module is not an ECMAScript module
single entry ./index main entry ./index main
factory:Xms building:Xms = Xms factory:Xms building:Xms = Xms
[1] ./a.js 22 bytes {0} [depth 1] [built] [1] ./a.js 22 bytes {0} [depth 1] [built]
ModuleConcatenation bailout: Module is not an ECMAScript module 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`] = ` exports[`StatsTestCases should print correct stats for resolve-plugin-context 1`] = `
"Hash: 2e97eaab59275aaa8d93 "Hash: 4ca4f81607549b34ea70
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -2069,7 +2069,7 @@ Entrypoint main = bundle.js
`; `;
exports[`StatsTestCases should print correct stats for reverse-sort-modules 1`] = ` exports[`StatsTestCases should print correct stats for reverse-sort-modules 1`] = `
"Hash: ce942cd1353f7d6fc01e "Hash: e8b18f1cf5f95cf5a285
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names 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`] = ` exports[`StatsTestCases should print correct stats for scope-hoisting-bailouts 1`] = `
"Hash: a0a30b6e8932d0227376 "Hash: 6ceacb948e0119070c3d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Entrypoint index = index.js Entrypoint index = index.js
@ -2170,9 +2170,9 @@ Entrypoint entry = entry.js
`; `;
exports[`StatsTestCases should print correct stats for scope-hoisting-multi 1`] = ` exports[`StatsTestCases should print correct stats for scope-hoisting-multi 1`] = `
"Hash: d1e41fb7099e132879ee438a93ced10bfac3b362 "Hash: e170f18d73c88b7b7d9ac46fd70f754a5383c1b7
Child Child
Hash: d1e41fb7099e132879ee Hash: e170f18d73c88b7b7d9a
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Entrypoint first = vendor.js first.js Entrypoint first = vendor.js first.js
@ -2189,7 +2189,7 @@ Child
[9] ./lazy_shared.js 31 bytes {5} [built] [9] ./lazy_shared.js 31 bytes {5} [built]
[10] ./lazy_second.js 55 bytes {4} [built] [10] ./lazy_second.js 55 bytes {4} [built]
Child Child
Hash: 438a93ced10bfac3b362 Hash: c46fd70f754a5383c1b7
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Entrypoint first = vendor.js first.js Entrypoint first = vendor.js first.js
@ -2219,7 +2219,7 @@ Child
`; `;
exports[`StatsTestCases should print correct stats for side-effects-issue-7428 1`] = ` exports[`StatsTestCases should print correct stats for side-effects-issue-7428 1`] = `
"Hash: 4f5d38944616c15bd399 "Hash: 8f2bd5e4f61d541b2803
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -2242,7 +2242,7 @@ Entrypoint main = main.js
[3] ./main.js + 1 modules 231 bytes {0} [built] [3] ./main.js + 1 modules 231 bytes {0} [built]
harmony side effect evaluation ./CompB ./components/src/CompAB/index.js 2:0-43 harmony side effect evaluation ./CompB ./components/src/CompAB/index.js 2:0-43
harmony export imported specifier ./CompB ./components/src/CompAB/index.js 2:0-43 harmony export imported specifier ./CompB ./components/src/CompAB/index.js 2:0-43
single entry ./main.js main entry ./main.js main
| ./main.js 144 bytes [built] | ./main.js 144 bytes [built]
| ./components/src/CompAB/CompB.js 77 bytes [built] | ./components/src/CompAB/CompB.js 77 bytes [built]
| [only some exports used: default] | [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`] = ` exports[`StatsTestCases should print correct stats for side-effects-simple-unused 1`] = `
"Hash: c7b680da5c0d869389e8 "Hash: 2aad9ba482cb71fcd705
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -2276,7 +2276,7 @@ Entrypoint main = main.js
[0] ./index.js + 2 modules 158 bytes {0} [built] [0] ./index.js + 2 modules 158 bytes {0} [built]
harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24 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 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] | ./index.js 55 bytes [built]
| ./node_modules/pmodule/index.js 75 bytes [built] | ./node_modules/pmodule/index.js 75 bytes [built]
| [only some exports used: default] | [only some exports used: default]
@ -2298,7 +2298,7 @@ Entrypoint main = main.js
`; `;
exports[`StatsTestCases should print correct stats for simple 1`] = ` exports[`StatsTestCases should print correct stats for simple 1`] = `
"Hash: 06cc914b885215f96c5a "Hash: 0d863bcfaf259a5eba10
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -2308,14 +2308,14 @@ Entrypoint main = bundle.js
`; `;
exports[`StatsTestCases should print correct stats for simple-more-info 1`] = ` exports[`StatsTestCases should print correct stats for simple-more-info 1`] = `
"Hash: c8c226a954f967e61630 "Hash: 64de01465a28fb4267d8
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
bundle.js 3.57 KiB 0 [emitted] main bundle.js 3.57 KiB 0 [emitted] main
Entrypoint main = bundle.js Entrypoint main = bundle.js
[0] ./index.js 0 bytes {0} [built] [0] ./index.js 0 bytes {0} [built]
single entry ./index main entry ./index main
factory:Xms building:Xms = Xms" factory:Xms building:Xms = Xms"
`; `;
@ -2486,17 +2486,17 @@ Child manual:
[6] ./c.js 72 bytes {3} {4} [built] [6] ./c.js 72 bytes {3} {4} [built]
chunk {5} default/a.js (a) 176 bytes ={7}= >{8}< [entry] [rendered] chunk {5} default/a.js (a) 176 bytes ={7}= >{8}< [entry] [rendered]
> ./a a > ./a a
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built] [1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[10] ./a.js + 1 modules 156 bytes {5} {6} [built] [9] ./a.js + 1 modules 156 bytes {5} {6} [built]
| ./a.js 121 bytes [built] | ./a.js 121 bytes [built]
| ./e.js 20 bytes [built] | ./e.js 20 bytes [built]
chunk {6} default/async-a.js (async-a) 176 bytes <{0}> ={7}= >{8}< [rendered] chunk {6} default/async-a.js (async-a) 176 bytes <{0}> ={7}= >{8}< [rendered]
> ./a [0] ./index.js 1:0-47 > ./a [0] ./index.js 1:0-47
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built] [1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[10] ./a.js + 1 modules 156 bytes {5} {6} [built] [9] ./a.js + 1 modules 156 bytes {5} {6} [built]
| ./a.js 121 bytes [built] | ./a.js 121 bytes [built]
| ./e.js 20 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) 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 > ./a a
> ./b b > ./b b
> ./c c > ./c c
@ -2506,12 +2506,11 @@ Child manual:
[2] ./node_modules/x.js 20 bytes {7} [built] [2] ./node_modules/x.js 20 bytes {7} [built]
[3] ./node_modules/y.js 20 bytes {7} [built] [3] ./node_modules/y.js 20 bytes {7} [built]
[7] ./node_modules/z.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] chunk {8} default/async-g.js (async-g) 54 bytes <{5}> <{6}> <{7}> [rendered]
> ./g [] 6:0-47 > ./g [] 6:0-47
> ./g [] 6:0-47 > ./g [] 6:0-47
[5] ./f.js 20 bytes {1} {2} {3} {4} {8} [built] [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: Child name-too-long:
Entrypoint main = main.js 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 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] [0] ./index.js 147 bytes {0} [built]
chunk {1} default/a.js (a) 216 bytes >{8}< [entry] [rendered] chunk {1} default/a.js (a) 216 bytes >{8}< [entry] [rendered]
> ./a a > ./a a
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built] [1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[2] ./node_modules/x.js 20 bytes {1} {7} [built] [2] ./node_modules/x.js 20 bytes {1} {7} [built]
[3] ./node_modules/y.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] [9] ./a.js + 1 modules 156 bytes {1} {6} [built]
| ./a.js 121 bytes [built] | ./a.js 121 bytes [built]
| ./e.js 20 bytes [built] | ./e.js 20 bytes [built]
chunk {2} default/b.js (b) 112 bytes ={7}= [entry] [rendered] chunk {2} default/b.js (b) 112 bytes ={7}= [entry] [rendered]
> ./b b > ./b b
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built] [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] [6] ./c.js 72 bytes {4} {5} [built]
chunk {6} default/async-a.js (async-a) 176 bytes <{0}> ={7}= >{8}< [rendered] chunk {6} default/async-a.js (async-a) 176 bytes <{0}> ={7}= >{8}< [rendered]
> ./a [0] ./index.js 1:0-47 > ./a [0] ./index.js 1:0-47
[1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built] [1] ./d.js 20 bytes {1} {2} {3} {4} {5} {6} [built]
[10] ./a.js + 1 modules 156 bytes {1} {6} [built] [9] ./a.js + 1 modules 156 bytes {1} {6} [built]
| ./a.js 121 bytes [built] | ./a.js 121 bytes [built]
| ./e.js 20 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) 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 > ./b b
> ./c c > ./c c
> ./a [0] ./index.js 1:0-47 > ./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] [2] ./node_modules/x.js 20 bytes {1} {7} [built]
[3] ./node_modules/y.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] [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] chunk {8} default/async-g.js (async-g) 54 bytes <{1}> <{6}> <{7}> [rendered]
> ./g [] 6:0-47 > ./g [] 6:0-47
> ./g [] 6:0-47 > ./g [] 6:0-47
[5] ./f.js 20 bytes {2} {3} {4} {5} {8} [built] [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`] = ` 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`] = ` exports[`StatsTestCases should print correct stats for tree-shaking 1`] = `
"Hash: 40df5eaa38b35883e99e "Hash: a66ca410afc2eb29b31d
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names
@ -3052,7 +3050,7 @@ Entrypoint main = bundle.js
`; `;
exports[`StatsTestCases should print correct stats for warnings-uglifyjs 1`] = ` exports[`StatsTestCases should print correct stats for warnings-uglifyjs 1`] = `
"Hash: ed8a6765253160add1c8 "Hash: 3663bd94f10ad20afb9e
Time: Xms Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names Asset Size Chunks Chunk Names

View File

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

View File

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

View File

@ -3,6 +3,5 @@ require("./common");
module.exports = "vendor"; module.exports = "vendor";
it("should have the correct main flag for multi vendor module", function() { it("should have the correct main flag for multi vendor module", function() {
var multiModule = __webpack_require__.c[module.parents[0]]; expect(module.hot._main).toBe(true);
expect(multiModule.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() { it("should ignore missing modules as entries", function() {
var fs = require("fs"); // a.js and b.js should be evaulated correctly
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 use WebpackMissingModule when evaluating missing modules", function() {
expect(function() { expect(function() {
require("./intentionally-missing-module"); require("./intentionally-missing-module");
}).toThrowError("Cannot find module './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"); const IgnorePlugin = require("../../../../lib/IgnorePlugin");
module.exports = { module.exports = {
entry: { entry: {
a: "./intentionally-missing-module.js",
b: ["./intentionally-missing-module.js"], b: ["./intentionally-missing-module.js"],
bundle0: ["./index"] bundle0: ["./index"]
}, },
output: { output: {
filename: "[name].js" filename: "[name].js"
}, },
plugins: [new IgnorePlugin(new RegExp(/intentionally-missing-module/))], plugins: [new IgnorePlugin(new RegExp(/intentionally-missing-module/))]
node: {
__dirname: false
}
}; };

View File

@ -1,6 +1,6 @@
"use strict"; "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 * 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 => { child.hooks.compilation.tap("TestChildCompilationFailurePlugin", childCompilation => {
childCompilation.errors.push(new Error("forced error")); 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); child.runAsChild(cb);
}); });
} }