Merge branch 'master' into crossorigin-attr

This commit is contained in:
Ryan Tsao 2018-04-19 14:11:37 -07:00
commit 573f2ae0bb
145 changed files with 1413 additions and 300 deletions

55
declarations.d.ts vendored Normal file
View File

@ -0,0 +1,55 @@
declare module "*.json";
declare module "webpack-cli";
// Deprecated NodeJS API usages in Webpack
declare namespace NodeJS {
interface Process {
binding(internalModule: string): any;
}
}
// There are no typings for chrome-trace-event
declare module 'chrome-trace-event' {
interface Event {
name: string
id?: number
cat: string[]
args?: Object
}
export class Tracer {
constructor(options: {
noStream: boolean
})
pipe(stream: NodeJS.WritableStream) : void
instantEvent(event: Event) : void
counter: number
trace: {
begin(event: Event) : void
end(event: Event) : void
}
}
}
/**
* Global variable declarations
* @todo Once this issue is resolved, remove these globals and add JSDoc onsite instead
* https://github.com/Microsoft/TypeScript/issues/15626
*/
declare const $hash$;
declare const $requestTimeout$;
declare const installedModules;
declare const $require$;
declare const hotDownloadManifest;
declare const hotDownloadUpdateChunk;
declare const hotDisposeChunk;
declare const modules;
declare const installedChunks;
declare const hotAddUpdateChunk;
declare const parentHotUpdateCallback;
declare const $hotChunkFilename$;
declare const $hotMainFilename$;
declare const WebAssembly;
declare const importScripts;
declare const $crossOriginLoading$;
declare const chunkId;

View File

@ -6,15 +6,28 @@
const DependenciesBlock = require("./DependenciesBlock");
module.exports = class AsyncDependenciesBlock extends DependenciesBlock {
constructor(name, module, loc, request) {
constructor(groupOptions, module, loc, request) {
super();
this.chunkName = name;
if (typeof groupOptions === "string") {
groupOptions = { name: groupOptions };
} else if (!groupOptions) {
groupOptions = { name: undefined };
}
this.groupOptions = groupOptions;
this.chunkGroup = undefined;
this.module = module;
this.loc = loc;
this.request = request;
}
get chunkName() {
return this.groupOptions.name;
}
set chunkName(value) {
this.groupOptions.name = value;
}
get chunks() {
throw new Error("Moved to AsyncDependenciesBlock.chunkGroup");
}
@ -24,7 +37,7 @@ module.exports = class AsyncDependenciesBlock extends DependenciesBlock {
}
updateHash(hash) {
hash.update(this.chunkName || "");
hash.update(JSON.stringify(this.groupOptions));
hash.update(
(this.chunkGroup &&
this.chunkGroup.chunks

View File

@ -6,6 +6,7 @@
const util = require("util");
const SortableSet = require("./util/SortableSet");
const intersect = require("./util/SetHelpers").intersect;
const GraphHelpers = require("./GraphHelpers");
let debugId = 1000;
const ERR_CHUNK_ENTRY = "Chunk.entry was removed. Use hasRuntime()";
@ -170,8 +171,8 @@ class Chunk {
if (aItem.done) return 0;
const aModuleIdentifier = aItem.value.identifier();
const bModuleIdentifier = bItem.value.identifier();
if (aModuleIdentifier > bModuleIdentifier) return -1;
if (aModuleIdentifier < bModuleIdentifier) return 1;
if (aModuleIdentifier < bModuleIdentifier) return -1;
if (aModuleIdentifier > bModuleIdentifier) return 1;
}
}
@ -321,12 +322,15 @@ class Chunk {
}
getAllAsyncChunks() {
const initialChunks = new Set();
const queue = new Set(this.groupsIterable);
const queue = new Set();
const chunks = new Set();
for (const chunkGroup of queue) {
for (const chunk of chunkGroup.chunks) initialChunks.add(chunk);
const initialChunks = intersect(
Array.from(this.groupsIterable, g => new Set(g.chunks))
);
for (const chunkGroup of this.groupsIterable) {
for (const child of chunkGroup.childrenIterable) queue.add(child);
}
for (const chunkGroup of queue) {
@ -361,6 +365,62 @@ class Chunk {
};
}
getChildIdsByOrders() {
const lists = new Map();
for (const group of this.groupsIterable) {
if (group.chunks[group.chunks.length - 1] === this) {
for (const childGroup of group.childrenIterable) {
// TODO webpack 5 remove this check for options
if (typeof childGroup.options === "object") {
for (const key of Object.keys(childGroup.options)) {
if (key.endsWith("Order")) {
const name = key.substr(0, key.length - "Order".length);
let list = lists.get(name);
if (list === undefined) lists.set(name, (list = []));
list.push({
order: childGroup.options[key],
group: childGroup
});
}
}
}
}
}
}
const result = Object.create(null);
for (const [name, list] of lists) {
list.sort((a, b) => {
const cmp = b.order - a.order;
if (cmp !== 0) return cmp;
// TOOD webpack 5 remove this check of compareTo
if (a.group.compareTo) return a.group.compareTo(b.group);
return 0;
});
result[name] = Array.from(
list.reduce((set, item) => {
for (const chunk of item.group.chunks) set.add(chunk.id);
return set;
}, new Set())
);
}
return result;
}
getChildIdsByOrdersMap() {
const chunkMaps = Object.create(null);
for (const chunk of this.getAllAsyncChunks()) {
const data = chunk.getChildIdsByOrders();
for (const key of Object.keys(data)) {
let chunkMap = chunkMaps[key];
if (chunkMap === undefined)
chunkMaps[key] = chunkMap = Object.create(null);
chunkMap[chunk.id] = data[key];
}
}
return chunkMaps;
}
getChunkModuleMaps(filterFn) {
const chunkModuleIdMap = Object.create(null);
const chunkModuleHashMap = Object.create(null);

View File

@ -26,9 +26,14 @@ const sortOrigin = (a, b) => {
};
class ChunkGroup {
constructor(name) {
constructor(options) {
if (typeof options === "string") {
options = { name: options };
} else if (!options) {
options = { name: undefined };
}
this.groupDebugId = debugId++;
this.name = name;
this.options = options;
this._children = new SortableSet(undefined, sortById);
this._parents = new SortableSet(undefined, sortById);
this._blocks = new SortableSet();
@ -36,6 +41,30 @@ class ChunkGroup {
this.origins = [];
}
addOptions(options) {
for (const key of Object.keys(options)) {
if (this.options[key] === undefined) {
this.options[key] = options[key];
} else if (this.options[key] !== options[key]) {
if (key.endsWith("Order")) {
this.options[key] = Math.max(this.options[key], options[key]);
} else {
throw new Error(
`ChunkGroup.addOptions: No option merge strategy for ${key}`
);
}
}
}
}
get name() {
return this.options.name;
}
set name(value) {
this.options.name = value;
}
/* istanbul ignore next */
get debugId() {
return Array.from(this.chunks, x => x.debugId).join("+");
@ -222,6 +251,18 @@ class ChunkGroup {
return false;
}
getFiles() {
const files = new Set();
for (const chunk of this.chunks) {
for (const file of chunk.files) {
files.add(file);
}
}
return Array.from(files);
}
remove(reason) {
// cleanup parents
for (const parentChunkGroup of this._parents) {
@ -269,6 +310,53 @@ class ChunkGroup {
this._children.sort();
}
compareTo(otherGroup) {
if (this.chunks.length > otherGroup.chunks.length) return -1;
if (this.chunks.length < otherGroup.chunks.length) return 1;
const a = this.chunks[Symbol.iterator]();
const b = otherGroup.chunks[Symbol.iterator]();
// eslint-disable-next-line
while (true) {
const aItem = a.next();
const bItem = b.next();
if (aItem.done) return 0;
const cmp = aItem.value.compareTo(bItem.value);
if (cmp !== 0) return cmp;
}
}
getChildrenByOrders() {
const lists = new Map();
for (const childGroup of this._children) {
// TODO webpack 5 remove this check for options
if (typeof childGroup.options === "object") {
for (const key of Object.keys(childGroup.options)) {
if (key.endsWith("Order")) {
const name = key.substr(0, key.length - "Order".length);
let list = lists.get(name);
if (list === undefined) lists.set(name, (list = []));
list.push({
order: childGroup.options[key],
group: childGroup
});
}
}
}
}
const result = Object.create(null);
for (const [name, list] of lists) {
list.sort((a, b) => {
const cmp = b.order - a.order;
if (cmp !== 0) return cmp;
// TOOD webpack 5 remove this check of compareTo
if (a.group.compareTo) return a.group.compareTo(b.group);
return 0;
});
result[name] = list.map(i => i.group);
}
return result;
}
checkConstraints() {
const chunk = this;
for (const child of chunk._children) {

View File

@ -208,6 +208,7 @@ class Compilation extends Tapable {
break;
}
});
this.name = undefined;
this.compiler = compiler;
this.resolverFactory = compiler.resolverFactory;
this.inputFileSystem = compiler.inputFileSystem;
@ -464,9 +465,8 @@ class Compilation extends Tapable {
recursive,
callback
) {
let _this = this;
const start = _this.profile && Date.now();
const currentProfile = _this.profile && {};
const start = this.profile && Date.now();
const currentProfile = this.profile && {};
asyncLib.forEach(
dependencies,
@ -475,7 +475,7 @@ class Compilation extends Tapable {
const errorAndCallback = err => {
err.origin = module;
_this.errors.push(err);
this.errors.push(err);
if (bail) {
callback(err);
} else {
@ -484,28 +484,24 @@ class Compilation extends Tapable {
};
const warningAndCallback = err => {
err.origin = module;
_this.warnings.push(err);
this.warnings.push(err);
callback();
};
const semaphore = _this.semaphore;
const semaphore = this.semaphore;
semaphore.acquire(() => {
if (_this === null) return semaphore.release();
const factory = item.factory;
factory.create(
{
contextInfo: {
issuer: module.nameForCondition && module.nameForCondition(),
compiler: _this.compiler.name
compiler: this.compiler.name
},
resolveOptions: module.resolveOptions,
context: module.context,
dependencies: dependencies
},
(err, dependentModule) => {
if (_this === null) return semaphore.release();
let afterFactory;
const isOptional = () => {
@ -543,7 +539,7 @@ class Compilation extends Tapable {
}
};
const addModuleResult = _this.addModule(
const addModuleResult = this.addModule(
dependentModule,
cacheGroup
);
@ -557,7 +553,7 @@ class Compilation extends Tapable {
}
if (recursive && addModuleResult.dependencies) {
_this.processModuleDependencies(dependentModule, callback);
this.processModuleDependencies(dependentModule, callback);
} else {
return callback();
}
@ -570,7 +566,7 @@ class Compilation extends Tapable {
dependentModule.issuer = module;
} else {
if (_this.profile) {
if (this.profile) {
if (module.profile) {
const time = Date.now() - start;
if (
@ -584,14 +580,12 @@ class Compilation extends Tapable {
}
if (addModuleResult.build) {
_this.buildModule(
this.buildModule(
dependentModule,
isOptional(),
module,
dependencies,
err => {
if (_this === null) return semaphore.release();
if (err) {
semaphore.release();
return errorOrWarningAndCallback(err);
@ -608,7 +602,7 @@ class Compilation extends Tapable {
);
} else {
semaphore.release();
_this.waitForBuildingFinished(dependentModule, afterBuild);
this.waitForBuildingFinished(dependentModule, afterBuild);
}
}
);
@ -1012,17 +1006,22 @@ class Compilation extends Tapable {
}
}
addChunkInGroup(name, module, loc, request) {
addChunkInGroup(groupOptions, module, loc, request) {
if (typeof groupOptions === "string") {
groupOptions = { name: groupOptions };
}
const name = groupOptions.name;
if (name) {
const chunkGroup = this.namedChunkGroups.get(name);
if (chunkGroup !== undefined) {
chunkGroup.addOptions(groupOptions);
if (module) {
chunkGroup.addOrigin(module, loc, request);
}
return chunkGroup;
}
}
const chunkGroup = new ChunkGroup(name);
const chunkGroup = new ChunkGroup(groupOptions);
if (module) chunkGroup.addOrigin(module, loc, request);
const chunk = this.addChunk(name);
@ -1051,15 +1050,13 @@ class Compilation extends Tapable {
}
assignIndex(module) {
const _this = this;
const assignIndexToModule = module => {
// enter module
if (typeof module.index !== "number") {
module.index = _this.nextFreeModuleIndex++;
module.index = this.nextFreeModuleIndex++;
// leave module
queue.push(() => (module.index2 = _this.nextFreeModuleIndex2++));
queue.push(() => (module.index2 = this.nextFreeModuleIndex2++));
// enter it as block
assignIndexToDependencyBlock(module);
@ -1198,11 +1195,18 @@ class Compilation extends Tapable {
);
c = chunkGroup;
} else {
c = this.addChunkInGroup(b.chunkName, module, b.loc, b.request);
c = this.addChunkInGroup(
b.groupOptions || b.chunkName,
module,
b.loc,
b.request
);
blockChunkGroups.set(b, c);
allCreatedChunkGroups.add(c);
}
} else {
// TODO webpack 5 remove addOptions check
if (c.addOptions) c.addOptions(b.groupOptions);
c.addOrigin(module, b.loc, b.request);
}

View File

@ -74,6 +74,8 @@ class Compiler extends Tapable {
}
});
this.name = undefined;
this.parentCompilation = undefined;
this.outputPath = "";
this.outputFileSystem = null;
this.inputFileSystem = null;

View File

@ -12,7 +12,7 @@ const Template = require("./Template");
class ContextModule extends Module {
// type ContextMode = "sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"
// type ContextOptions = { resource: string, recursive: boolean, regExp: RegExp, addon?: string, mode?: ContextMode, chunkName?: string, include?: RegExp, exclude?: RegExp }
// type ContextOptions = { resource: string, recursive: boolean, regExp: RegExp, addon?: string, mode?: ContextMode, chunkName?: string, include?: RegExp, exclude?: RegExp, groupOptions?: Object }
// resolveDependencies: (fs: FS, options: ContextOptions, (err: Error?, dependencies: Dependency[]) => void) => void
// options: ContextOptions
constructor(resolveDependencies, options) {
@ -81,6 +81,11 @@ class ContextModule extends Module {
if (this.options.regExp) identifier += ` ${this.options.regExp}`;
if (this.options.include) identifier += ` include: ${this.options.include}`;
if (this.options.exclude) identifier += ` exclude: ${this.options.exclude}`;
if (this.options.groupOptions) {
identifier += ` groupOptions: ${JSON.stringify(
this.options.groupOptions
)}`;
}
if (this.options.namespaceObject === "strict")
identifier += " strict namespace object";
else if (this.options.namespaceObject) identifier += " namespace object";
@ -106,6 +111,11 @@ class ContextModule extends Module {
identifier += ` include: ${this.prettyRegExp(this.options.include + "")}`;
if (this.options.exclude)
identifier += ` exclude: ${this.prettyRegExp(this.options.exclude + "")}`;
if (this.options.groupOptions) {
const groupOptions = this.options.groupOptions;
for (const key of Object.keys(groupOptions))
identifier += ` ${key}: ${groupOptions[key]}`;
}
if (this.options.namespaceObject === "strict")
identifier += " strict namespace object";
else if (this.options.namespaceObject) identifier += " namespace object";
@ -170,7 +180,9 @@ class ContextModule extends Module {
// and add that block to this context
if (dependencies.length > 0) {
const block = new AsyncDependenciesBlock(
this.options.chunkName,
Object.assign({}, this.options.groupOptions, {
name: this.options.chunkName
}),
this
);
for (const dep of dependencies) {
@ -202,7 +214,9 @@ class ContextModule extends Module {
);
}
const block = new AsyncDependenciesBlock(
chunkName,
Object.assign({}, this.options.groupOptions, {
name: chunkName
}),
dep.module,
dep.loc,
dep.userRequest

View File

@ -16,18 +16,6 @@ class Entrypoint extends ChunkGroup {
return true;
}
getFiles() {
const files = new Set();
for (const chunk of this.chunks) {
for (const file of chunk.files) {
files.add(file);
}
}
return Array.from(files);
}
setRuntimeChunk(chunk) {
this.runtimeChunk = chunk;
}

View File

@ -6,6 +6,7 @@
const { RawSource } = require("webpack-sources");
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
const cache = new WeakMap();
class EvalDevToolModuleTemplatePlugin {

View File

@ -7,6 +7,8 @@
const { RawSource } = require("webpack-sources");
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
const cache = new WeakMap();
class EvalSourceMapDevToolModuleTemplatePlugin {
constructor(compilation, options) {
this.compilation = compilation;
@ -29,12 +31,16 @@ class EvalSourceMapDevToolModuleTemplatePlugin {
moduleTemplate.hooks.module.tap(
"EvalSourceMapDevToolModuleTemplatePlugin",
(source, module) => {
if (source.__EvalSourceMapDevToolData)
return source.__EvalSourceMapDevToolData;
const cachedSource = cache.get(source);
if (cachedSource !== undefined) {
return cachedSource;
}
if (!matchModule(module.resource)) {
return source;
}
/** @type {{ [key: string]: any; }} */
let sourceMap;
let content;
if (source.sourceAndMap) {
@ -87,10 +93,14 @@ class EvalSourceMapDevToolModuleTemplatePlugin {
"utf8"
).toString("base64")}`
) + `\n//# sourceURL=webpack-internal:///${module.id}\n`; // workaround for chrome bug
source.__EvalSourceMapDevToolData = new RawSource(
const evalSource = new RawSource(
`eval(${JSON.stringify(content + footer)});`
);
return source.__EvalSourceMapDevToolData;
cache.set(source, evalSource);
return evalSource;
}
);
moduleTemplate.hooks.hash.tap(

View File

@ -362,6 +362,7 @@ module.exports = function() {
for (var id in hotUpdate) {
if (Object.prototype.hasOwnProperty.call(hotUpdate, id)) {
moduleId = toModuleId(id);
/** @type {any} */
var result;
if (hotUpdate[id]) {
result = getAffectedStuff(moduleId);
@ -371,6 +372,7 @@ module.exports = function() {
moduleId: id
};
}
/** @type {Error|false} */
var abortError = false;
var doApply = false;
var doDispose = false;

View File

@ -145,8 +145,8 @@ module.exports = class HotModuleReplacementPlugin {
h: compilation.hash,
c: {}
};
for (let chunkId of Object.keys(records.chunkHashs)) {
chunkId = isNaN(+chunkId) ? chunkId : +chunkId;
for (const key of Object.keys(records.chunkHashs)) {
const chunkId = isNaN(+key) ? key : +key;
const currentChunk = compilation.chunks.find(
chunk => chunk.id === chunkId
);
@ -343,13 +343,17 @@ module.exports = class HotModuleReplacementPlugin {
parser.state.module.addDependency(dep);
requests.push(request);
});
if (expr.arguments.length > 1)
if (expr.arguments.length > 1) {
parser.hooks.hotAcceptCallback.call(
expr.arguments[1],
requests
);
else
parser.walkExpression(expr.arguments[1]); // other args are ignored
return true;
} else {
parser.hooks.hotAcceptWithoutCallback.call(expr, requests);
return true;
}
}
}
});

16
lib/HotUpdateChunk.js Normal file
View File

@ -0,0 +1,16 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const Chunk = require("./Chunk");
class HotUpdateChunk extends Chunk {
constructor() {
super();
this.removedModules = undefined;
}
}
module.exports = HotUpdateChunk;

View File

@ -5,7 +5,7 @@
"use strict";
const Template = require("./Template");
const Chunk = require("./Chunk");
const HotUpdateChunk = require("./HotUpdateChunk");
const { Tapable, SyncWaterfallHook, SyncHook } = require("tapable");
module.exports = class HotUpdateChunkTemplate extends Tapable {
@ -41,7 +41,7 @@ module.exports = class HotUpdateChunkTemplate extends Tapable {
moduleTemplate,
dependencyTemplates
) {
const hotUpdateChunk = new Chunk();
const hotUpdateChunk = new HotUpdateChunk();
hotUpdateChunk.id = id;
hotUpdateChunk.setModules(modules);
hotUpdateChunk.removedModules = removedModules;

View File

@ -11,6 +11,10 @@ const ModuleReason = require("./ModuleReason");
const SortableSet = require("./util/SortableSet");
const Template = require("./Template");
/** @typedef {typeof import("./Chunk")} Chunk */
/** @typedef {typeof import("./RequestShortener")} RequestShortener */
const EMPTY_RESOLVE_OPTIONS = {};
let debugId = 1000;
@ -23,51 +27,79 @@ const sortByDebugId = (a, b) => {
return a.debugId - b.debugId;
};
/** @typedef {(requestShortener: RequestShortener) => string} OptimizationBailoutFunction */
class Module extends DependenciesBlock {
constructor(type, context = null) {
super();
/** @type {string} */
this.type = type;
/** @type {string} */
this.context = context;
// Unique Id
/** @type {number} */
this.debugId = debugId++;
// Hash
/** @type {string} */
this.hash = undefined;
/** @type {string} */
this.renderedHash = undefined;
// Info from Factory
/** @type {object} */
this.resolveOptions = EMPTY_RESOLVE_OPTIONS;
/** @type {object} */
this.factoryMeta = {};
// Info from Build
/** @type {Error[]} */
this.warnings = [];
/** @type {Error[]} */
this.errors = [];
/** @type {object} */
this.buildMeta = undefined;
/** @type {object} */
this.buildInfo = undefined;
// Graph (per Compilation)
/** @type {ModuleReason[]} */
this.reasons = [];
/** @type {SortableSet} */
this._chunks = new SortableSet(undefined, sortById);
// Info from Compilation (per Compilation)
/** @type {number | string} */
this.id = null;
/** @type {number} */
this.index = null;
/** @type {number} */
this.index2 = null;
/** @type {number} */
this.depth = null;
/** @type {Module} */
this.issuer = null;
/** @type {undefined | object} */
this.profile = undefined;
/** @type {boolean} */
this.prefetched = false;
/** @type {boolean} */
this.built = false;
// Info from Optimization (per Compilation)
/** @type {null | boolean} */
this.used = null;
/** @type {false | true | string[]} */
this.usedExports = null;
/** @type {(string | OptimizationBailoutFunction)[]} */
this.optimizationBailout = [];
// delayed operations
/** @type {undefined | {oldChunk: Chunk, newChunks: Chunk[]}[] } */
this._rewriteChunkInReasons = undefined;
/** @type {boolean} */
this.useSourceMap = false;
}

View File

@ -154,7 +154,9 @@ class NormalModule extends Module {
this.errors.push(new ModuleError(this, error));
},
exec: (code, filename) => {
// @ts-ignore Argument of type 'this' is not assignable to parameter of type 'Module'.
const module = new NativeModule(filename, this);
// @ts-ignore _nodeModulePaths is deprecated and undocumented Node.js API
module.paths = NativeModule._nodeModulePaths(this.context);
module.filename = filename;
module._compile(code, filename);

View File

@ -1877,7 +1877,8 @@ class Parser extends Tapable {
return {
range: left.range,
value: left.value,
code: true
code: true,
conditional: false
};
} else if (right.code) {
return {
@ -1886,12 +1887,15 @@ class Parser extends Tapable {
right.range ? right.range[1] : left.range[1]
],
value: left.value + right.value,
code: true
code: true,
conditional: false
};
} else {
return {
range: [left.range[0], right.range[1]],
value: left.value + right.value
value: left.value + right.value,
code: false,
conditional: false
};
}
}
@ -1907,6 +1911,7 @@ class Parser extends Tapable {
else if (!alternate.code) items.push(alternate);
else break;
return {
range: undefined,
value: "",
code: true,
conditional: items
@ -1915,12 +1920,16 @@ class Parser extends Tapable {
case "Literal":
return {
range: expression.range,
value: expression.value + ""
value: expression.value + "",
code: false,
conditional: false
};
}
return {
range: undefined,
value: "",
code: true
code: true,
conditional: false
};
}

View File

@ -353,7 +353,8 @@ module.exports = class RuleSet {
};
}
return {
loader: useItemString
loader: useItemString,
options: undefined
};
}

View File

@ -12,6 +12,16 @@ module.exports = class RuntimeTemplate {
this.requestShortener = requestShortener;
}
/**
* Add a comment
* @param {object} options Information content of the comment
* @param {string=} options.request request string used originally
* @param {string=} options.chunkName name of the chunk referenced
* @param {string=} options.chunkReason reason information of the chunk
* @param {string=} options.message additional message
* @param {string=} options.exportName name of the export
* @return {string} comment
*/
comment({ request, chunkName, chunkReason, message, exportName }) {
let content;
if (this.outputOptions.pathinfo) {
@ -195,7 +205,7 @@ module.exports = class RuntimeTemplate {
} else if (originModule.buildMeta.strictHarmonyModule) {
if (exportName) {
return "/* non-default import from non-esm module */undefined";
} else if (!exportName) {
} else {
if (asiSafe) {
return `/*#__PURE__*/{ /* fake namespace object */ "default": ${importVar} }`;
} else {

View File

@ -7,6 +7,10 @@
const SizeFormatHelpers = exports;
SizeFormatHelpers.formatSize = size => {
if (typeof size !== "number" || Number.isNaN(size) === true) {
return "unknown size";
}
if (size <= 0) {
return "0 bytes";
}

View File

@ -401,12 +401,39 @@ class Stats {
for (const keyValuePair of compilation.entrypoints) {
const name = keyValuePair[0];
const ep = keyValuePair[1];
const children = ep.getChildrenByOrders();
obj.entrypoints[name] = {
chunks: ep.chunks.map(c => c.id),
assets: ep.chunks.reduce(
(array, c) => array.concat(c.files || []),
[]
)
),
children: Object.keys(children).reduce((obj, key) => {
const groups = children[key];
obj[key] = groups.map(group => ({
name: group.name,
chunks: group.chunks.map(c => c.id),
assets: group.chunks.reduce(
(array, c) => array.concat(c.files || []),
[]
)
}));
return obj;
}, Object.create(null)),
childAssets: Object.keys(children).reduce((obj, key) => {
const groups = children[key];
obj[key] = Array.from(
groups.reduce((set, group) => {
for (const chunk of group.chunks) {
for (const asset of chunk.files) {
set.add(asset);
}
}
return set;
}, new Set())
);
return obj;
}, Object.create(null))
};
if (showPerformance) {
obj.entrypoints[name].isOverSizeLimit = ep.isOverSizeLimit;
@ -519,6 +546,7 @@ class Stats {
const parents = new Set();
const children = new Set();
const siblings = new Set();
const childIdByOrder = chunk.getChildIdsByOrders();
for (const chunkGroup of chunk.groupsIterable) {
for (const parentGroup of chunkGroup.parentsIterable) {
for (const chunk of parentGroup.chunks) {
@ -547,7 +575,8 @@ class Stats {
hash: chunk.renderedHash,
siblings: Array.from(siblings).sort(),
parents: Array.from(parents).sort(),
children: Array.from(children).sort()
children: Array.from(children).sort(),
childrenByOrder: childIdByOrder
};
if (showChunkModules) {
obj.modules = chunk
@ -749,7 +778,7 @@ class Stats {
const builtAtDate = new Date(obj.builtAt);
colors.normal("Built at: ");
colors.normal(
builtAtDate.toLocaleDateString({
builtAtDate.toLocaleDateString(undefined, {
day: "2-digit",
month: "2-digit",
year: "numeric"
@ -851,6 +880,18 @@ class Stats {
colors.normal(" ");
colors.green(asset);
}
for (const name of Object.keys(ep.childAssets)) {
const assets = ep.childAssets[name];
if (assets && assets.length > 0) {
colors.normal(" ");
colors.magenta(`(${name}:`);
for (const asset of assets) {
colors.normal(" ");
colors.green(asset);
}
colors.magenta(")");
}
}
newline();
}
}
@ -1103,6 +1144,19 @@ class Stats {
colors.yellow(id);
colors.normal("}<");
}
if (chunk.childrenByOrder) {
for (const name of Object.keys(chunk.childrenByOrder)) {
const children = chunk.childrenByOrder[name];
colors.normal(" ");
colors.magenta(`(${name}:`);
for (const id of children) {
colors.normal(" {");
colors.yellow(id);
colors.normal("}");
}
colors.magenta(")");
}
}
if (chunk.entry) {
colors.yellow(" [entry]");
} else if (chunk.initial) {

View File

@ -5,6 +5,14 @@
"use strict";
module.exports = class WebpackError extends Error {
constructor(message) {
super(message);
this.details = undefined;
Error.captureStackTrace(this, this.constructor);
}
inspect() {
return this.stack + (this.details ? `\n${this.details}` : "");
}

View File

@ -123,12 +123,12 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
switch (options.target) {
case "web":
case "electron-renderer":
case "node-webkit":
return "window";
case "webworker":
return "self";
case "node":
case "async-node":
case "node-webkit":
case "electron-main":
return "global";
default:
@ -193,6 +193,7 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
options => (isProductionLikeMode(options) ? "warning" : false)
);
this.set("optimization", "call", value => Object.assign({}, value));
this.set("optimization.removeAvailableModules", true);
this.set("optimization.removeEmptyChunks", true);
this.set("optimization.mergeDuplicateChunks", true);

View File

@ -141,7 +141,7 @@ class WebpackOptionsValidationError extends WebpackError {
if (schema.anyOf) return schema.anyOf.map(formatInnerSchema).join(" | ");
if (schema.enum)
return schema.enum.map(item => JSON.stringify(item)).join(" | ");
return JSON.stringify(schema, 0, 2);
return JSON.stringify(schema, null, 2);
}
static formatValidationError(err) {
@ -306,7 +306,7 @@ class WebpackOptionsValidationError extends WebpackError {
// eslint-disable-line no-fallthrough
return `${dataPath} ${err.message} (${JSON.stringify(
err,
0,
null,
2
)}).\n${getSchemaPartText(err.parentSchema)}`;
}

View File

@ -320,10 +320,15 @@ const makeInterceptorFor = (instance, tracer) => hookName => ({
}
});
/** @typedef {(...args: any[]) => void | Promise<any>} PluginFunction */
/**
* @param {string} hookName Name of the hook to profile.
* @param {{counter: number, trace: *, profiler: *}} tracer Instance of tracer.
* @param {{name: string, type: string, fn: Function}} opts Options for the profiled fn.
* @param {Tracer} tracer Instance of tracer.
* @param {object} options Options for the profiled fn.
* @param {string} options.name Plugin name
* @param {string} options.type Plugin type (sync | async | promise)
* @param {PluginFunction} options.fn Plugin function
* @returns {*} Chainable hooked function.
*/
const makeNewProfiledTapFn = (hookName, tracer, { name, type, fn }) => {
@ -339,7 +344,8 @@ const makeNewProfiledTapFn = (hookName, tracer, { name, type, fn }) => {
id,
cat: defaultCategory
});
return fn(...args).then(r => {
const promise = /** @type {Promise<*>} */ (fn(...args));
return promise.then(r => {
tracer.trace.end({
name,
id,

View File

@ -13,6 +13,7 @@ class AMDDefineDependency extends NullDependency {
this.functionRange = functionRange;
this.objectRange = objectRange;
this.namedModule = namedModule;
this.localModule = null;
}
get type() {

View File

@ -20,7 +20,9 @@ module.exports = class AMDRequireDependenciesBlock extends AsyncDependenciesBloc
this.expr = expr;
this.outerRange = expr.range;
this.arrayRange = arrayRange;
this.functionBindThis = false;
this.functionRange = functionRange;
this.errorCallbackBindThis = false;
this.errorCallbackRange = errorCallbackRange;
this.bindThis = true;
if (arrayRange && functionRange && errorCallbackRange) {

View File

@ -9,11 +9,13 @@ const CriticalDependencyWarning = require("./CriticalDependencyWarning");
const regExpToString = r => (r ? r + "" : "");
class ContextDependency extends Dependency {
// options: { request, recursive, regExp, include, exclude, mode, chunkName }
// options: { request, recursive, regExp, include, exclude, mode, chunkName, groupOptions }
constructor(options) {
super();
this.options = options;
this.userRequest = this.options.request;
/** @type {false | string} */
this.critical = false;
this.hadGlobalOrStickyRegExp = false;
if (this.options.regExp.global || this.options.regExp.sticky) {
this.options.regExp = null;
@ -27,7 +29,8 @@ class ContextDependency extends Dependency {
`${regExpToString(this.options.regExp)} ${regExpToString(
this.options.include
)} ${regExpToString(this.options.exclude)} ` +
`${this.options.mode} ${this.options.chunkName}`
`${this.options.mode} ${this.options.chunkName} ` +
`${JSON.stringify(this.options.groupOptions)}`
);
}
@ -47,6 +50,7 @@ class ContextDependency extends Dependency {
}
}
// TODO remove in webpack 5
Object.defineProperty(ContextDependency.prototype, "async", {
configurable: false,
get() {

View File

@ -16,7 +16,7 @@ class HarmonyAcceptImportDependency extends HarmonyImportDependency {
}
}
HarmonyAcceptImportDependency.Template = class HarmonyAcceptImportDependencyTemplate {
HarmonyAcceptImportDependency.Template = class HarmonyAcceptImportDependencyTemplate extends HarmonyImportDependency.Template {
apply(dep, source, runtime) {}
};

View File

@ -28,6 +28,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
this.callArgs = undefined;
this.call = undefined;
this.directImport = undefined;
this.shorthand = undefined;
}
get type() {

View File

@ -7,8 +7,9 @@ const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
const ImportDependency = require("./ImportDependency");
module.exports = class ImportDependenciesBlock extends AsyncDependenciesBlock {
constructor(request, range, chunkName, module, loc, originModule) {
super(chunkName, module, loc, request);
// TODO webpack 5 reorganize arguments
constructor(request, range, groupOptions, module, loc, originModule) {
super(groupOptions, module, loc, request);
this.range = range;
const dep = new ImportDependency(request, originModule, this);
dep.loc = loc;

View File

@ -29,11 +29,12 @@ class ImportParserPlugin {
let mode = "lazy";
let include = null;
let exclude = null;
const groupOptions = {};
const importOptions = parser.getCommentOptions(expr.range);
if (importOptions) {
if (typeof importOptions.webpackChunkName !== "undefined") {
if (typeof importOptions.webpackChunkName !== "string")
if (typeof importOptions.webpackChunkName !== "string") {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
@ -42,10 +43,12 @@ class ImportParserPlugin {
}.`
)
);
else chunkName = importOptions.webpackChunkName;
} else {
chunkName = importOptions.webpackChunkName;
}
}
if (typeof importOptions.webpackMode !== "undefined") {
if (typeof importOptions.webpackMode !== "string")
if (typeof importOptions.webpackMode !== "string") {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
@ -54,7 +57,41 @@ class ImportParserPlugin {
}.`
)
);
else mode = importOptions.webpackMode;
} else {
mode = importOptions.webpackMode;
}
}
if (typeof importOptions.webpackPrefetch !== "undefined") {
if (importOptions.webpackPrefetch === true) {
groupOptions.prefetchOrder = 0;
} else if (typeof importOptions.webpackPrefetch === "number") {
groupOptions.prefetchOrder = importOptions.webpackPrefetch;
} else {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackPrefetch\` expected true or a number, but received: ${
importOptions.webpackPrefetch
}.`
)
);
}
}
if (typeof importOptions.webpackPreload !== "undefined") {
if (importOptions.webpackPreload === true) {
groupOptions.preloadOrder = 0;
} else if (typeof importOptions.webpackPreload === "number") {
groupOptions.preloadOrder = importOptions.webpackPreload;
} else {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackPreload\` expected true or a number, but received: ${
importOptions.webpackPreload
}.`
)
);
}
}
if (typeof importOptions.webpackInclude !== "undefined") {
if (
@ -120,7 +157,9 @@ class ImportParserPlugin {
const depBlock = new ImportDependenciesBlock(
param.string,
expr.range,
chunkName,
Object.assign(groupOptions, {
name: chunkName
}),
parser.state.module,
expr.loc,
parser.state.module
@ -155,6 +194,7 @@ class ImportParserPlugin {
this.options,
{
chunkName,
groupOptions,
include,
exclude,
mode,

View File

@ -36,6 +36,7 @@ class LoaderPlugin {
}`
)
);
compilation.semaphore.release();
compilation.addModuleDependencies(
module,
[
@ -46,39 +47,41 @@ class LoaderPlugin {
],
true,
"lm",
false,
true,
err => {
if (err) return callback(err);
compilation.semaphore.acquire(() => {
if (err) return callback(err);
if (!dep.module)
return callback(new Error("Cannot load the module"));
if (!dep.module)
return callback(new Error("Cannot load the module"));
if (dep.module.error) return callback(dep.module.error);
if (!dep.module._source)
throw new Error(
"The module created for a LoaderDependency must have a property _source"
);
let source, map;
const moduleSource = dep.module._source;
if (moduleSource.sourceAndMap) {
const sourceAndMap = moduleSource.sourceAndMap();
map = sourceAndMap.map;
source = sourceAndMap.source;
} else {
map = moduleSource.map();
source = moduleSource.source();
}
if (dep.module.buildInfo.fileDependencies) {
for (const d of dep.module.buildInfo.fileDependencies) {
loaderContext.addDependency(d);
if (dep.module.error) return callback(dep.module.error);
if (!dep.module._source)
throw new Error(
"The module created for a LoaderDependency must have a property _source"
);
let source, map;
const moduleSource = dep.module._source;
if (moduleSource.sourceAndMap) {
const sourceAndMap = moduleSource.sourceAndMap();
map = sourceAndMap.map;
source = sourceAndMap.source;
} else {
map = moduleSource.map();
source = moduleSource.source();
}
}
if (dep.module.buildInfo.contextDependencies) {
for (const d of dep.module.buildInfo.contextDependencies) {
loaderContext.addContextDependency(d);
if (dep.module.buildInfo.fileDependencies) {
for (const d of dep.module.buildInfo.fileDependencies) {
loaderContext.addDependency(d);
}
}
}
return callback(null, source, map, dep.module);
if (dep.module.buildInfo.contextDependencies) {
for (const d of dep.module.buildInfo.contextDependencies) {
loaderContext.addContextDependency(d);
}
}
return callback(null, source, map, dep.module);
});
}
);
};

View File

@ -26,7 +26,8 @@ module.exports = expr => {
) {
return {
fn: expr.callee.object,
expressions: [expr.arguments[0]]
expressions: [expr.arguments[0]],
needThis: undefined
};
}
// (function(_this) {return <FunctionExpression>})(this) (Coffeescript)

View File

@ -3,35 +3,44 @@
Author Tobias Koppers @sokra
*/
"use strict";
const sortByIndex = (a, b) => {
return a.index - b.index;
};
const sortByIndex2 = (a, b) => {
return a.index2 - b.index2;
};
class ChunkModuleIdRangePlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
const options = this.options;
compiler.hooks.compilation.tap("ChunkModuleIdRangePlugin", compilation => {
compilation.hooks.moduleIds.tap("ChunkModuleIdRangePlugin", modules => {
const chunk = this.chunks.find(chunk => chunk.name === options.name);
if (!chunk)
const chunk = compilation.chunks.find(
chunk => chunk.name === options.name
);
if (!chunk) {
throw new Error(
"ChunkModuleIdRangePlugin: Chunk with name '" +
options.name +
"' was not found"
`ChunkModuleIdRangePlugin: Chunk with name '${
options.name
}"' was not found`
);
let currentId = options.start;
}
let chunkModules;
if (options.order) {
chunkModules = chunk.modules.slice();
chunkModules = Array.from(chunk.modulesIterable);
switch (options.order) {
case "index":
chunkModules.sort((a, b) => {
return a.index - b.index;
});
chunkModules.sort(sortByIndex);
break;
case "index2":
chunkModules.sort((a, b) => {
return a.index2 - b.index2;
});
chunkModules.sort(sortByIndex2);
break;
default:
throw new Error(
@ -40,10 +49,11 @@ class ChunkModuleIdRangePlugin {
}
} else {
chunkModules = modules.filter(m => {
return m.chunks.includes(chunk);
return m.chunksIterable.has(chunk);
});
}
let currentId = options.start || 0;
for (let i = 0; i < chunkModules.length; i++) {
const m = chunkModules[i];
if (m.id === null) {

View File

@ -148,15 +148,17 @@ class ModuleConcatenationPlugin {
nonHarmonyReasons.map(r => r.explanation).filter(Boolean)
);
const importingModuleTypes = new Map(
Array.from(importingModules).map(m => [
m,
new Set(
nonHarmonyReasons
.filter(r => r.module === m)
.map(r => r.dependency.type)
.sort()
)
])
Array.from(importingModules).map(
m => /** @type {[string, Set]} */ ([
m,
new Set(
nonHarmonyReasons
.filter(r => r.module === m)
.map(r => r.dependency.type)
.sort()
)
])
)
);
setBailoutReason(module, requestShortener => {
const names = Array.from(importingModules)

View File

@ -8,6 +8,7 @@ class Semaphore {
constructor(available) {
this.available = available;
this.waiters = [];
this._continue = this._continue.bind(this);
}
acquire(callback) {
@ -20,11 +21,19 @@ class Semaphore {
}
release() {
this.available++;
if (this.waiters.length > 0) {
const callback = this.waiters.pop();
process.nextTick(callback);
} else {
this.available++;
process.nextTick(this._continue);
}
}
_continue() {
if (this.available > 0) {
if (this.waiters.length > 0) {
this.available--;
const callback = this.waiters.pop();
callback();
}
}
}
}

View File

@ -11,7 +11,7 @@ class SortableSet extends Set {
/**
* @param {any} value - value to add to set
* @returns {SortableSet} - returns itself
* @returns {this} - returns itself
*/
add(value) {
this._lastActiveSortFn = null;
@ -33,11 +33,7 @@ class SortableSet extends Set {
return super.clear();
}
/**
* @param {Function} sortFn - function to sort the set
* @returns {void}
*/
sortWith(sortFn) {
sortWith(/** @type {(a: any, b: any) => number} */ sortFn) {
if (this.size === 0 || sortFn === this._lastActiveSortFn) {
// already sorted - nothing to do
return;

View File

@ -91,7 +91,10 @@ class StackedSetMap {
this._compress();
return Array.from(
this.map.entries(),
pair => (pair[1] === UNDEFINED_MARKER ? [pair[0], undefined] : pair)
pair =>
/** @type {[any, any]} */ (pair[1] === UNDEFINED_MARKER
? [pair[0], undefined]
: pair)
);
}

View File

@ -6,19 +6,14 @@
const mergeCache = new WeakMap();
const cachedMerge = (first, ...args) => {
if (args.length === 0) return first;
if (args.length > 1) {
return cachedMerge(first, cachedMerge(...args));
}
const second = args[0];
const cachedMerge = (first, second) => {
let innerCache = mergeCache.get(first);
if (innerCache === undefined) {
innerCache = new WeakMap();
mergeCache.set(first, innerCache);
}
const cachedMerge = innerCache.get(second);
if (cachedMerge !== undefined) return cachedMerge;
const prevMerge = innerCache.get(second);
if (prevMerge !== undefined) return prevMerge;
const newMerge = Object.assign({}, first, second);
innerCache.set(second, newMerge);
return newMerge;

View File

@ -6,5 +6,11 @@
* @returns {Map} an ES6 Map of KV pairs
*/
module.exports = function objectToMap(obj) {
return new Map(Object.keys(obj).map(key => [key, obj[key]]));
return new Map(
Object.keys(obj).map(key => {
/** @type {[string, string]} */
const pair = [key, obj[key]];
return pair;
})
);
};

View File

@ -36,84 +36,117 @@ class JsonpMainTemplatePlugin {
"hash"
]);
}
if (!mainTemplate.hooks.linkPreload) {
mainTemplate.hooks.linkPreload = new SyncWaterfallHook([
"source",
"chunk",
"hash"
]);
}
if (!mainTemplate.hooks.linkPrefetch) {
mainTemplate.hooks.linkPrefetch = new SyncWaterfallHook([
"source",
"chunk",
"hash"
]);
}
const getScriptSrcPath = (hash, chunk, chunkIdExpression) => {
const chunkFilename = mainTemplate.outputOptions.chunkFilename;
const chunkMaps = chunk.getChunkMaps();
return mainTemplate.getAssetPath(JSON.stringify(chunkFilename), {
hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
hashWithLength: length =>
`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
chunk: {
id: `" + ${chunkIdExpression} + "`,
hash: `" + ${JSON.stringify(
chunkMaps.hash
)}[${chunkIdExpression}] + "`,
hashWithLength(length) {
const shortChunkHashMap = Object.create(null);
for (const chunkId of Object.keys(chunkMaps.hash)) {
if (typeof chunkMaps.hash[chunkId] === "string")
shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(
0,
length
);
}
return `" + ${JSON.stringify(
shortChunkHashMap
)}[${chunkIdExpression}] + "`;
},
name: `" + (${JSON.stringify(
chunkMaps.name
)}[${chunkIdExpression}]||${chunkIdExpression}) + "`,
contentHash: {
javascript: `" + ${JSON.stringify(
chunkMaps.contentHash.javascript
)}[${chunkIdExpression}] + "`
},
contentHashWithLength: {
javascript: length => {
const shortContentHashMap = {};
const contentHash = chunkMaps.contentHash.javascript;
for (const chunkId of Object.keys(contentHash)) {
if (typeof contentHash[chunkId] === "string") {
shortContentHashMap[chunkId] = contentHash[chunkId].substr(
0,
length
);
}
}
return `" + ${JSON.stringify(
shortContentHashMap
)}[${chunkIdExpression}] + "`;
}
}
},
contentHashType: "javascript"
});
};
mainTemplate.hooks.localVars.tap(
"JsonpMainTemplatePlugin",
(source, chunk) => {
(source, chunk, hash) => {
if (needChunkLoadingCode(chunk)) {
return Template.asString([
source,
"",
"// object to store loaded and loading chunks",
"// undefined = chunk not loaded, null = chunk preloaded/prefetched",
"// Promise = chunk loading, 0 = chunk loaded",
"var installedChunks = {",
Template.indent(
chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(",\n")
),
"};",
"",
"// script path function",
"function jsonpScriptSrc(chunkId) {",
Template.indent([
`return ${mainTemplate.requireFn}.p + ${getScriptSrcPath(
hash,
chunk,
"chunkId"
)}`
]),
"}",
"",
needEntryDeferringCode(chunk) ? "var deferredModules = [];" : ""
]);
}
return source;
}
);
mainTemplate.hooks.jsonpScript.tap(
"JsonpMainTemplatePlugin",
(_, chunk, hash) => {
const chunkFilename = mainTemplate.outputOptions.chunkFilename;
const chunkMaps = chunk.getChunkMaps();
const crossOriginLoading =
mainTemplate.outputOptions.crossOriginLoading;
const chunkLoadTimeout = mainTemplate.outputOptions.chunkLoadTimeout;
const jsonpScriptType = mainTemplate.outputOptions.jsonpScriptType;
const scriptSrcPath = mainTemplate.getAssetPath(
JSON.stringify(chunkFilename),
{
hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
hashWithLength: length =>
`" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
chunk: {
id: '" + chunkId + "',
hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`,
hashWithLength(length) {
const shortChunkHashMap = Object.create(null);
for (const chunkId of Object.keys(chunkMaps.hash)) {
if (typeof chunkMaps.hash[chunkId] === "string")
shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr(
0,
length
);
}
return `" + ${JSON.stringify(shortChunkHashMap)}[chunkId] + "`;
},
name: `" + (${JSON.stringify(
chunkMaps.name
)}[chunkId]||chunkId) + "`,
contentHash: {
javascript: `" + ${JSON.stringify(
chunkMaps.contentHash.javascript
)}[chunkId] + "`
},
contentHashWithLength: {
javascript: length => {
const shortContentHashMap = {};
const contentHash = chunkMaps.contentHash.javascript;
for (const chunkId of Object.keys(contentHash)) {
if (typeof contentHash[chunkId] === "string") {
shortContentHashMap[chunkId] = contentHash[
chunkId
].substr(0, length);
}
}
return `" + ${JSON.stringify(
shortContentHashMap
)}[chunkId] + "`;
}
}
},
contentHashType: "javascript"
}
);
return Template.asString([
"var script = document.createElement('script');",
jsonpScriptType
@ -126,7 +159,7 @@ class JsonpMainTemplatePlugin {
`script.setAttribute("nonce", ${mainTemplate.requireFn}.nc);`
),
"}",
`script.src = ${mainTemplate.requireFn}.p + ${scriptSrcPath};`,
"script.src = jsonpScriptSrc(chunkId);",
crossOriginLoading
? `if (script.src.indexOf(window.location.origin)) {${Template.indent(
`script.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
@ -164,8 +197,47 @@ class JsonpMainTemplatePlugin {
]);
}
);
mainTemplate.hooks.requireEnsure.tap(
mainTemplate.hooks.linkPreload.tap(
"JsonpMainTemplatePlugin",
(_, chunk, hash) => {
const crossOriginLoading =
mainTemplate.outputOptions.crossOriginLoading;
const jsonpScriptType = mainTemplate.outputOptions.jsonpScriptType;
return Template.asString([
"var link = document.createElement('link');",
jsonpScriptType
? `link.type = ${JSON.stringify(jsonpScriptType)};`
: "",
"link.charset = 'utf-8';",
`if (${mainTemplate.requireFn}.nc) {`,
Template.indent(
`link.setAttribute("nonce", ${mainTemplate.requireFn}.nc);`
),
"}",
'link.rel = "preload";',
'link.as = "script";',
"link.href = jsonpScriptSrc(chunkId);",
crossOriginLoading
? `if (link.href.indexOf(window.location.origin)) {${Template.indent(
`link.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
)}}`
: ""
]);
}
);
mainTemplate.hooks.linkPrefetch.tap(
"JsonpMainTemplatePlugin",
(_, chunk, hash) => {
return Template.asString([
"var link = document.createElement('link');",
'link.rel = "prefetch";',
"link.href = jsonpScriptSrc(chunkId);"
]);
}
);
mainTemplate.hooks.requireEnsure.tap(
"JsonpMainTemplatePlugin load",
(source, chunk, hash) => {
return Template.asString([
source,
@ -200,6 +272,80 @@ class JsonpMainTemplatePlugin {
]);
}
);
mainTemplate.hooks.requireEnsure.tap(
{
name: "JsonpMainTemplatePlugin preload",
stage: 10
},
(source, chunk, hash) => {
const chunkMap = chunk.getChildIdsByOrdersMap().preload;
if (!chunkMap || Object.keys(chunkMap).length === 0) return source;
return Template.asString([
source,
"",
"// chunk preloadng for javascript",
"",
`var chunkPreloadMap = ${JSON.stringify(chunkMap, null, "\t")}`,
"",
"var chunkPreloadData = chunkPreloadMap[chunkId];",
"if(chunkPreloadData) {",
Template.indent([
"var head = document.getElementsByTagName('head')[0];",
"chunkPreloadData.forEach(function(chunkId) {",
Template.indent([
"if(installedChunks[chunkId] === undefined) {",
Template.indent([
"installedChunks[chunkId] = null;",
mainTemplate.hooks.linkPreload.call("", chunk, hash),
"head.appendChild(link);"
]),
"}"
]),
"});"
]),
"}"
]);
}
);
mainTemplate.hooks.requireEnsure.tap(
{
name: "JsonpMainTemplatePlugin prefetch",
stage: 20
},
(source, chunk, hash) => {
const chunkMap = chunk.getChildIdsByOrdersMap().prefetch;
if (!chunkMap || Object.keys(chunkMap).length === 0) return source;
return Template.asString([
source,
"",
"// chunk prefetching for javascript",
"",
`var chunkPrefetchMap = ${JSON.stringify(chunkMap, null, "\t")}`,
"",
"var chunkPrefetchData = chunkPrefetchMap[chunkId];",
"if(chunkPrefetchData) {",
Template.indent([
"Promise.all(promises).then(function() {",
Template.indent([
"var head = document.getElementsByTagName('head')[0];",
"chunkPrefetchData.forEach(function(chunkId) {",
Template.indent([
"if(installedChunks[chunkId] === undefined) {",
Template.indent([
"installedChunks[chunkId] = null;",
mainTemplate.hooks.linkPrefetch.call("", chunk, hash),
"head.appendChild(link);"
]),
"}"
]),
"});"
]),
"})"
]),
"}"
]);
}
);
mainTemplate.hooks.requireExtensions.tap(
"JsonpMainTemplatePlugin",
(source, chunk) => {

View File

@ -1,6 +1,6 @@
{
"name": "webpack",
"version": "4.5.0",
"version": "4.6.0",
"author": "Tobias Koppers @sokra",
"description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
"license": "MIT",
@ -19,13 +19,15 @@
"mkdirp": "~0.5.0",
"neo-async": "^2.5.0",
"node-libs-browser": "^2.0.0",
"schema-utils": "^0.4.2",
"schema-utils": "^0.4.4",
"tapable": "^1.0.0",
"uglifyjs-webpack-plugin": "^1.2.4",
"watchpack": "^1.5.0",
"webpack-sources": "^1.0.1"
},
"devDependencies": {
"@types/node": "^9.6.4",
"@types/tapable": "^1.0.1",
"benchmark": "^2.1.1",
"bundle-loader": "~0.5.0",
"codacy-coverage": "^2.0.1",
@ -61,11 +63,12 @@
"simple-git": "^1.65.0",
"sinon": "^2.3.2",
"style-loader": "^0.19.1",
"typescript": "^2.9.0-dev.20180412",
"url-loader": "^0.6.2",
"val-loader": "^1.0.2",
"vm-browserify": "~0.0.0",
"webpack-dev-middleware": "^1.9.0",
"worker-loader": "^1.1.0",
"worker-loader": "^1.1.1",
"xxhashjs": "^0.2.1"
},
"engines": {
@ -105,10 +108,11 @@
"build:examples": "cd examples && node buildAll.js",
"pretest": "yarn lint",
"prelint": "yarn setup",
"lint": "yarn code-lint && yarn schema-lint",
"lint": "yarn code-lint && yarn schema-lint && yarn type-lint",
"code-lint": "eslint setup lib bin hot buildin \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\"",
"type-lint": "tsc --pretty",
"fix": "yarn code-lint --fix",
"pretty": "prettier \"setup/**/*.js\" \"lib/**/*.js\" \"bin/*.js\" \"hot/*.js\" \"buildin/*.js\" \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\" --write",
"pretty": "prettier \"setup/**/*.js\" \"lib/**/*.js\" \"bin/*.js\" \"hot/*.js\" \"buildin/*.js\" \"test/*.js\" \"test/**/webpack.config.js\" \"examples/**/webpack.config.js\" \"schemas/**/*.js\" \"declarations.d.ts\" --write",
"schema-lint": "mocha test/*.lint.js --opts test/lint-mocha.opts",
"benchmark": "mocha --max-old-space-size=4096 --harmony --trace-deprecation test/*.benchmark.js -R spec",
"cover": "yarn cover:init && yarn cover:all && yarn cover:report",

View File

@ -11,7 +11,7 @@ const checkArrayExpectation = require("./checkArrayExpectation");
const Stats = require("../lib/Stats");
const webpack = require("../lib/webpack");
const prepareOptions = require("../lib/prepareOptions");
const prepareOptions = require("./helpers/prepareOptions");
describe("ConfigTestCases", () => {
const casesPath = path.join(__dirname, "configCases");
@ -149,8 +149,18 @@ describe("ConfigTestCases", () => {
return test;
}
function _beforeEach(title, fn) {
return suite.beforeEach(title, fn);
}
function _afterEach(title, fn) {
return suite.afterEach(title, fn);
}
const globalContext = {
console: console
console: console,
setTimeout: setTimeout,
clearTimeout: clearTimeout
};
function _require(currentDirectory, module) {
@ -175,7 +185,7 @@ describe("ConfigTestCases", () => {
options.target === "webworker"
) {
fn = vm.runInNewContext(
"(function(require, module, exports, __dirname, __filename, it, window) {" +
"(function(require, module, exports, __dirname, __filename, it, beforeEach, afterEach, window) {" +
content +
"\n})",
globalContext,
@ -183,7 +193,7 @@ describe("ConfigTestCases", () => {
);
} else {
fn = vm.runInThisContext(
"(function(require, module, exports, __dirname, __filename, it) {" +
"(function(require, module, exports, __dirname, __filename, it, beforeEach, afterEach) {" +
content +
"\n})",
p
@ -200,6 +210,8 @@ describe("ConfigTestCases", () => {
path.dirname(p),
p,
_it,
_beforeEach,
_afterEach,
globalContext
);
return m.exports;

View File

@ -4,14 +4,15 @@ require("should");
describe("removed plugin errors", () => {
it("should error when accessing removed plugins", () => {
(() => webpack.optimize.UglifyJsPlugin).should.throw(
RemovedPluginError,
/webpack\.optimize\.UglifyJsPlugin has been removed, please use config\.optimization\.minimize instead\./
);
(() => webpack.optimize.UglifyJsPlugin).should.throw(RemovedPluginError, {
message: /webpack\.optimize\.UglifyJsPlugin has been removed, please use config\.optimization\.minimize instead\./
});
(() => webpack.optimize.CommonsChunkPlugin).should.throw(
RemovedPluginError,
/webpack\.optimize\.CommonsChunkPlugin has been removed, please use config\.optimization\.splitChunks instead\./
{
message: /webpack\.optimize\.CommonsChunkPlugin has been removed, please use config\.optimization\.splitChunks instead\./
}
);
});
});

View File

@ -43,5 +43,10 @@ describe("SizeFormatHelpers", () => {
"1.2 GiB"
);
});
it("should handle undefined/NaN", () => {
should(SizeFormatHelpers.formatSize(undefined)).be.eql("unknown size");
should(SizeFormatHelpers.formatSize(NaN)).be.eql("unknown size");
});
});
});

View File

@ -0,0 +1,4 @@
module.exports = function(config) {
// This test can't run in development mode as it depends on the flagIncludedChunks optimization
return config.mode !== "development";
};

View File

@ -0,0 +1 @@
module.exports = "a";

View File

@ -0,0 +1 @@
module.exports = require("c");

View File

@ -0,0 +1 @@
module.exports = "c";

View File

@ -0,0 +1,3 @@
it("should resolve module dependencies recursively", function() {
require("!./loaders/index!a").should.be.eql("c");
});

View File

@ -0,0 +1,9 @@
module.exports = function() {
var callback = this.async();
this.loadModule("b", function(error) {
if (error) {
return callback(error);
}
callback(null, "module.exports = require('b');");
});
};

View File

@ -0,0 +1,7 @@
{
"browser": {
"a": "./a.js",
"b": "./b.js",
"c": "./c.js"
}
}

View File

@ -0,0 +1,8 @@
it("should allow random comments in import()", () => {
return Promise.all([
import(/* hello world */ "./module"),
import(/* }); */ "./module"),
import(/* test */ "./module"),
import(/* 1234 */ "./module")
]);
});

View File

@ -0,0 +1,4 @@
it("should not deadlock when using loadModule", () => {
const result = require("./loader!");
result.should.match(/console.log\(42\)/);
});

View File

@ -0,0 +1,15 @@
module.exports = function() {
const callback = this.async();
let finished = false;
this.loadModule("./module.js", (err, result) => {
if (err) return callback(err);
if (finished) return;
finished = true;
callback(null, `module.exports = ${JSON.stringify(result)};`);
});
setTimeout(() => {
if (finished) return;
finished = true;
callback(new Error("loadModule is hanging"));
}, 2000);
};

View File

@ -0,0 +1 @@
console.log(42);

View File

@ -0,0 +1,3 @@
module.exports = {
parallelism: 1
};

View File

@ -0,0 +1,17 @@
const should = require("should");
const FakeDocument = require("../../../helpers/FakeDocument");
beforeEach(() => {
global.document = new FakeDocument();
});
afterEach(() => {
delete global.document;
})
it("should be able to load the split chunk on demand", () => {
const promise = import(/* webpackChunkName: "shared" */ "./shared");
const script = document.head._children[0];
should(script.src).be.eql("dep~b~shared.js");
});

View File

@ -0,0 +1 @@
import "./shared";

View File

@ -0,0 +1,5 @@
module.exports = {
findBundle: function(i, options) {
return ["runtime.js", "a.js"];
}
};

View File

@ -0,0 +1,24 @@
const path = require("path");
module.exports = {
entry: {
a: "./a",
b: "./b"
},
target: "web",
output: {
filename: "[name].js"
},
optimization: {
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
dep: {
chunks: "all",
test: path.resolve(__dirname, "shared.js"),
enforce: true
}
}
}
}
};

View File

@ -0,0 +1,5 @@
export default function() {
import(/* webpackPrefetch: true, webpackChunkName: "chunk1-a" */ "./chunk1-a");
import(/* webpackPreload: true, webpackChunkName: "chunk1-b" */ "./chunk1-b");
import(/* webpackPrefetch: 10, webpackChunkName: "chunk1-c" */ "./chunk1-c");
}

View File

@ -0,0 +1,57 @@
const should = require("should");
const FakeDocument = require("../../../helpers/FakeDocument");
let oldNonce;
let oldPublicPath;
beforeEach(() => {
oldNonce = __webpack_nonce__;
oldPublicPath = __webpack_public_path__;
global.document = new FakeDocument();
});
afterEach(() => {
delete global.document;
__webpack_nonce__ = oldNonce;
__webpack_public_path__ = oldPublicPath;
})
it("should prefetch and preload child chunks on chunk load", () => {
__webpack_nonce__ = "nonce";
__webpack_public_path__ = "/public/path/";
const promise = import(/* webpackChunkName: "chunk1" */ "./chunk1");
document.head._children.length.should.be.eql(2);
const script = document.head._children[0];
script._type.should.be.eql("script");
should(script.src).be.eql("/public/path/chunk1.js")
should(script.getAttribute("nonce")).be.eql("nonce")
should(script.crossOrigin).be.eql("anonymous");
should(script.onload).be.type("function");
let link = document.head._children[1];
link._type.should.be.eql("link");
should(link.rel).be.eql("preload");
should(link.as).be.eql("script");
should(link.href).be.eql("/public/path/chunk1-b.js");
should(link.charset).be.eql("utf-8");
should(link.getAttribute("nonce")).be.eql("nonce");
should(link.crossOrigin).be.eql("anonymous");
__non_webpack_require__("./chunk1.js");
script.onload();
return promise.then((ex) => {
document.head._children.length.should.be.eql(4);
let link = document.head._children[2];
link._type.should.be.eql("link");
should(link.rel).be.eql("prefetch");
should(link.href).be.eql("/public/path/chunk1-c.js");
link = document.head._children[3];
link._type.should.be.eql("link");
should(link.rel).be.eql("prefetch");
should(link.href).be.eql("/public/path/chunk1-a.js");
});
})

View File

@ -0,0 +1,13 @@
module.exports = {
target: "web",
output: {
chunkFilename: "[name].js",
crossOriginLoading: "anonymous"
},
performance: {
hints: false
},
optimization: {
minimize: false
}
};

View File

@ -0,0 +1,36 @@
module.exports = class FakeDocument {
constructor() {
this.head = this.createElement("head");
}
createElement(type) {
return new FakeElement(type);
}
getElementsByTagName(name) {
if (name === "head") return [this.head];
throw new Error(
`FakeDocument.getElementsByTagName(${name}): not implemented`
);
}
};
class FakeElement {
constructor(type) {
this._type = type;
this._children = [];
this._attributes = Object.create(null);
}
appendChild(node) {
this._children.push(node);
}
setAttribute(name, value) {
this._attributes[name] = value;
}
getAttribute(name) {
return this._attributes[name];
}
}

View File

@ -0,0 +1,3 @@
export default 1;
---
export default 2;

View File

@ -0,0 +1 @@
import "./module";

View File

@ -0,0 +1,19 @@
import value1 from "./a";
it("should have the expected static path defined", function() {
DEFINE_PATH.should.be.eql('./a');
});
it("should hot.accept the module located at the static file path without breaking the compiler", function() {
module.hot.accept("./a");
value1.should.be.eql(1);
});
it("should hot.accept the module located at the defined file path without breaking the compiler, when one argument is passed to hot.accept", function() {
module.hot.accept(DEFINE_PATH);
});
it("should hot.accept the module located at the defined file path without breaking the compiler, when multiple arguments are passed to hot.accept", function(done) {
module.hot.accept(DEFINE_PATH, () => done());
NEXT(require("../../update")(done));
});

View File

@ -0,0 +1,11 @@
"use strict";
const webpack = require("../../../../");
module.exports = {
plugins: [
new webpack.DefinePlugin({
DEFINE_PATH: JSON.stringify("./a")
})
]
};

View File

@ -1,18 +1,18 @@
Hash: a82dbd8d6c7a22df1cafa82dbd8d6c7a22df1caf
Hash: e3ba3c1dddc97b92dbf7e3ba3c1dddc97b92dbf7
Child fitting:
Hash: a82dbd8d6c7a22df1caf
Hash: e3ba3c1dddc97b92dbf7
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
fb95acf7c457672e70d0.js 1.05 KiB 0 [emitted]
a1e683753eca705a0882.js 9.97 KiB 1 [emitted]
2795fd99577b4ba7fef2.js 10.2 KiB 1 [emitted]
d43339a3d0f86c6b8d90.js 1.94 KiB 2 [emitted]
6c7fb52c5514dbfbf094.js 1.94 KiB 3 [emitted]
Entrypoint main = d43339a3d0f86c6b8d90.js 6c7fb52c5514dbfbf094.js a1e683753eca705a0882.js
Entrypoint main = d43339a3d0f86c6b8d90.js 6c7fb52c5514dbfbf094.js 2795fd99577b4ba7fef2.js
chunk {0} fb95acf7c457672e70d0.js 916 bytes <{1}> <{2}> <{3}>
> ./g [4] ./index.js 7:0-13
[7] ./g.js 916 bytes {0} [built]
chunk {1} a1e683753eca705a0882.js 1.87 KiB ={2}= ={3}= >{0}< [entry] [rendered]
chunk {1} 2795fd99577b4ba7fef2.js 1.87 KiB ={2}= ={3}= >{0}< [entry] [rendered]
> ./index main
[3] ./e.js 899 bytes {1} [built]
[4] ./index.js 111 bytes {1} [built]
@ -26,19 +26,19 @@ Child fitting:
[1] ./c.js 899 bytes {3} [built]
[2] ./d.js 899 bytes {3} [built]
Child content-change:
Hash: a82dbd8d6c7a22df1caf
Hash: e3ba3c1dddc97b92dbf7
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
fb95acf7c457672e70d0.js 1.05 KiB 0 [emitted]
a1e683753eca705a0882.js 9.97 KiB 1 [emitted]
2795fd99577b4ba7fef2.js 10.2 KiB 1 [emitted]
d43339a3d0f86c6b8d90.js 1.94 KiB 2 [emitted]
6c7fb52c5514dbfbf094.js 1.94 KiB 3 [emitted]
Entrypoint main = d43339a3d0f86c6b8d90.js 6c7fb52c5514dbfbf094.js a1e683753eca705a0882.js
Entrypoint main = d43339a3d0f86c6b8d90.js 6c7fb52c5514dbfbf094.js 2795fd99577b4ba7fef2.js
chunk {0} fb95acf7c457672e70d0.js 916 bytes <{1}> <{2}> <{3}>
> ./g [4] ./index.js 7:0-13
[7] ./g.js 916 bytes {0} [built]
chunk {1} a1e683753eca705a0882.js 1.87 KiB ={2}= ={3}= >{0}< [entry] [rendered]
chunk {1} 2795fd99577b4ba7fef2.js 1.87 KiB ={2}= ={3}= >{0}< [entry] [rendered]
> ./index main
[3] ./e.js 899 bytes {1} [built]
[4] ./index.js 111 bytes {1} [built]

View File

@ -1,4 +1,4 @@
Hash: 7a73868d9be286944b0a
Hash: 0bbde62e97b9652dcaac
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
@ -12,9 +12,9 @@ aafb9d82e452def4c3bb.js 1 KiB 1 [emitted]
344e13508b62e833aacf.js 1 KiB 7 [emitted]
2aaed192bbfbc2302c53.js 1.94 KiB 8 [emitted]
72e04d4eaed46d9aac4c.js 1.94 KiB 9 [emitted]
d20b83dfd7d0fd0c8793.js 8.41 KiB 10 [emitted] main
d19dabec0d62bca26765.js 8.68 KiB 10 [emitted] main
1165c0cca1ba14a506ff.js 1.94 KiB 11 [emitted]
Entrypoint main = d20b83dfd7d0fd0c8793.js
Entrypoint main = d19dabec0d62bca26765.js
chunk {0} 4467a9f70ef8365bcb32.js 1.76 KiB <{10}> ={1}= ={2}= ={3}= ={7}= ={9}= [recorded] aggressive splitted
> ./b ./d ./e ./f ./g [11] ./index.js 5:0-44
> ./b ./d ./e ./f ./g ./h ./i ./j ./k [11] ./index.js 6:0-72
@ -56,7 +56,7 @@ chunk {9} 72e04d4eaed46d9aac4c.js 1.76 KiB <{10}> ={0}= ={2}= ={3}= ={7}= [re
> ./b ./d ./e ./f ./g ./h ./i ./j ./k [11] ./index.js 6:0-72
[7] ./i.js 899 bytes {9} {11} [built]
[8] ./j.js 901 bytes {6} {9} [built]
chunk {10} d20b83dfd7d0fd0c8793.js (main) 248 bytes >{0}< >{1}< >{11}< >{2}< >{3}< >{4}< >{5}< >{6}< >{7}< >{8}< >{9}< [entry] [rendered]
chunk {10} d19dabec0d62bca26765.js (main) 248 bytes >{0}< >{1}< >{11}< >{2}< >{3}< >{4}< >{5}< >{6}< >{7}< >{8}< >{9}< [entry] [rendered]
> ./index main
[11] ./index.js 248 bytes {10} [built]
chunk {11} 1165c0cca1ba14a506ff.js 1.76 KiB <{10}> ={2}= ={6}= [rendered] [recorded] aggressive splitted

View File

@ -1,14 +1,14 @@
Entrypoint main = main.js
chunk {0} 0.js 21 bytes <{3}> ={1}= ={2}= [rendered] reused as split chunk (cache group: default)
> [3] ./index.js 17:1-21:3
chunk {0} 0.js 21 bytes <{3}> [rendered] reused as split chunk (cache group: default)
> [3] ./index.js 2:1-5:3
[0] ./a.js 21 bytes {0} {1} {2} [built]
chunk {1} 1.js 42 bytes <{3}> [rendered]
> ./a ./b [3] ./index.js 9:1-13:3
[0] ./a.js 21 bytes {0} [built]
chunk {1} 1.js 21 bytes <{3}> ={0}= [rendered]
> ./a ./b [3] ./index.js 9:1-13:3
[0] ./a.js 21 bytes {0} {1} {2} [built]
[1] ./b.js 21 bytes {1} [built]
chunk {2} 2.js 21 bytes <{3}> ={0}= [rendered]
chunk {2} 2.js 42 bytes <{3}> [rendered]
> [3] ./index.js 17:1-21:3
[0] ./a.js 21 bytes {0} {1} {2} [built]
[2] ./c.js 21 bytes {2} [built]
chunk {3} main.js (main) 550 bytes >{0}< >{1}< >{2}< [entry] [rendered]
> ./ main

View File

@ -0,0 +1 @@
export default "a";

View File

@ -0,0 +1 @@
export default "b";

View File

@ -0,0 +1 @@
export default "c";

View File

@ -0,0 +1 @@
export default "d";

View File

@ -0,0 +1 @@
export default "e";

View File

@ -0,0 +1,22 @@
Hash: 27b68d27e07b42624dae
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
main2.js 3.89 KiB 0 [emitted] main2
main1.js 3.89 KiB 1 [emitted] main1
Entrypoint main1 = main1.js
Entrypoint main2 = main2.js
chunk {0} main2.js (main2) 136 bytes [entry] [rendered]
> ./main2 main2
[0] ./e.js 20 bytes {0} [built]
[1] ./f.js 20 bytes {0} [built]
[2] ./main2.js 56 bytes {0} [built]
[100] ./d.js 20 bytes {0} {1} [built]
[101] ./a.js 20 bytes {0} {1} [built]
chunk {1} main1.js (main1) 136 bytes [entry] [rendered]
> ./main1 main1
[3] ./b.js 20 bytes {1} [built]
[4] ./main1.js 56 bytes {1} [built]
[100] ./d.js 20 bytes {0} {1} [built]
[101] ./a.js 20 bytes {0} {1} [built]
[102] ./c.js 20 bytes {1} [built]

View File

@ -0,0 +1 @@
export default "f";

View File

@ -0,0 +1,4 @@
import "./a";
import "./b";
import "./c";
import "./d";

View File

@ -0,0 +1,4 @@
import "./a";
import "./d";
import "./e";
import "./f";

View File

@ -0,0 +1,28 @@
const webpack = require("../../../");
module.exports = {
mode: "none",
entry: {
main1: "./main1",
main2: "./main2"
},
plugins: [
new webpack.optimize.ChunkModuleIdRangePlugin({
name: "main1",
start: 100,
end: 102
}),
new webpack.optimize.ChunkModuleIdRangePlugin({
name: "main2",
order: "index2"
})
],
stats: {
chunks: true,
chunkModules: true,
chunkOrigins: true,
entrypoints: true,
modules: false,
publicPath: true
}
};

View File

@ -1,11 +1,11 @@
Hash: e81afb52ad447e8765ab
Hash: d8b40b77893587325329
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
0.bundle.js 433 bytes 0 [emitted]
1.bundle.js 297 bytes 1 [emitted]
2.bundle.js 588 bytes 2 [emitted]
bundle.js 7.38 KiB main [emitted] main
bundle.js 7.65 KiB main [emitted] main
Entrypoint main = bundle.js
chunk {main} bundle.js (main) 73 bytes >{0}< >{1}< [entry] [rendered]
> ./index main

View File

@ -1,10 +1,10 @@
Hash: 4a1bda30edd6ae541ab2
Hash: e99cd61934506d7567a3
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
0.bundle.js 152 bytes 0 [emitted]
1.bundle.js 289 bytes 1 [emitted]
bundle.js 7 KiB 2 [emitted] main
bundle.js 7.27 KiB 2 [emitted] main
3.bundle.js 227 bytes 3 [emitted]
Entrypoint main = bundle.js
chunk {0} 0.bundle.js 22 bytes <{2}> [rendered]

View File

@ -2,7 +2,7 @@ Hash: cad25b99a073374722a7
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
entry-1.js 5.49 KiB 0 [emitted] entry-1
entry-1.js 5.79 KiB 0 [emitted] entry-1
vendor-1~entry-1.js 314 bytes 1 [emitted] vendor-1~entry-1
Entrypoint entry-1 = vendor-1~entry-1.js entry-1.js
[0] ./entry-1.js 145 bytes {0} [built]

View File

@ -2,7 +2,7 @@ Hash: c176225f44e51c7a39a4
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
entry-1.js 5.49 KiB 0 [emitted] entry-1
entry-1.js 5.79 KiB 0 [emitted] entry-1
vendor-1.js 314 bytes 1 [emitted] vendor-1
Entrypoint entry-1 = vendor-1.js entry-1.js
[0] ./entry-1.js 145 bytes {0} [built]

View File

@ -4,7 +4,7 @@ Child
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
app.js 5.58 KiB 0 [emitted] app
app.js 5.9 KiB 0 [emitted] app
vendor.c0e73bece4137a7015c2.js 619 bytes 1 [emitted] vendor
Entrypoint app = vendor.c0e73bece4137a7015c2.js app.js
[./constants.js] 87 bytes {1} [built]
@ -17,7 +17,7 @@ Child
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
app.js 5.59 KiB 0 [emitted] app
app.js 5.92 KiB 0 [emitted] app
vendor.c0e73bece4137a7015c2.js 619 bytes 1 [emitted] vendor
Entrypoint app = vendor.c0e73bece4137a7015c2.js app.js
[./constants.js] 87 bytes {1} [built]

View File

@ -1,11 +1,11 @@
Hash: 20afe8e9eb9a69aecddb
Hash: 736289137c8313a6d802
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
0.js 305 bytes 0 [emitted]
1.js 314 bytes 1 [emitted]
2.js 308 bytes 2 [emitted]
entry.js 7.8 KiB 3 [emitted] entry
entry.js 8.07 KiB 3 [emitted] entry
Entrypoint entry = entry.js
[0] ./templates/bar.js 38 bytes {0} [optional] [built]
[1] ./templates/baz.js 38 bytes {1} [optional] [built]

View File

@ -1,9 +1,9 @@
Hash: 1f9db3ad053a3687e3bb
Hash: 1c55fc2d238369c62239
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
0.js 149 bytes 0 [emitted]
entry.js 7.79 KiB 1 [emitted] entry
entry.js 8.06 KiB 1 [emitted] entry
Entrypoint entry = entry.js
[0] ./modules/b.js 22 bytes {0} [built]
[1] ./entry.js 120 bytes {1} [built]

View File

@ -1,10 +1,10 @@
Hash: 599eb45be3863921e183f90c7b21ae5c6e853a0df3a313c9918d7d712c3f113bf580db9e5c6196ce
Hash: 89bb5076b735d47082582924d303eb8bcffb1c785cc24ae5dbdd7c6bafb935e3a49d38d6f5cc7854
Child 1 chunks:
Hash: 599eb45be3863921e183
Hash: 89bb5076b735d4708258
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
bundle.js 5.68 KiB 0 [emitted] main
bundle.js 5.98 KiB 0 [emitted] main
Entrypoint main = bundle.js
chunk {0} bundle.js (main) 191 bytes <{0}> >{0}< [entry] [rendered]
[0] ./index.js 73 bytes {0} [built]
@ -14,12 +14,12 @@ Child 1 chunks:
[4] ./d.js 22 bytes {0} [built]
[5] ./e.js 22 bytes {0} [built]
Child 2 chunks:
Hash: f90c7b21ae5c6e853a0d
Hash: 2924d303eb8bcffb1c78
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
0.bundle.js 1 KiB 0 [emitted]
bundle.js 7.19 KiB 1 [emitted] main
bundle.js 7.46 KiB 1 [emitted] main
Entrypoint main = bundle.js
chunk {0} 0.bundle.js 118 bytes <{0}> <{1}> >{0}< [rendered]
[0] ./d.js 22 bytes {0} [built]
@ -30,13 +30,13 @@ Child 2 chunks:
chunk {1} bundle.js (main) 73 bytes >{0}< [entry] [rendered]
[5] ./index.js 73 bytes {1} [built]
Child 3 chunks:
Hash: f3a313c9918d7d712c3f
Hash: 5cc24ae5dbdd7c6bafb9
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
0.bundle.js 886 bytes 0 [emitted]
1.bundle.js 245 bytes 1 [emitted]
bundle.js 7.19 KiB 2 [emitted] main
bundle.js 7.46 KiB 2 [emitted] main
Entrypoint main = bundle.js
chunk {0} 0.bundle.js 74 bytes <{0}> <{2}> >{0}< >{1}< [rendered]
[0] ./d.js 22 bytes {0} [built]
@ -48,14 +48,14 @@ Child 3 chunks:
chunk {2} bundle.js (main) 73 bytes >{0}< >{1}< [entry] [rendered]
[5] ./index.js 73 bytes {2} [built]
Child 4 chunks:
Hash: 113bf580db9e5c6196ce
Hash: 35e3a49d38d6f5cc7854
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Asset Size Chunks Chunk Names
0.bundle.js 236 bytes 0 [emitted]
1.bundle.js 245 bytes 1 [emitted]
2.bundle.js 715 bytes 2 [emitted]
bundle.js 7.19 KiB 3 [emitted] main
bundle.js 7.46 KiB 3 [emitted] main
Entrypoint main = bundle.js
chunk {0} 0.bundle.js 44 bytes <{2}> <{3}> [rendered]
[0] ./d.js 22 bytes {0} [built]

View File

@ -1,4 +1,4 @@
Hash: d71bd16b0b20f34e994a
Hash: 021e4419d6957e08eedd
Time: Xms
Built at: Thu Jan 01 1970 00:00:00 GMT
Entrypoint main = main.js

View File

@ -2,9 +2,9 @@
async3.js 818 bytes 0 [emitted] async3
async1.js 818 bytes 1 [emitted] async1
async2.js 818 bytes 2 [emitted] async2
e1.js 8.02 KiB 3 [emitted] e1
e2.js 8.05 KiB 4 [emitted] e2
e3.js 8.07 KiB 5 [emitted] e3
e1.js 8.29 KiB 3 [emitted] e1
e2.js 8.31 KiB 4 [emitted] e2
e3.js 8.33 KiB 5 [emitted] e3
Entrypoint e1 = e1.js
Entrypoint e2 = e2.js
Entrypoint e3 = e3.js

View File

@ -5,9 +5,9 @@ Asset Size Chunks Chunk Names
3.js 661 bytes 3 [emitted]
4.js 661 bytes 4 [emitted]
5.js 661 bytes 5 [emitted]
e1.js 8.14 KiB 6 [emitted] e1
e2.js 8.16 KiB 7 [emitted] e2
e3.js 8.18 KiB 8 [emitted] e3
e1.js 8.4 KiB 6 [emitted] e1
e2.js 8.43 KiB 7 [emitted] e2
e3.js 8.45 KiB 8 [emitted] e3
Entrypoint e1 = e1.js
Entrypoint e2 = e2.js
Entrypoint e3 = e3.js

Some files were not shown because too many files have changed in this diff Show More