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/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
- infrastructurelog: new SyncBailHook(["origin", "type", "args"]),
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.infrastructurelog.call(name, type, args) === undefined) {
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, callback);
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 chunkt that will be replaced
56
- * @returns {boolean} rerturns true for
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;
@@ -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 = [];
@@ -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
- let state = msg;
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 stateMsg = `${now - lastStateTime}ms ${lastState}`;
65
- goToLineStart(stateMsg);
66
- process.stderr.write(stateMsg + "\n");
67
- lineCaretPosition = 0;
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 (lastMessage !== msg) {
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 = this.handler || createDefaultHandler(this.profile);
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(file, chunk, options, compilation);
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 > 2)
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 ? `${JSON.stringify(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
- this.set("optimization.removeAvailableModules", true);
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 =>