webpack 4.35.3 → 4.38.0
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/declarations/WebpackOptions.d.ts +36 -11
- package/lib/AbstractMethodError.js +43 -0
- package/lib/Chunk.js +5 -1
- package/lib/ChunkGroup.js +1 -1
- package/lib/Compilation.js +87 -471
- package/lib/Compiler.js +33 -0
- package/lib/HashedModuleIdsPlugin.js +3 -1
- package/lib/JavascriptModulesPlugin.js +2 -3
- package/lib/ModuleFilenameHelpers.js +2 -1
- package/lib/NamedModulesPlugin.js +2 -1
- package/lib/NormalModule.js +16 -5
- package/lib/NormalModuleFactory.js +2 -2
- package/lib/OptionsDefaulter.js +9 -9
- package/lib/ProgressPlugin.js +0 -1
- package/lib/ResolverFactory.js +11 -14
- package/lib/SourceMapDevToolPlugin.js +110 -22
- package/lib/Stats.js +221 -3
- package/lib/Template.js +1 -1
- package/lib/TemplatedPathPlugin.js +4 -1
- package/lib/WebpackOptionsApply.js +5 -6
- package/lib/WebpackOptionsDefaulter.js +12 -1
- package/lib/buildChunkGraph.js +689 -0
- package/lib/debug/ProfilingPlugin.js +1 -1
- package/lib/logging/Logger.js +126 -0
- package/lib/logging/createConsoleLogger.js +188 -0
- package/lib/logging/runtime.js +35 -0
- package/lib/node/NodeEnvironmentPlugin.js +14 -0
- package/lib/util/cleverMerge.js +77 -0
- package/lib/util/createHash.js +57 -12
- package/lib/util/objectToMap.js +1 -1
- package/lib/wasm/WebAssemblyGenerator.js +7 -7
- package/lib/webpack.js +3 -1
- package/package.json +2 -1
- package/schemas/WebpackOptions.json +54 -2
@@ -148,9 +148,8 @@ class JavascriptModulesPlugin {
|
|
148
148
|
hash.update(m.hash);
|
149
149
|
}
|
150
150
|
}
|
151
|
-
|
152
|
-
|
153
|
-
.substr(0, hashDigestLength);
|
151
|
+
const digest = /** @type {string} */ (hash.digest(hashDigest));
|
152
|
+
chunk.contentHash.javascript = digest.substr(0, hashDigestLength);
|
154
153
|
});
|
155
154
|
}
|
156
155
|
);
|
@@ -44,7 +44,8 @@ const getBefore = (str, token) => {
|
|
44
44
|
const getHash = str => {
|
45
45
|
const hash = createHash("md4");
|
46
46
|
hash.update(str);
|
47
|
-
|
47
|
+
const digest = /** @type {string} */ (hash.digest("hex"));
|
48
|
+
return digest.substr(0, 4);
|
48
49
|
};
|
49
50
|
|
50
51
|
const asRegExp = test => {
|
@@ -10,7 +10,8 @@ const RequestShortener = require("./RequestShortener");
|
|
10
10
|
const getHash = str => {
|
11
11
|
const hash = createHash("md4");
|
12
12
|
hash.update(str);
|
13
|
-
|
13
|
+
const digest = /** @type {string} */ (hash.digest("hex"));
|
14
|
+
return digest.substr(0, 4);
|
14
15
|
};
|
15
16
|
|
16
17
|
class NamedModulesPlugin {
|
package/lib/NormalModule.js
CHANGED
@@ -147,16 +147,20 @@ class NormalModule extends Module {
|
|
147
147
|
|
148
148
|
createLoaderContext(resolver, options, compilation, fs) {
|
149
149
|
const requestShortener = compilation.runtimeTemplate.requestShortener;
|
150
|
+
const getCurrentLoaderName = () => {
|
151
|
+
const currentLoader = this.getCurrentLoader(loaderContext);
|
152
|
+
if (!currentLoader) return "(not in loader scope)";
|
153
|
+
return requestShortener.shorten(currentLoader.loader);
|
154
|
+
};
|
150
155
|
const loaderContext = {
|
151
156
|
version: 2,
|
152
157
|
emitWarning: warning => {
|
153
158
|
if (!(warning instanceof Error)) {
|
154
159
|
warning = new NonErrorEmittedError(warning);
|
155
160
|
}
|
156
|
-
const currentLoader = this.getCurrentLoader(loaderContext);
|
157
161
|
this.warnings.push(
|
158
162
|
new ModuleWarning(this, warning, {
|
159
|
-
from:
|
163
|
+
from: getCurrentLoaderName()
|
160
164
|
})
|
161
165
|
);
|
162
166
|
},
|
@@ -164,13 +168,20 @@ class NormalModule extends Module {
|
|
164
168
|
if (!(error instanceof Error)) {
|
165
169
|
error = new NonErrorEmittedError(error);
|
166
170
|
}
|
167
|
-
const currentLoader = this.getCurrentLoader(loaderContext);
|
168
171
|
this.errors.push(
|
169
172
|
new ModuleError(this, error, {
|
170
|
-
from:
|
173
|
+
from: getCurrentLoaderName()
|
171
174
|
})
|
172
175
|
);
|
173
176
|
},
|
177
|
+
getLogger: name => {
|
178
|
+
const currentLoader = this.getCurrentLoader(loaderContext);
|
179
|
+
return compilation.getLogger(() =>
|
180
|
+
[currentLoader && currentLoader.loader, name, this.identifier()]
|
181
|
+
.filter(Boolean)
|
182
|
+
.join("|")
|
183
|
+
);
|
184
|
+
},
|
174
185
|
// TODO remove in webpack 5
|
175
186
|
exec: (code, filename) => {
|
176
187
|
// @ts-ignore Argument of type 'this' is not assignable to parameter of type 'Module'.
|
@@ -405,7 +416,7 @@ class NormalModule extends Module {
|
|
405
416
|
}
|
406
417
|
hash.update("meta");
|
407
418
|
hash.update(JSON.stringify(this.buildMeta));
|
408
|
-
this._buildHash = hash.digest("hex");
|
419
|
+
this._buildHash = /** @type {string} */ (hash.digest("hex"));
|
409
420
|
}
|
410
421
|
|
411
422
|
build(options, compilation, resolver, fs, callback) {
|
@@ -17,7 +17,7 @@ const {
|
|
17
17
|
const NormalModule = require("./NormalModule");
|
18
18
|
const RawModule = require("./RawModule");
|
19
19
|
const RuleSet = require("./RuleSet");
|
20
|
-
const
|
20
|
+
const { cachedCleverMerge } = require("./util/cleverMerge");
|
21
21
|
|
22
22
|
const EMPTY_RESOLVE_OPTIONS = {};
|
23
23
|
|
@@ -304,7 +304,7 @@ class NormalModuleFactory extends Tapable {
|
|
304
304
|
typeof settings[r.type] === "object" &&
|
305
305
|
settings[r.type] !== null
|
306
306
|
) {
|
307
|
-
settings[r.type] =
|
307
|
+
settings[r.type] = cachedCleverMerge(settings[r.type], r.value);
|
308
308
|
} else {
|
309
309
|
settings[r.type] = r.value;
|
310
310
|
}
|
package/lib/OptionsDefaulter.js
CHANGED
@@ -6,8 +6,8 @@
|
|
6
6
|
|
7
7
|
/**
|
8
8
|
* Gets the value at path of object
|
9
|
-
* @param {object} obj
|
10
|
-
* @param {string} path
|
9
|
+
* @param {object} obj object to query
|
10
|
+
* @param {string} path query path
|
11
11
|
* @returns {any} - if {@param path} requests element from array, then `undefined` will be returned
|
12
12
|
*/
|
13
13
|
const getProperty = (obj, path) => {
|
@@ -21,9 +21,9 @@ const getProperty = (obj, path) => {
|
|
21
21
|
|
22
22
|
/**
|
23
23
|
* Sets the value at path of object. Stops execution, if {@param path} requests element from array to be set
|
24
|
-
* @param {object} obj
|
25
|
-
* @param {string} path
|
26
|
-
* @param {any} value
|
24
|
+
* @param {object} obj object to query
|
25
|
+
* @param {string} path query path
|
26
|
+
* @param {any} value value to be set
|
27
27
|
* @returns {void}
|
28
28
|
*/
|
29
29
|
const setProperty = (obj, path, value) => {
|
@@ -65,7 +65,7 @@ class OptionsDefaulter {
|
|
65
65
|
|
66
66
|
/**
|
67
67
|
* Enhancing {@param options} with default values
|
68
|
-
* @param {object} options
|
68
|
+
* @param {object} options provided options
|
69
69
|
* @returns {object} - enhanced options
|
70
70
|
* @throws {Error} - will throw error, if configuration value is other then `undefined` or {@link ConfigType}
|
71
71
|
*/
|
@@ -122,9 +122,9 @@ class OptionsDefaulter {
|
|
122
122
|
|
123
123
|
/**
|
124
124
|
* Builds up default values
|
125
|
-
* @param {string} name
|
126
|
-
* @param {ConfigType | any} config
|
127
|
-
* @param {MakeConfigHandler | CallConfigHandler | AppendConfigValues} [def]
|
125
|
+
* @param {string} name option path
|
126
|
+
* @param {ConfigType | any} config if {@param def} is provided, then only {@link ConfigType} is allowed
|
127
|
+
* @param {MakeConfigHandler | CallConfigHandler | AppendConfigValues} [def] defaults
|
128
128
|
* @returns {void}
|
129
129
|
*/
|
130
130
|
set(name, config, def) {
|
package/lib/ProgressPlugin.js
CHANGED
@@ -263,7 +263,6 @@ class ProgressPlugin {
|
|
263
263
|
recordModules: "record modules",
|
264
264
|
recordChunks: "record chunks",
|
265
265
|
beforeHash: "hashing",
|
266
|
-
contentHash: "content hashing",
|
267
266
|
afterHash: "after hashing",
|
268
267
|
recordHash: "record hash",
|
269
268
|
beforeModuleAssets: "module assets processing",
|
package/lib/ResolverFactory.js
CHANGED
@@ -6,9 +6,12 @@
|
|
6
6
|
|
7
7
|
const { Tapable, HookMap, SyncHook, SyncWaterfallHook } = require("tapable");
|
8
8
|
const Factory = require("enhanced-resolve").ResolverFactory;
|
9
|
+
const { cachedCleverMerge } = require("./util/cleverMerge");
|
9
10
|
|
10
11
|
/** @typedef {import("enhanced-resolve").Resolver} Resolver */
|
11
12
|
|
13
|
+
const EMTPY_RESOLVE_OPTIONS = {};
|
14
|
+
|
12
15
|
module.exports = class ResolverFactory extends Tapable {
|
13
16
|
constructor() {
|
14
17
|
super();
|
@@ -22,30 +25,24 @@ module.exports = class ResolverFactory extends Tapable {
|
|
22
25
|
let match;
|
23
26
|
match = /^resolve-options (.+)$/.exec(options.name);
|
24
27
|
if (match) {
|
25
|
-
this.hooks.resolveOptions
|
26
|
-
match[1]
|
27
|
-
options.fn.name || "unnamed compat plugin",
|
28
|
-
options.fn
|
29
|
-
);
|
28
|
+
this.hooks.resolveOptions
|
29
|
+
.for(match[1])
|
30
|
+
.tap(options.fn.name || "unnamed compat plugin", options.fn);
|
30
31
|
return true;
|
31
32
|
}
|
32
33
|
match = /^resolver (.+)$/.exec(options.name);
|
33
34
|
if (match) {
|
34
|
-
this.hooks.resolver
|
35
|
-
match[1]
|
36
|
-
options.fn.name || "unnamed compat plugin",
|
37
|
-
options.fn
|
38
|
-
);
|
35
|
+
this.hooks.resolver
|
36
|
+
.for(match[1])
|
37
|
+
.tap(options.fn.name || "unnamed compat plugin", options.fn);
|
39
38
|
return true;
|
40
39
|
}
|
41
40
|
});
|
42
|
-
this.cache1 = new WeakMap();
|
43
41
|
this.cache2 = new Map();
|
44
42
|
}
|
45
43
|
|
46
44
|
get(type, resolveOptions) {
|
47
|
-
|
48
|
-
if (cachedResolver) return cachedResolver();
|
45
|
+
resolveOptions = resolveOptions || EMTPY_RESOLVE_OPTIONS;
|
49
46
|
const ident = `${type}|${JSON.stringify(resolveOptions)}`;
|
50
47
|
const resolver = this.cache2.get(ident);
|
51
48
|
if (resolver) return resolver;
|
@@ -66,7 +63,7 @@ module.exports = class ResolverFactory extends Tapable {
|
|
66
63
|
resolver.withOptions = options => {
|
67
64
|
const cacheEntry = childCache.get(options);
|
68
65
|
if (cacheEntry !== undefined) return cacheEntry;
|
69
|
-
const mergedOptions =
|
66
|
+
const mergedOptions = cachedCleverMerge(originalResolveOptions, options);
|
70
67
|
const resolver = this.get(type, mergedOptions);
|
71
68
|
childCache.set(options, resolver);
|
72
69
|
return resolver;
|
@@ -14,25 +14,52 @@ const validateOptions = require("schema-utils");
|
|
14
14
|
const schema = require("../schemas/plugins/SourceMapDevToolPlugin.json");
|
15
15
|
|
16
16
|
/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */
|
17
|
+
/** @typedef {import("./Chunk")} Chunk */
|
18
|
+
/** @typedef {import("webpack-sources").Source} Source */
|
19
|
+
/** @typedef {import("source-map").RawSourceMap} SourceMap */
|
20
|
+
/** @typedef {import("./Module")} Module */
|
21
|
+
/** @typedef {import("./Compilation")} Compilation */
|
22
|
+
/** @typedef {import("./Compiler")} Compiler */
|
23
|
+
/** @typedef {import("./Compilation")} SourceMapDefinition */
|
17
24
|
|
25
|
+
/**
|
26
|
+
* @typedef {object} SourceMapTask
|
27
|
+
* @property {Source} asset
|
28
|
+
* @property {Array<string | Module>} [modules]
|
29
|
+
* @property {string} source
|
30
|
+
* @property {string} file
|
31
|
+
* @property {SourceMap} sourceMap
|
32
|
+
* @property {Chunk} chunk
|
33
|
+
*/
|
34
|
+
|
35
|
+
/**
|
36
|
+
* @param {string} name file path
|
37
|
+
* @returns {string} file name
|
38
|
+
*/
|
18
39
|
const basename = name => {
|
19
40
|
if (!name.includes("/")) return name;
|
20
41
|
return name.substr(name.lastIndexOf("/") + 1);
|
21
42
|
};
|
22
43
|
|
44
|
+
/**
|
45
|
+
* @type {WeakMap<Source, {file: string, assets: {[k: string]: ConcatSource | RawSource}}>}
|
46
|
+
*/
|
23
47
|
const assetsCache = new WeakMap();
|
24
48
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
49
|
+
/**
|
50
|
+
* Creating {@link SourceMapTask} for given file
|
51
|
+
* @param {string} file current compiled file
|
52
|
+
* @param {Source} asset the asset
|
53
|
+
* @param {Chunk} chunk related chunk
|
54
|
+
* @param {SourceMapDevToolPluginOptions} options source map options
|
55
|
+
* @param {Compilation} compilation compilation instance
|
56
|
+
* @returns {SourceMapTask | undefined} created task instance or `undefined`
|
57
|
+
*/
|
58
|
+
const getTaskForFile = (file, asset, chunk, options, compilation) => {
|
35
59
|
let source, sourceMap;
|
60
|
+
/**
|
61
|
+
* Check if asset can build source map
|
62
|
+
*/
|
36
63
|
if (asset.sourceAndMap) {
|
37
64
|
const sourceAndMap = asset.sourceAndMap(options);
|
38
65
|
sourceMap = sourceAndMap.map;
|
@@ -55,7 +82,8 @@ const getTaskForFile = (file, chunk, options, compilation) => {
|
|
55
82
|
|
56
83
|
class SourceMapDevToolPlugin {
|
57
84
|
/**
|
58
|
-
* @param {SourceMapDevToolPluginOptions
|
85
|
+
* @param {SourceMapDevToolPluginOptions} [options] options object
|
86
|
+
* @throws {Error} throws error, if got more than 1 arguments
|
59
87
|
*/
|
60
88
|
constructor(options) {
|
61
89
|
if (arguments.length > 1) {
|
@@ -68,21 +96,31 @@ class SourceMapDevToolPlugin {
|
|
68
96
|
|
69
97
|
validateOptions(schema, options, "SourceMap DevTool Plugin");
|
70
98
|
|
99
|
+
/** @type {string | false} */
|
71
100
|
this.sourceMapFilename = options.filename;
|
72
101
|
/** @type {string | false} */
|
73
102
|
this.sourceMappingURLComment =
|
74
103
|
options.append === false
|
75
104
|
? false
|
76
105
|
: options.append || "\n//# sourceMappingURL=[url]";
|
106
|
+
/** @type {string | Function} */
|
77
107
|
this.moduleFilenameTemplate =
|
78
108
|
options.moduleFilenameTemplate || "webpack://[namespace]/[resourcePath]";
|
109
|
+
/** @type {string | Function} */
|
79
110
|
this.fallbackModuleFilenameTemplate =
|
80
111
|
options.fallbackModuleFilenameTemplate ||
|
81
112
|
"webpack://[namespace]/[resourcePath]?[hash]";
|
113
|
+
/** @type {string} */
|
82
114
|
this.namespace = options.namespace || "";
|
115
|
+
/** @type {SourceMapDevToolPluginOptions} */
|
83
116
|
this.options = options;
|
84
117
|
}
|
85
118
|
|
119
|
+
/**
|
120
|
+
* Apply compiler
|
121
|
+
* @param {Compiler} compiler compiler instance
|
122
|
+
* @returns {void}
|
123
|
+
*/
|
86
124
|
apply(compiler) {
|
87
125
|
const sourceMapFilename = this.sourceMapFilename;
|
88
126
|
const sourceMappingURLComment = this.sourceMappingURLComment;
|
@@ -102,12 +140,21 @@ class SourceMapDevToolPlugin {
|
|
102
140
|
new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation);
|
103
141
|
|
104
142
|
compilation.hooks.afterOptimizeChunkAssets.tap(
|
105
|
-
{
|
106
|
-
|
107
|
-
|
108
|
-
|
143
|
+
/** @type {TODO} */
|
144
|
+
({ name: "SourceMapDevToolPlugin", context: true }),
|
145
|
+
/**
|
146
|
+
* @param {object} context hook context
|
147
|
+
* @param {Array<Chunk>} chunks resulted chunks
|
148
|
+
* @throws {Error} throws error, if `sourceMapFilename === false && sourceMappingURLComment === false`
|
149
|
+
* @returns {void}
|
150
|
+
*/
|
109
151
|
(context, chunks) => {
|
152
|
+
/** @type {Map<string | Module, string>} */
|
110
153
|
const moduleToSourceNameMapping = new Map();
|
154
|
+
/**
|
155
|
+
* @type {Function}
|
156
|
+
* @returns {void}
|
157
|
+
*/
|
111
158
|
const reportProgress =
|
112
159
|
context && context.reportProgress
|
113
160
|
? context.reportProgress
|
@@ -128,12 +175,35 @@ class SourceMapDevToolPlugin {
|
|
128
175
|
reportProgress(0.0);
|
129
176
|
const tasks = [];
|
130
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
|
+
|
131
194
|
reportProgress(
|
132
195
|
(0.5 * idx) / files.length,
|
133
196
|
file,
|
134
197
|
"generate SourceMap"
|
135
198
|
);
|
136
|
-
|
199
|
+
/** @type {SourceMapTask | undefined} */
|
200
|
+
const task = getTaskForFile(
|
201
|
+
file,
|
202
|
+
asset,
|
203
|
+
chunk,
|
204
|
+
options,
|
205
|
+
compilation
|
206
|
+
);
|
137
207
|
|
138
208
|
if (task) {
|
139
209
|
const modules = task.sourceMap.sources.map(source => {
|
@@ -165,10 +235,15 @@ class SourceMapDevToolPlugin {
|
|
165
235
|
});
|
166
236
|
|
167
237
|
reportProgress(0.5, "resolve sources");
|
238
|
+
/** @type {Set<string>} */
|
168
239
|
const usedNamesSet = new Set(moduleToSourceNameMapping.values());
|
240
|
+
/** @type {Set<string>} */
|
169
241
|
const conflictDetectionSet = new Set();
|
170
242
|
|
171
|
-
|
243
|
+
/**
|
244
|
+
* all modules in defined order (longest identifier first)
|
245
|
+
* @type {Array<string | Module>}
|
246
|
+
*/
|
172
247
|
const allModules = Array.from(moduleToSourceNameMapping.keys()).sort(
|
173
248
|
(a, b) => {
|
174
249
|
const ai = typeof a === "string" ? a : a.identifier();
|
@@ -254,7 +329,7 @@ class SourceMapDevToolPlugin {
|
|
254
329
|
query = filename.substr(idx);
|
255
330
|
filename = filename.substr(0, idx);
|
256
331
|
}
|
257
|
-
|
332
|
+
const pathParams = {
|
258
333
|
chunk,
|
259
334
|
filename: options.fileContext
|
260
335
|
? path.relative(options.fileContext, filename)
|
@@ -264,21 +339,31 @@ class SourceMapDevToolPlugin {
|
|
264
339
|
contentHash: createHash("md4")
|
265
340
|
.update(sourceMapString)
|
266
341
|
.digest("hex")
|
267
|
-
}
|
342
|
+
};
|
343
|
+
let sourceMapFile = compilation.getPath(
|
344
|
+
sourceMapFilename,
|
345
|
+
pathParams
|
346
|
+
);
|
268
347
|
const sourceMapUrl = options.publicPath
|
269
348
|
? options.publicPath + sourceMapFile.replace(/\\/g, "/")
|
270
349
|
: path
|
271
350
|
.relative(path.dirname(file), sourceMapFile)
|
272
351
|
.replace(/\\/g, "/");
|
352
|
+
/**
|
353
|
+
* Add source map url to compilation asset, if {@link currentSourceMappingURLComment} presented
|
354
|
+
*/
|
273
355
|
if (currentSourceMappingURLComment !== false) {
|
274
356
|
assets[file] = compilation.assets[file] = new ConcatSource(
|
275
357
|
new RawSource(source),
|
276
|
-
|
277
|
-
|
278
|
-
sourceMapUrl
|
358
|
+
compilation.getPath(
|
359
|
+
currentSourceMappingURLComment,
|
360
|
+
Object.assign({ url: sourceMapUrl }, pathParams)
|
279
361
|
)
|
280
362
|
);
|
281
363
|
}
|
364
|
+
/**
|
365
|
+
* Add source map file to compilation assets and chunk files
|
366
|
+
*/
|
282
367
|
assets[sourceMapFile] = compilation.assets[
|
283
368
|
sourceMapFile
|
284
369
|
] = new RawSource(sourceMapString);
|
@@ -289,6 +374,9 @@ class SourceMapDevToolPlugin {
|
|
289
374
|
"SourceMapDevToolPlugin: append can't be false when no filename is provided"
|
290
375
|
);
|
291
376
|
}
|
377
|
+
/**
|
378
|
+
* Add source map as data url to asset
|
379
|
+
*/
|
292
380
|
assets[file] = compilation.assets[file] = new ConcatSource(
|
293
381
|
new RawSource(source),
|
294
382
|
currentSourceMappingURLComment
|