webpack 5.68.0 → 5.70.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.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/lib/BannerPlugin.js +10 -4
- package/lib/ChunkGraph.js +1 -2
- package/lib/CleanPlugin.js +64 -18
- package/lib/Compilation.js +43 -17
- package/lib/ContextModule.js +90 -26
- package/lib/ContextModuleFactory.js +65 -21
- package/lib/EntryOptionPlugin.js +1 -0
- package/lib/ExportsInfo.js +4 -4
- package/lib/Generator.js +1 -0
- package/lib/ModuleHashingError.js +29 -0
- package/lib/NodeStuffPlugin.js +10 -0
- package/lib/NormalModule.js +21 -16
- package/lib/NormalModuleFactory.js +40 -35
- package/lib/ProgressPlugin.js +4 -5
- package/lib/RuntimeTemplate.js +1 -0
- package/lib/TemplatedPathPlugin.js +48 -23
- package/lib/WebpackOptionsApply.js +2 -0
- package/lib/asset/AssetGenerator.js +122 -33
- package/lib/buildChunkGraph.js +1 -1
- package/lib/cache/ResolverCachePlugin.js +89 -28
- package/lib/config/browserslistTargetHandler.js +3 -5
- package/lib/config/defaults.js +7 -2
- package/lib/config/normalization.js +1 -0
- package/lib/css/CssLoadingRuntimeModule.js +63 -70
- package/lib/css/CssModulesPlugin.js +2 -1
- package/lib/debug/ProfilingPlugin.js +3 -4
- package/lib/dependencies/ContextDependencyHelpers.js +1 -1
- package/lib/dependencies/ContextElementDependency.js +8 -2
- package/lib/dependencies/ExportsInfoDependency.js +6 -0
- package/lib/dependencies/HarmonyAcceptImportDependency.js +5 -3
- package/lib/dependencies/HarmonyExportInitFragment.js +4 -1
- package/lib/dependencies/ImportContextDependency.js +0 -2
- package/lib/dependencies/ImportMetaContextDependency.js +35 -0
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +252 -0
- package/lib/dependencies/ImportMetaContextPlugin.js +59 -0
- package/lib/dependencies/LoaderPlugin.js +2 -0
- package/lib/dependencies/RequireContextDependency.js +0 -16
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +24 -8
- package/lib/index.js +5 -0
- package/lib/javascript/JavascriptModulesPlugin.js +27 -2
- package/lib/javascript/StartupHelpers.js +3 -2
- package/lib/library/AssignLibraryPlugin.js +8 -2
- package/lib/node/NodeTargetPlugin.js +1 -0
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -7
- package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -7
- package/lib/optimize/ConcatenatedModule.js +10 -4
- package/lib/schemes/HttpUriPlugin.js +68 -6
- package/lib/serialization/FileMiddleware.js +44 -9
- package/lib/util/compileBooleanMatcher.js +1 -1
- package/lib/util/deterministicGrouping.js +1 -1
- package/lib/util/identifier.js +65 -44
- package/lib/util/internalSerializables.js +2 -0
- package/lib/util/nonNumericOnlyHash.js +22 -0
- package/lib/util/semver.js +17 -10
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +15 -5
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +30 -20
- package/module.d.ts +15 -0
- package/package.json +13 -13
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +17 -1
- package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
- package/types.d.ts +203 -91
@@ -12,6 +12,7 @@ const Generator = require("../Generator");
|
|
12
12
|
const RuntimeGlobals = require("../RuntimeGlobals");
|
13
13
|
const createHash = require("../util/createHash");
|
14
14
|
const { makePathsRelative } = require("../util/identifier");
|
15
|
+
const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
|
15
16
|
|
16
17
|
/** @typedef {import("webpack-sources").Source} Source */
|
17
18
|
/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */
|
@@ -112,6 +113,7 @@ const decodeDataUriContent = (encoding, content) => {
|
|
112
113
|
|
113
114
|
const JS_TYPES = new Set(["javascript"]);
|
114
115
|
const JS_AND_ASSET_TYPES = new Set(["javascript", "asset"]);
|
116
|
+
const DEFAULT_ENCODING = "base64";
|
115
117
|
|
116
118
|
class AssetGenerator extends Generator {
|
117
119
|
/**
|
@@ -130,6 +132,65 @@ class AssetGenerator extends Generator {
|
|
130
132
|
this.emit = emit;
|
131
133
|
}
|
132
134
|
|
135
|
+
/**
|
136
|
+
* @param {NormalModule} module module
|
137
|
+
* @param {RuntimeTemplate} runtimeTemplate runtime template
|
138
|
+
* @returns {string} source file name
|
139
|
+
*/
|
140
|
+
getSourceFileName(module, runtimeTemplate) {
|
141
|
+
return makePathsRelative(
|
142
|
+
runtimeTemplate.compilation.compiler.context,
|
143
|
+
module.matchResource || module.resource,
|
144
|
+
runtimeTemplate.compilation.compiler.root
|
145
|
+
).replace(/^\.\//, "");
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* @param {NormalModule} module module
|
150
|
+
* @returns {string} mime type
|
151
|
+
*/
|
152
|
+
getMimeType(module) {
|
153
|
+
if (typeof this.dataUrlOptions === "function") {
|
154
|
+
throw new Error(
|
155
|
+
"This method must not be called when dataUrlOptions is a function"
|
156
|
+
);
|
157
|
+
}
|
158
|
+
|
159
|
+
let mimeType = this.dataUrlOptions.mimetype;
|
160
|
+
if (mimeType === undefined) {
|
161
|
+
const ext = path.extname(module.nameForCondition());
|
162
|
+
if (
|
163
|
+
module.resourceResolveData &&
|
164
|
+
module.resourceResolveData.mimetype !== undefined
|
165
|
+
) {
|
166
|
+
mimeType =
|
167
|
+
module.resourceResolveData.mimetype +
|
168
|
+
module.resourceResolveData.parameters;
|
169
|
+
} else if (ext) {
|
170
|
+
mimeType = mimeTypes.lookup(ext);
|
171
|
+
|
172
|
+
if (typeof mimeType !== "string") {
|
173
|
+
throw new Error(
|
174
|
+
"DataUrl can't be generated automatically, " +
|
175
|
+
`because there is no mimetype for "${ext}" in mimetype database. ` +
|
176
|
+
'Either pass a mimetype via "generator.mimetype" or ' +
|
177
|
+
'use type: "asset/resource" to create a resource file instead of a DataUrl'
|
178
|
+
);
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
if (typeof mimeType !== "string") {
|
184
|
+
throw new Error(
|
185
|
+
"DataUrl can't be generated automatically. " +
|
186
|
+
'Either pass a mimetype via "generator.mimetype" or ' +
|
187
|
+
'use type: "asset/resource" to create a resource file instead of a DataUrl'
|
188
|
+
);
|
189
|
+
}
|
190
|
+
|
191
|
+
return mimeType;
|
192
|
+
}
|
193
|
+
|
133
194
|
/**
|
134
195
|
* @param {NormalModule} module module for which the code should be generated
|
135
196
|
* @param {GenerateContext} generateContext context for generate
|
@@ -169,31 +230,9 @@ class AssetGenerator extends Generator {
|
|
169
230
|
}
|
170
231
|
}
|
171
232
|
if (encoding === undefined) {
|
172
|
-
encoding =
|
173
|
-
}
|
174
|
-
let ext;
|
175
|
-
let mimeType = this.dataUrlOptions.mimetype;
|
176
|
-
if (mimeType === undefined) {
|
177
|
-
ext = path.extname(module.nameForCondition());
|
178
|
-
if (
|
179
|
-
module.resourceResolveData &&
|
180
|
-
module.resourceResolveData.mimetype !== undefined
|
181
|
-
) {
|
182
|
-
mimeType =
|
183
|
-
module.resourceResolveData.mimetype +
|
184
|
-
module.resourceResolveData.parameters;
|
185
|
-
} else if (ext) {
|
186
|
-
mimeType = mimeTypes.lookup(ext);
|
187
|
-
}
|
188
|
-
}
|
189
|
-
if (typeof mimeType !== "string") {
|
190
|
-
throw new Error(
|
191
|
-
"DataUrl can't be generated automatically, " +
|
192
|
-
`because there is no mimetype for "${ext}" in mimetype database. ` +
|
193
|
-
'Either pass a mimetype via "generator.mimetype" or ' +
|
194
|
-
'use type: "asset/resource" to create a resource file instead of a DataUrl'
|
195
|
-
);
|
233
|
+
encoding = DEFAULT_ENCODING;
|
196
234
|
}
|
235
|
+
const mimeType = this.getMimeType(module);
|
197
236
|
|
198
237
|
let encodedContent;
|
199
238
|
|
@@ -232,16 +271,15 @@ class AssetGenerator extends Generator {
|
|
232
271
|
const fullHash = /** @type {string} */ (
|
233
272
|
hash.digest(runtimeTemplate.outputOptions.hashDigest)
|
234
273
|
);
|
235
|
-
const contentHash =
|
236
|
-
|
274
|
+
const contentHash = nonNumericOnlyHash(
|
275
|
+
fullHash,
|
237
276
|
runtimeTemplate.outputOptions.hashDigestLength
|
238
277
|
);
|
239
278
|
module.buildInfo.fullContentHash = fullHash;
|
240
|
-
const sourceFilename =
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
).replace(/^\.\//, "");
|
279
|
+
const sourceFilename = this.getSourceFileName(
|
280
|
+
module,
|
281
|
+
runtimeTemplate
|
282
|
+
);
|
245
283
|
let { path: filename, info: assetInfo } =
|
246
284
|
runtimeTemplate.compilation.getAssetPathWithInfo(
|
247
285
|
assetModuleFilename,
|
@@ -367,8 +405,59 @@ class AssetGenerator extends Generator {
|
|
367
405
|
* @param {Hash} hash hash that will be modified
|
368
406
|
* @param {UpdateHashContext} updateHashContext context for updating hash
|
369
407
|
*/
|
370
|
-
updateHash(hash, { module }) {
|
371
|
-
|
408
|
+
updateHash(hash, { module, runtime, runtimeTemplate, chunkGraph }) {
|
409
|
+
if (module.buildInfo.dataUrl) {
|
410
|
+
hash.update("data-url");
|
411
|
+
// this.dataUrlOptions as function should be pure and only depend on input source and filename
|
412
|
+
// therefore it doesn't need to be hashed
|
413
|
+
if (typeof this.dataUrlOptions === "function") {
|
414
|
+
const ident = /** @type {{ ident?: string }} */ (this.dataUrlOptions)
|
415
|
+
.ident;
|
416
|
+
if (ident) hash.update(ident);
|
417
|
+
} else {
|
418
|
+
if (
|
419
|
+
this.dataUrlOptions.encoding &&
|
420
|
+
this.dataUrlOptions.encoding !== DEFAULT_ENCODING
|
421
|
+
) {
|
422
|
+
hash.update(this.dataUrlOptions.encoding);
|
423
|
+
}
|
424
|
+
if (this.dataUrlOptions.mimetype)
|
425
|
+
hash.update(this.dataUrlOptions.mimetype);
|
426
|
+
// computed mimetype depends only on module filename which is already part of the hash
|
427
|
+
}
|
428
|
+
} else {
|
429
|
+
hash.update("resource");
|
430
|
+
|
431
|
+
const pathData = {
|
432
|
+
module,
|
433
|
+
runtime,
|
434
|
+
filename: this.getSourceFileName(module, runtimeTemplate),
|
435
|
+
chunkGraph,
|
436
|
+
contentHash: runtimeTemplate.contentHashReplacement
|
437
|
+
};
|
438
|
+
|
439
|
+
if (typeof this.publicPath === "function") {
|
440
|
+
hash.update("path");
|
441
|
+
const assetInfo = {};
|
442
|
+
hash.update(this.publicPath(pathData, assetInfo));
|
443
|
+
hash.update(JSON.stringify(assetInfo));
|
444
|
+
} else if (this.publicPath) {
|
445
|
+
hash.update("path");
|
446
|
+
hash.update(this.publicPath);
|
447
|
+
} else {
|
448
|
+
hash.update("no-path");
|
449
|
+
}
|
450
|
+
|
451
|
+
const assetModuleFilename =
|
452
|
+
this.filename || runtimeTemplate.outputOptions.assetModuleFilename;
|
453
|
+
const { path: filename, info } =
|
454
|
+
runtimeTemplate.compilation.getAssetPathWithInfo(
|
455
|
+
assetModuleFilename,
|
456
|
+
pathData
|
457
|
+
);
|
458
|
+
hash.update(filename);
|
459
|
+
hash.update(JSON.stringify(info));
|
460
|
+
}
|
372
461
|
}
|
373
462
|
}
|
374
463
|
|
package/lib/buildChunkGraph.js
CHANGED
@@ -128,6 +128,13 @@ class ResolverCachePlugin {
|
|
128
128
|
fileDependencies: new LazySet(),
|
129
129
|
contextDependencies: new LazySet()
|
130
130
|
};
|
131
|
+
let yieldResult;
|
132
|
+
let withYield = false;
|
133
|
+
if (typeof newResolveContext.yield === "function") {
|
134
|
+
yieldResult = [];
|
135
|
+
withYield = true;
|
136
|
+
newResolveContext.yield = obj => yieldResult.push(obj);
|
137
|
+
}
|
131
138
|
const propagate = key => {
|
132
139
|
if (resolveContext[key]) {
|
133
140
|
addAllToSet(resolveContext[key], newResolveContext[key]);
|
@@ -155,15 +162,22 @@ class ResolverCachePlugin {
|
|
155
162
|
snapshotOptions,
|
156
163
|
(err, snapshot) => {
|
157
164
|
if (err) return callback(err);
|
165
|
+
const resolveResult = withYield ? yieldResult : result;
|
166
|
+
// since we intercept resolve hook
|
167
|
+
// we still can get result in callback
|
168
|
+
if (withYield && result) yieldResult.push(result);
|
158
169
|
if (!snapshot) {
|
159
|
-
if (
|
170
|
+
if (resolveResult) return callback(null, resolveResult);
|
160
171
|
return callback();
|
161
172
|
}
|
162
|
-
itemCache.store(
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
173
|
+
itemCache.store(
|
174
|
+
new CacheEntry(resolveResult, snapshot),
|
175
|
+
storeErr => {
|
176
|
+
if (storeErr) return callback(storeErr);
|
177
|
+
if (resolveResult) return callback(null, resolveResult);
|
178
|
+
callback();
|
179
|
+
}
|
180
|
+
);
|
167
181
|
}
|
168
182
|
);
|
169
183
|
}
|
@@ -173,6 +187,8 @@ class ResolverCachePlugin {
|
|
173
187
|
factory(type, hook) {
|
174
188
|
/** @type {Map<string, (function(Error=, Object=): void)[]>} */
|
175
189
|
const activeRequests = new Map();
|
190
|
+
/** @type {Map<string, [function(Error=, Object=): void, function(Error=, Object=): void][]>} */
|
191
|
+
const activeRequestsWithYield = new Map();
|
176
192
|
hook.tap(
|
177
193
|
"ResolverCachePlugin",
|
178
194
|
/**
|
@@ -197,29 +213,67 @@ class ResolverCachePlugin {
|
|
197
213
|
if (request._ResolverCachePluginCacheMiss || !fileSystemInfo) {
|
198
214
|
return callback();
|
199
215
|
}
|
200
|
-
const
|
201
|
-
|
202
|
-
|
203
|
-
)}`;
|
204
|
-
|
205
|
-
if (
|
206
|
-
activeRequest.
|
207
|
-
|
216
|
+
const withYield = typeof resolveContext.yield === "function";
|
217
|
+
const identifier = `${type}${
|
218
|
+
withYield ? "|yield" : "|default"
|
219
|
+
}${optionsIdent}${objectToString(request, !cacheWithContext)}`;
|
220
|
+
|
221
|
+
if (withYield) {
|
222
|
+
const activeRequest = activeRequestsWithYield.get(identifier);
|
223
|
+
if (activeRequest) {
|
224
|
+
activeRequest[0].push(callback);
|
225
|
+
activeRequest[1].push(resolveContext.yield);
|
226
|
+
return;
|
227
|
+
}
|
228
|
+
} else {
|
229
|
+
const activeRequest = activeRequests.get(identifier);
|
230
|
+
if (activeRequest) {
|
231
|
+
activeRequest.push(callback);
|
232
|
+
return;
|
233
|
+
}
|
208
234
|
}
|
209
235
|
const itemCache = cache.getItemCache(identifier, null);
|
210
|
-
let callbacks;
|
211
|
-
const done =
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
236
|
+
let callbacks, yields;
|
237
|
+
const done = withYield
|
238
|
+
? (err, result) => {
|
239
|
+
if (callbacks === undefined) {
|
240
|
+
if (err) {
|
241
|
+
callback(err);
|
242
|
+
} else {
|
243
|
+
if (result)
|
244
|
+
for (const r of result) resolveContext.yield(r);
|
245
|
+
callback(null, null);
|
246
|
+
}
|
247
|
+
yields = undefined;
|
248
|
+
callbacks = false;
|
249
|
+
} else {
|
250
|
+
if (err) {
|
251
|
+
for (const cb of callbacks) cb(err);
|
252
|
+
} else {
|
253
|
+
for (let i = 0; i < callbacks.length; i++) {
|
254
|
+
const cb = callbacks[i];
|
255
|
+
const yield_ = yields[i];
|
256
|
+
if (result) for (const r of result) yield_(r);
|
257
|
+
cb(null, null);
|
258
|
+
}
|
259
|
+
}
|
260
|
+
activeRequestsWithYield.delete(identifier);
|
261
|
+
yields = undefined;
|
262
|
+
callbacks = false;
|
263
|
+
}
|
264
|
+
}
|
265
|
+
: (err, result) => {
|
266
|
+
if (callbacks === undefined) {
|
267
|
+
callback(err, result);
|
268
|
+
callbacks = false;
|
269
|
+
} else {
|
270
|
+
for (const callback of callbacks) {
|
271
|
+
callback(err, result);
|
272
|
+
}
|
273
|
+
activeRequests.delete(identifier);
|
274
|
+
callbacks = false;
|
275
|
+
}
|
276
|
+
};
|
223
277
|
/**
|
224
278
|
* @param {Error=} err error if any
|
225
279
|
* @param {CacheEntry=} cacheEntry cache entry
|
@@ -276,7 +330,14 @@ class ResolverCachePlugin {
|
|
276
330
|
}
|
277
331
|
};
|
278
332
|
itemCache.get(processCacheResult);
|
279
|
-
if (callbacks === undefined) {
|
333
|
+
if (withYield && callbacks === undefined) {
|
334
|
+
callbacks = [callback];
|
335
|
+
yields = [resolveContext.yield];
|
336
|
+
activeRequestsWithYield.set(
|
337
|
+
identifier,
|
338
|
+
/** @type {[any, any]} */ ([callbacks, yields])
|
339
|
+
);
|
340
|
+
} else if (callbacks === undefined) {
|
280
341
|
callbacks = [callback];
|
281
342
|
activeRequests.set(identifier, callbacks);
|
282
343
|
}
|
@@ -121,8 +121,7 @@ const resolve = browsers => {
|
|
121
121
|
// baidu: Not supported
|
122
122
|
// and_uc: Not supported
|
123
123
|
// kaios: Not supported
|
124
|
-
|
125
|
-
node: [13, 14]
|
124
|
+
node: [12, 17]
|
126
125
|
});
|
127
126
|
|
128
127
|
return {
|
@@ -248,8 +247,7 @@ const resolve = browsers => {
|
|
248
247
|
// baidu: Not supported
|
249
248
|
// and_uc: Not supported
|
250
249
|
// kaios: Not supported
|
251
|
-
|
252
|
-
node: [13, 14]
|
250
|
+
node: [12, 17]
|
253
251
|
}),
|
254
252
|
dynamicImport: es6DynamicImport,
|
255
253
|
dynamicImportInWorker: es6DynamicImport && !anyNode,
|
@@ -272,7 +270,7 @@ const resolve = browsers => {
|
|
272
270
|
// baidu: Unknown support
|
273
271
|
// and_uc: Unknown support
|
274
272
|
// kaios: Unknown support
|
275
|
-
node:
|
273
|
+
node: 12
|
276
274
|
}),
|
277
275
|
optionalChaining: rawChecker({
|
278
276
|
chrome: 80,
|
package/lib/config/defaults.js
CHANGED
@@ -907,6 +907,7 @@ const applyOutputDefaults = (
|
|
907
907
|
D(output, "strictModuleExceptionHandling", false);
|
908
908
|
|
909
909
|
const optimistic = v => v || v === undefined;
|
910
|
+
const conditionallyOptimistic = (v, c) => (v === undefined && c) || v;
|
910
911
|
F(
|
911
912
|
output.environment,
|
912
913
|
"arrowFunction",
|
@@ -920,8 +921,12 @@ const applyOutputDefaults = (
|
|
920
921
|
);
|
921
922
|
F(output.environment, "forOf", () => tp && optimistic(tp.forOf));
|
922
923
|
F(output.environment, "bigIntLiteral", () => tp && tp.bigIntLiteral);
|
923
|
-
F(output.environment, "dynamicImport", () =>
|
924
|
-
|
924
|
+
F(output.environment, "dynamicImport", () =>
|
925
|
+
conditionallyOptimistic(tp && tp.dynamicImport, output.module)
|
926
|
+
);
|
927
|
+
F(output.environment, "module", () =>
|
928
|
+
conditionallyOptimistic(tp && tp.module, output.module)
|
929
|
+
);
|
925
930
|
|
926
931
|
const { trustedTypes } = output;
|
927
932
|
if (trustedTypes) {
|
@@ -488,6 +488,7 @@ const getNormalizedEntryStatic = entry => {
|
|
488
488
|
filename: value.filename,
|
489
489
|
layer: value.layer,
|
490
490
|
runtime: value.runtime,
|
491
|
+
baseUri: value.baseUri,
|
491
492
|
publicPath: value.publicPath,
|
492
493
|
chunkLoading: value.chunkLoading,
|
493
494
|
asyncChunks: value.asyncChunks,
|
@@ -274,78 +274,71 @@ class CssLoadingRuntimeModule extends RuntimeModule {
|
|
274
274
|
"",
|
275
275
|
withLoading
|
276
276
|
? Template.asString([
|
277
|
-
`${fn}.css = ${runtimeTemplate.basicFunction(
|
278
|
-
"
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
277
|
+
`${fn}.css = ${runtimeTemplate.basicFunction("chunkId, promises", [
|
278
|
+
"// css chunk loading",
|
279
|
+
`var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
|
280
|
+
'if(installedChunkData !== 0) { // 0 means "already installed".',
|
281
|
+
Template.indent([
|
282
|
+
"",
|
283
|
+
'// a Promise means "currently loading".',
|
284
|
+
"if(installedChunkData) {",
|
285
|
+
Template.indent(["promises.push(installedChunkData[2]);"]),
|
286
|
+
"} else {",
|
287
|
+
Template.indent([
|
288
|
+
hasCssMatcher === true
|
289
|
+
? "if(true) { // all chunks have CSS"
|
290
|
+
: `if(${hasCssMatcher("chunkId")}) {`,
|
291
|
+
Template.indent([
|
292
|
+
"// setup Promise in chunk cache",
|
293
|
+
`var promise = new Promise(${runtimeTemplate.expressionFunction(
|
294
|
+
`installedChunkData = installedChunks[chunkId] = [resolve, reject]`,
|
295
|
+
"resolve, reject"
|
296
|
+
)});`,
|
297
|
+
"promises.push(installedChunkData[2] = promise);",
|
298
|
+
"",
|
299
|
+
"// start chunk loading",
|
300
|
+
`var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkCssFilename}(chunkId);`,
|
301
|
+
"// create error before stack unwound to get useful stacktrace later",
|
302
|
+
"var error = new Error();",
|
303
|
+
`var loadingEnded = ${runtimeTemplate.basicFunction(
|
304
|
+
"event",
|
305
|
+
[
|
306
|
+
`if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`,
|
296
307
|
Template.indent([
|
297
|
-
"
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
"var errorType = event && event.type;",
|
320
|
-
"var realSrc = event && event.target && event.target.src;",
|
321
|
-
"error.message = 'Loading css chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
|
322
|
-
"error.name = 'ChunkLoadError';",
|
323
|
-
"error.type = errorType;",
|
324
|
-
"error.request = realSrc;",
|
325
|
-
"installedChunkData[1](error);"
|
326
|
-
]),
|
327
|
-
"} else {",
|
328
|
-
Template.indent([
|
329
|
-
`loadCssChunkData(${RuntimeGlobals.moduleFactories}, link, chunkId);`,
|
330
|
-
"installedChunkData[0]();"
|
331
|
-
]),
|
332
|
-
"}"
|
333
|
-
]),
|
334
|
-
"}"
|
335
|
-
]),
|
336
|
-
"}"
|
337
|
-
]
|
338
|
-
)};`,
|
339
|
-
"var link = loadStylesheet(chunkId, url, loadingEnded);"
|
308
|
+
"installedChunkData = installedChunks[chunkId];",
|
309
|
+
"if(installedChunkData !== 0) installedChunks[chunkId] = undefined;",
|
310
|
+
"if(installedChunkData) {",
|
311
|
+
Template.indent([
|
312
|
+
'if(event.type !== "load") {',
|
313
|
+
Template.indent([
|
314
|
+
"var errorType = event && event.type;",
|
315
|
+
"var realSrc = event && event.target && event.target.src;",
|
316
|
+
"error.message = 'Loading css chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
|
317
|
+
"error.name = 'ChunkLoadError';",
|
318
|
+
"error.type = errorType;",
|
319
|
+
"error.request = realSrc;",
|
320
|
+
"installedChunkData[1](error);"
|
321
|
+
]),
|
322
|
+
"} else {",
|
323
|
+
Template.indent([
|
324
|
+
`loadCssChunkData(${RuntimeGlobals.moduleFactories}, link, chunkId);`,
|
325
|
+
"installedChunkData[0]();"
|
326
|
+
]),
|
327
|
+
"}"
|
328
|
+
]),
|
329
|
+
"}"
|
340
330
|
]),
|
341
|
-
"}
|
342
|
-
]
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
331
|
+
"}"
|
332
|
+
]
|
333
|
+
)};`,
|
334
|
+
"var link = loadStylesheet(chunkId, url, loadingEnded);"
|
335
|
+
]),
|
336
|
+
"} else installedChunks[chunkId] = 0;"
|
337
|
+
]),
|
338
|
+
"}"
|
339
|
+
]),
|
340
|
+
"}"
|
341
|
+
])};`
|
349
342
|
])
|
350
343
|
: "// no chunk loading",
|
351
344
|
"",
|
@@ -19,6 +19,7 @@ const { compareModulesByIdentifier } = require("../util/comparators");
|
|
19
19
|
const createSchemaValidation = require("../util/create-schema-validation");
|
20
20
|
const createHash = require("../util/createHash");
|
21
21
|
const memoize = require("../util/memoize");
|
22
|
+
const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
|
22
23
|
const CssExportsGenerator = require("./CssExportsGenerator");
|
23
24
|
const CssGenerator = require("./CssGenerator");
|
24
25
|
const CssParser = require("./CssParser");
|
@@ -201,7 +202,7 @@ class CssModulesPlugin {
|
|
201
202
|
hash.update(chunkGraph.getModuleHash(module, chunk.runtime));
|
202
203
|
}
|
203
204
|
const digest = /** @type {string} */ (hash.digest(hashDigest));
|
204
|
-
chunk.contentHash.css = digest
|
205
|
+
chunk.contentHash.css = nonNumericOnlyHash(digest, hashDigestLength);
|
205
206
|
});
|
206
207
|
compilation.hooks.renderManifest.tap(plugin, (result, options) => {
|
207
208
|
const { chunkGraph } = compilation;
|
@@ -343,7 +343,8 @@ const interceptAllJavascriptModulesPluginHooks = (compilation, tracer) => {
|
|
343
343
|
};
|
344
344
|
|
345
345
|
const makeInterceptorFor = (instance, tracer) => hookName => ({
|
346
|
-
register:
|
346
|
+
register: tapInfo => {
|
347
|
+
const { name, type, fn } = tapInfo;
|
347
348
|
const newFn =
|
348
349
|
// Don't tap our own hooks to ensure stream can close cleanly
|
349
350
|
name === pluginName
|
@@ -354,9 +355,7 @@ const makeInterceptorFor = (instance, tracer) => hookName => ({
|
|
354
355
|
fn
|
355
356
|
});
|
356
357
|
return {
|
357
|
-
|
358
|
-
type,
|
359
|
-
context,
|
358
|
+
...tapInfo,
|
360
359
|
fn: newFn
|
361
360
|
};
|
362
361
|
}
|
@@ -37,7 +37,7 @@ const splitContextFromPrefix = prefix => {
|
|
37
37
|
};
|
38
38
|
};
|
39
39
|
|
40
|
-
/** @typedef {Partial<Omit<ContextDependencyOptions, "resource"
|
40
|
+
/** @typedef {Partial<Omit<ContextDependencyOptions, "resource">>} PartialContextDependencyOptions */
|
41
41
|
|
42
42
|
/** @typedef {{ new(options: ContextDependencyOptions, range: [number, number], valueRange: [number, number]): ContextDependency }} ContextDependencyConstructor */
|
43
43
|
|
@@ -53,12 +53,18 @@ class ContextElementDependency extends ModuleDependency {
|
|
53
53
|
}
|
54
54
|
|
55
55
|
serialize(context) {
|
56
|
-
context
|
56
|
+
const { write } = context;
|
57
|
+
write(this._typePrefix);
|
58
|
+
write(this._category);
|
59
|
+
write(this.referencedExports);
|
57
60
|
super.serialize(context);
|
58
61
|
}
|
59
62
|
|
60
63
|
deserialize(context) {
|
61
|
-
|
64
|
+
const { read } = context;
|
65
|
+
this._typePrefix = read();
|
66
|
+
this._category = read();
|
67
|
+
this.referencedExports = read();
|
62
68
|
super.deserialize(context);
|
63
69
|
}
|
64
70
|
}
|
@@ -46,6 +46,12 @@ const getProperty = (moduleGraph, module, exportName, property, runtime) => {
|
|
46
46
|
}
|
47
47
|
}
|
48
48
|
switch (property) {
|
49
|
+
case "canMangle": {
|
50
|
+
const exportsInfo = moduleGraph.getExportsInfo(module);
|
51
|
+
const exportInfo = exportsInfo.getExportInfo(exportName);
|
52
|
+
if (exportInfo) return exportInfo.canMangle;
|
53
|
+
return exportsInfo.otherExportsInfo.canMangle;
|
54
|
+
}
|
49
55
|
case "used":
|
50
56
|
return (
|
51
57
|
moduleGraph.getExportsInfo(module).getUsed(exportName, runtime) !==
|