webpack 4.37.0 → 4.39.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/lib/BannerPlugin.js +4 -6
- package/lib/Chunk.js +5 -1
- package/lib/ChunkGroup.js +13 -13
- package/lib/Compilation.js +5 -477
- package/lib/Compiler.js +11 -4
- package/lib/Entrypoint.js +2 -2
- package/lib/MultiCompiler.js +8 -1
- package/lib/ProgressPlugin.js +21 -63
- package/lib/SourceMapDevToolPlugin.js +25 -17
- package/lib/Stats.js +8 -2
- package/lib/SystemMainTemplatePlugin.js +5 -1
- package/lib/TemplatedPathPlugin.js +8 -1
- package/lib/WebpackOptionsDefaulter.js +6 -1
- package/lib/buildChunkGraph.js +689 -0
- package/lib/debug/ProfilingPlugin.js +1 -1
- package/lib/logging/Logger.js +6 -1
- package/lib/logging/createConsoleLogger.js +46 -25
- package/lib/logging/runtime.js +2 -1
- package/lib/logging/truncateArgs.js +76 -0
- package/lib/node/NodeEnvironmentPlugin.js +3 -1
- package/lib/node/nodeConsole.js +135 -0
- package/lib/web/JsonpMainTemplatePlugin.js +1 -1
- package/package.json +18 -20
package/lib/Compiler.js
CHANGED
@@ -55,6 +55,8 @@ class Compiler extends Tapable {
|
|
55
55
|
run: new AsyncSeriesHook(["compiler"]),
|
56
56
|
/** @type {AsyncSeriesHook<Compilation>} */
|
57
57
|
emit: new AsyncSeriesHook(["compilation"]),
|
58
|
+
/** @type {AsyncSeriesHook<string, Buffer>} */
|
59
|
+
assetEmitted: new AsyncSeriesHook(["file", "content"]),
|
58
60
|
/** @type {AsyncSeriesHook<Compilation>} */
|
59
61
|
afterEmit: new AsyncSeriesHook(["compilation"]),
|
60
62
|
|
@@ -86,7 +88,7 @@ class Compiler extends Tapable {
|
|
86
88
|
watchClose: new SyncHook([]),
|
87
89
|
|
88
90
|
/** @type {SyncBailHook<string, string, any[]>} */
|
89
|
-
|
91
|
+
infrastructureLog: new SyncBailHook(["origin", "type", "args"]),
|
90
92
|
|
91
93
|
// TODO the following hooks are weirdly located here
|
92
94
|
// TODO move them for webpack 5
|
@@ -101,6 +103,8 @@ class Compiler extends Tapable {
|
|
101
103
|
/** @type {SyncBailHook<string, Entry>} */
|
102
104
|
entryOption: new SyncBailHook(["context", "entry"])
|
103
105
|
};
|
106
|
+
// TODO webpack 5 remove this
|
107
|
+
this.hooks.infrastructurelog = this.hooks.infrastructureLog;
|
104
108
|
|
105
109
|
this._pluginCompat.tap("Compiler", options => {
|
106
110
|
switch (options.name) {
|
@@ -221,7 +225,7 @@ class Compiler extends Tapable {
|
|
221
225
|
);
|
222
226
|
}
|
223
227
|
}
|
224
|
-
if (this.hooks.
|
228
|
+
if (this.hooks.infrastructureLog.call(name, type, args) === undefined) {
|
225
229
|
if (this.infrastructureLogger !== undefined) {
|
226
230
|
this.infrastructureLogger(name, type, args);
|
227
231
|
}
|
@@ -430,7 +434,7 @@ class Compiler extends Tapable {
|
|
430
434
|
: targetFileGeneration + 1;
|
431
435
|
cacheEntry.writtenTo.set(targetPath, newGeneration);
|
432
436
|
this._assetEmittingWrittenFiles.set(targetPath, newGeneration);
|
433
|
-
callback
|
437
|
+
this.hooks.assetEmitted.callAsync(file, content, callback);
|
434
438
|
});
|
435
439
|
} else {
|
436
440
|
if (source.existsAt === targetPath) {
|
@@ -445,7 +449,10 @@ class Compiler extends Tapable {
|
|
445
449
|
|
446
450
|
source.existsAt = targetPath;
|
447
451
|
source.emitted = true;
|
448
|
-
this.outputFileSystem.writeFile(targetPath, content,
|
452
|
+
this.outputFileSystem.writeFile(targetPath, content, err => {
|
453
|
+
if (err) return callback(err);
|
454
|
+
this.hooks.assetEmitted.callAsync(file, content, callback);
|
455
|
+
});
|
449
456
|
}
|
450
457
|
};
|
451
458
|
|
package/lib/Entrypoint.js
CHANGED
@@ -52,8 +52,8 @@ class Entrypoint extends ChunkGroup {
|
|
52
52
|
|
53
53
|
/**
|
54
54
|
* @param {Chunk} oldChunk chunk to be replaced
|
55
|
-
* @param {Chunk} newChunk New
|
56
|
-
* @returns {boolean}
|
55
|
+
* @param {Chunk} newChunk New chunk that will be replaced with
|
56
|
+
* @returns {boolean} returns true if the replacement was successful
|
57
57
|
*/
|
58
58
|
replaceChunk(oldChunk, newChunk) {
|
59
59
|
if (this.runtimeChunk === oldChunk) this.runtimeChunk = newChunk;
|
package/lib/MultiCompiler.js
CHANGED
@@ -18,7 +18,10 @@ module.exports = class MultiCompiler extends Tapable {
|
|
18
18
|
invalid: new MultiHook(compilers.map(c => c.hooks.invalid)),
|
19
19
|
run: new MultiHook(compilers.map(c => c.hooks.run)),
|
20
20
|
watchClose: new SyncHook([]),
|
21
|
-
watchRun: new MultiHook(compilers.map(c => c.hooks.watchRun))
|
21
|
+
watchRun: new MultiHook(compilers.map(c => c.hooks.watchRun)),
|
22
|
+
infrastructureLog: new MultiHook(
|
23
|
+
compilers.map(c => c.hooks.infrastructureLog)
|
24
|
+
)
|
22
25
|
};
|
23
26
|
if (!Array.isArray(compilers)) {
|
24
27
|
compilers = Object.keys(compilers).map(name => {
|
@@ -90,6 +93,10 @@ module.exports = class MultiCompiler extends Tapable {
|
|
90
93
|
}
|
91
94
|
}
|
92
95
|
|
96
|
+
getInfrastructureLogger(name) {
|
97
|
+
return this.compilers[0].getInfrastructureLogger(name);
|
98
|
+
}
|
99
|
+
|
93
100
|
validateDependencies(callback) {
|
94
101
|
const edges = new Set();
|
95
102
|
const missing = [];
|
package/lib/ProgressPlugin.js
CHANGED
@@ -10,50 +10,14 @@ const schema = require("../schemas/plugins/ProgressPlugin.json");
|
|
10
10
|
/** @typedef {import("../declarations/plugins/ProgressPlugin").ProgressPluginArgument} ProgressPluginArgument */
|
11
11
|
/** @typedef {import("../declarations/plugins/ProgressPlugin").ProgressPluginOptions} ProgressPluginOptions */
|
12
12
|
|
13
|
-
const createDefaultHandler = profile => {
|
14
|
-
let lineCaretPosition = 0;
|
15
|
-
let lastMessage = "";
|
13
|
+
const createDefaultHandler = (profile, logger) => {
|
16
14
|
let lastState;
|
17
15
|
let lastStateTime;
|
18
16
|
|
19
17
|
const defaultHandler = (percentage, msg, ...args) => {
|
20
|
-
|
21
|
-
const details = args.filter(v => v.length);
|
22
|
-
const maxLineLength = process.stderr.columns || Infinity;
|
23
|
-
if (percentage < 1) {
|
24
|
-
percentage = Math.floor(percentage * 100);
|
25
|
-
msg = `${percentage}% ${msg}`;
|
26
|
-
if (percentage < 100) {
|
27
|
-
msg = ` ${msg}`;
|
28
|
-
}
|
29
|
-
if (percentage < 10) {
|
30
|
-
msg = ` ${msg}`;
|
31
|
-
}
|
32
|
-
|
33
|
-
if (details.length) {
|
34
|
-
const maxTotalDetailsLength = maxLineLength - msg.length;
|
35
|
-
const totalDetailsLength = details.reduce(
|
36
|
-
(a, b) => a + b.length,
|
37
|
-
details.length // account for added space before each detail text
|
38
|
-
);
|
39
|
-
const maxDetailLength =
|
40
|
-
totalDetailsLength < maxTotalDetailsLength
|
41
|
-
? Infinity
|
42
|
-
: Math.floor(maxTotalDetailsLength / details.length);
|
43
|
-
|
44
|
-
for (let detail of details) {
|
45
|
-
if (!detail) continue;
|
46
|
-
if (detail.length + 1 > maxDetailLength) {
|
47
|
-
const truncatePrefix = "...";
|
48
|
-
detail = `${truncatePrefix}${detail.substr(
|
49
|
-
-(maxDetailLength - truncatePrefix.length - 1)
|
50
|
-
)}`;
|
51
|
-
}
|
52
|
-
msg += ` ${detail}`;
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
18
|
+
logger.status(`${Math.floor(percentage * 100)}%`, msg, ...args);
|
56
19
|
if (profile) {
|
20
|
+
let state = msg;
|
57
21
|
state = state.replace(/^\d+\/\d+\s+/, "");
|
58
22
|
if (percentage === 0) {
|
59
23
|
lastState = null;
|
@@ -61,33 +25,23 @@ const createDefaultHandler = profile => {
|
|
61
25
|
} else if (state !== lastState || percentage === 1) {
|
62
26
|
const now = Date.now();
|
63
27
|
if (lastState) {
|
64
|
-
const
|
65
|
-
|
66
|
-
|
67
|
-
|
28
|
+
const diff = now - lastStateTime;
|
29
|
+
const stateMsg = `${diff}ms ${lastState}`;
|
30
|
+
if (diff > 1000) {
|
31
|
+
logger.warn(stateMsg);
|
32
|
+
} else if (diff > 10) {
|
33
|
+
logger.info(stateMsg);
|
34
|
+
} else if (diff > 0) {
|
35
|
+
logger.log(stateMsg);
|
36
|
+
} else {
|
37
|
+
logger.debug(stateMsg);
|
38
|
+
}
|
68
39
|
}
|
69
40
|
lastState = state;
|
70
41
|
lastStateTime = now;
|
71
42
|
}
|
72
43
|
}
|
73
|
-
if (
|
74
|
-
goToLineStart(msg);
|
75
|
-
msg = msg.substring(0, maxLineLength);
|
76
|
-
process.stderr.write(msg);
|
77
|
-
lastMessage = msg;
|
78
|
-
}
|
79
|
-
};
|
80
|
-
|
81
|
-
const goToLineStart = nextMessage => {
|
82
|
-
let str = "";
|
83
|
-
for (; lineCaretPosition > nextMessage.length; lineCaretPosition--) {
|
84
|
-
str += "\b \b";
|
85
|
-
}
|
86
|
-
for (var i = 0; i < lineCaretPosition; i++) {
|
87
|
-
str += "\b";
|
88
|
-
}
|
89
|
-
lineCaretPosition = nextMessage.length;
|
90
|
-
if (str) process.stderr.write(str);
|
44
|
+
if (percentage === 1) logger.status();
|
91
45
|
};
|
92
46
|
|
93
47
|
return defaultHandler;
|
@@ -118,7 +72,12 @@ class ProgressPlugin {
|
|
118
72
|
|
119
73
|
apply(compiler) {
|
120
74
|
const { modulesCount } = this;
|
121
|
-
const handler =
|
75
|
+
const handler =
|
76
|
+
this.handler ||
|
77
|
+
createDefaultHandler(
|
78
|
+
this.profile,
|
79
|
+
compiler.getInfrastructureLogger("webpack.Progress")
|
80
|
+
);
|
122
81
|
const showEntries = this.showEntries;
|
123
82
|
const showModules = this.showModules;
|
124
83
|
const showActiveModules = this.showActiveModules;
|
@@ -263,7 +222,6 @@ class ProgressPlugin {
|
|
263
222
|
recordModules: "record modules",
|
264
223
|
recordChunks: "record chunks",
|
265
224
|
beforeHash: "hashing",
|
266
|
-
contentHash: "content hashing",
|
267
225
|
afterHash: "after hashing",
|
268
226
|
recordHash: "record hash",
|
269
227
|
beforeModuleAssets: "module assets processing",
|
@@ -49,27 +49,13 @@ const assetsCache = new WeakMap();
|
|
49
49
|
/**
|
50
50
|
* Creating {@link SourceMapTask} for given file
|
51
51
|
* @param {string} file current compiled file
|
52
|
+
* @param {Source} asset the asset
|
52
53
|
* @param {Chunk} chunk related chunk
|
53
54
|
* @param {SourceMapDevToolPluginOptions} options source map options
|
54
55
|
* @param {Compilation} compilation compilation instance
|
55
56
|
* @returns {SourceMapTask | undefined} created task instance or `undefined`
|
56
57
|
*/
|
57
|
-
const getTaskForFile = (file, chunk, options, compilation) => {
|
58
|
-
const asset = compilation.assets[file];
|
59
|
-
const cache = assetsCache.get(asset);
|
60
|
-
/**
|
61
|
-
* If presented in cache, reassigns assets. Cache assets already have source maps.
|
62
|
-
*/
|
63
|
-
if (cache && cache.file === file) {
|
64
|
-
for (const cachedFile in cache.assets) {
|
65
|
-
compilation.assets[cachedFile] = cache.assets[cachedFile];
|
66
|
-
/**
|
67
|
-
* Add file to chunk, if not presented there
|
68
|
-
*/
|
69
|
-
if (cachedFile !== file) chunk.files.push(cachedFile);
|
70
|
-
}
|
71
|
-
return;
|
72
|
-
}
|
58
|
+
const getTaskForFile = (file, asset, chunk, options, compilation) => {
|
73
59
|
let source, sourceMap;
|
74
60
|
/**
|
75
61
|
* Check if asset can build source map
|
@@ -189,13 +175,35 @@ class SourceMapDevToolPlugin {
|
|
189
175
|
reportProgress(0.0);
|
190
176
|
const tasks = [];
|
191
177
|
files.forEach(({ file, chunk }, idx) => {
|
178
|
+
const asset = compilation.assets[file];
|
179
|
+
const cache = assetsCache.get(asset);
|
180
|
+
/**
|
181
|
+
* If presented in cache, reassigns assets. Cache assets already have source maps.
|
182
|
+
*/
|
183
|
+
if (cache && cache.file === file) {
|
184
|
+
for (const cachedFile in cache.assets) {
|
185
|
+
compilation.assets[cachedFile] = cache.assets[cachedFile];
|
186
|
+
/**
|
187
|
+
* Add file to chunk, if not presented there
|
188
|
+
*/
|
189
|
+
if (cachedFile !== file) chunk.files.push(cachedFile);
|
190
|
+
}
|
191
|
+
return;
|
192
|
+
}
|
193
|
+
|
192
194
|
reportProgress(
|
193
195
|
(0.5 * idx) / files.length,
|
194
196
|
file,
|
195
197
|
"generate SourceMap"
|
196
198
|
);
|
197
199
|
/** @type {SourceMapTask | undefined} */
|
198
|
-
const task = getTaskForFile(
|
200
|
+
const task = getTaskForFile(
|
201
|
+
file,
|
202
|
+
asset,
|
203
|
+
chunk,
|
204
|
+
options,
|
205
|
+
compilation
|
206
|
+
);
|
199
207
|
|
200
208
|
if (task) {
|
201
209
|
const modules = task.sourceMap.sources.map(source => {
|
package/lib/Stats.js
CHANGED
@@ -755,6 +755,7 @@ class Stats {
|
|
755
755
|
LogType.profile,
|
756
756
|
LogType.profileEnd,
|
757
757
|
LogType.time,
|
758
|
+
LogType.status,
|
758
759
|
LogType.clear
|
759
760
|
]);
|
760
761
|
collapsedGroups = true;
|
@@ -1442,7 +1443,7 @@ class Stats {
|
|
1442
1443
|
let indent = "";
|
1443
1444
|
for (const entry of logData.entries) {
|
1444
1445
|
let color = colors.normal;
|
1445
|
-
let prefix = "";
|
1446
|
+
let prefix = " ";
|
1446
1447
|
switch (entry.type) {
|
1447
1448
|
case LogType.clear:
|
1448
1449
|
colors.normal(`${indent}-------`);
|
@@ -1467,6 +1468,10 @@ class Stats {
|
|
1467
1468
|
case LogType.debug:
|
1468
1469
|
color = colors.normal;
|
1469
1470
|
break;
|
1471
|
+
case LogType.status:
|
1472
|
+
color = colors.magenta;
|
1473
|
+
prefix = "<s> ";
|
1474
|
+
break;
|
1470
1475
|
case LogType.profile:
|
1471
1476
|
color = colors.magenta;
|
1472
1477
|
prefix = "<p> ";
|
@@ -1481,13 +1486,14 @@ class Stats {
|
|
1481
1486
|
break;
|
1482
1487
|
case LogType.group:
|
1483
1488
|
color = colors.cyan;
|
1489
|
+
prefix = "<-> ";
|
1484
1490
|
break;
|
1485
1491
|
case LogType.groupCollapsed:
|
1486
1492
|
color = colors.cyan;
|
1487
1493
|
prefix = "<+> ";
|
1488
1494
|
break;
|
1489
1495
|
case LogType.groupEnd:
|
1490
|
-
if (indent.length
|
1496
|
+
if (indent.length >= 2)
|
1491
1497
|
indent = indent.slice(0, indent.length - 2);
|
1492
1498
|
continue;
|
1493
1499
|
}
|
@@ -34,7 +34,11 @@ class SystemMainTemplatePlugin {
|
|
34
34
|
const externals = chunk.getModules().filter(m => m.external);
|
35
35
|
|
36
36
|
// The name this bundle should be registered as with System
|
37
|
-
const name = this.name
|
37
|
+
const name = this.name
|
38
|
+
? `${JSON.stringify(
|
39
|
+
mainTemplate.getAssetPath(this.name, { hash, chunk })
|
40
|
+
)}, `
|
41
|
+
: "";
|
38
42
|
|
39
43
|
// The array of dependencies that are external to webpack and will be provided by System
|
40
44
|
const systemDependencies = JSON.stringify(
|
@@ -47,12 +47,18 @@ const getReplacer = (value, allowEmpty) => {
|
|
47
47
|
}
|
48
48
|
return "";
|
49
49
|
} else {
|
50
|
-
return `${value}`;
|
50
|
+
return `${escapePathVariables(value)}`;
|
51
51
|
}
|
52
52
|
};
|
53
53
|
return fn;
|
54
54
|
};
|
55
55
|
|
56
|
+
const escapePathVariables = value => {
|
57
|
+
return typeof value === "string"
|
58
|
+
? value.replace(/\[(\\*[\w:]+\\*)\]/gi, "[\\$1\\]")
|
59
|
+
: value;
|
60
|
+
};
|
61
|
+
|
56
62
|
const replacePathVariables = (path, data) => {
|
57
63
|
const chunk = data.chunk;
|
58
64
|
const chunkId = chunk && chunk.id;
|
@@ -114,6 +120,7 @@ const replacePathVariables = (path, data) => {
|
|
114
120
|
.replace(REGEXP_QUERY, getReplacer(data.query, true))
|
115
121
|
// only available in sourceMappingURLComment
|
116
122
|
.replace(REGEXP_URL, getReplacer(data.url))
|
123
|
+
.replace(/\[\\(\\*[\w:]+\\*)\\\]/gi, "[$1]")
|
117
124
|
);
|
118
125
|
};
|
119
126
|
|
@@ -196,7 +196,12 @@ class WebpackOptionsDefaulter extends OptionsDefaulter {
|
|
196
196
|
);
|
197
197
|
|
198
198
|
this.set("optimization", "call", value => Object.assign({}, value));
|
199
|
-
|
199
|
+
// TODO webpack 5: Disable by default in a modes
|
200
|
+
this.set(
|
201
|
+
"optimization.removeAvailableModules",
|
202
|
+
"make",
|
203
|
+
options => options.mode !== "development"
|
204
|
+
);
|
200
205
|
this.set("optimization.removeEmptyChunks", true);
|
201
206
|
this.set("optimization.mergeDuplicateChunks", true);
|
202
207
|
this.set("optimization.flagIncludedChunks", "make", options =>
|