webpack 5.111.0 → 5.111.1
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/APIPlugin.js +3 -4
- package/lib/CompatibilityPlugin.js +3 -4
- package/lib/Compilation.js +16 -35
- package/lib/Compiler.js +4 -5
- package/lib/ConstPlugin.js +16 -132
- package/lib/DependencyTemplate.js +2 -1
- package/lib/DotenvPlugin.js +24 -28
- package/lib/ErrorHelpers.js +113 -0
- package/lib/ExportsInfo.js +20 -16
- package/lib/ExternalModule.js +6 -8
- package/lib/FlagDependencyExportsPlugin.js +8 -13
- package/lib/FlagDependencyUsagePlugin.js +9 -13
- package/lib/Generator.js +24 -2
- package/lib/HotModuleReplacementPlugin.js +2 -0
- package/lib/IgnorePlugin.js +1 -1
- package/lib/LoaderOptionsPlugin.js +1 -1
- package/lib/Module.js +3 -3
- package/lib/ModuleGraph.js +6 -9
- package/lib/MultiCompiler.js +6 -16
- package/lib/NormalModule.js +96 -44
- package/lib/RuntimeTemplate.js +33 -43
- package/lib/SourceMapDevToolPlugin.js +53 -103
- package/lib/TemplatedPathPlugin.js +16 -59
- package/lib/asset/AssetBytesGenerator.js +7 -1
- package/lib/asset/AssetGenerator.js +25 -16
- package/lib/asset/AssetSourceGenerator.js +7 -1
- package/lib/buildChunkGraph.js +11 -15
- package/lib/cache/MemoryCachePlugin.js +4 -4
- package/lib/cache/MemoryWithGcCachePlugin.js +7 -8
- package/lib/cache/PackFileCacheStrategy.js +3 -18
- package/lib/cache/getLazyHashedEtag.js +3 -5
- package/lib/config/browserslistTargetHandler.js +2 -8
- package/lib/config/defaults.js +52 -78
- package/lib/config/getClaimedAssetTypes.js +10 -11
- package/lib/config/target.js +3 -4
- package/lib/{ContextExclusionPlugin.js → context/ContextExclusionPlugin.js} +1 -1
- package/lib/{ContextModule.js → context/ContextModule.js} +37 -34
- package/lib/{ContextModuleFactory.js → context/ContextModuleFactory.js} +19 -21
- package/lib/{ContextReplacementPlugin.js → context/ContextReplacementPlugin.js} +4 -4
- package/lib/css/CssGenerator.js +19 -11
- package/lib/css/CssParser.js +18 -20
- package/lib/css/cssMinify.js +32 -29
- package/lib/css/data.js +797 -288
- package/lib/css/syntax.js +2250 -934
- package/lib/debug/ProfilingPlugin.js +3 -4
- package/lib/dependencies/CommonJsExportRequireDependency.js +10 -11
- package/lib/dependencies/CommonJsImportsParserPlugin.js +4 -5
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +2 -4
- package/lib/dependencies/ContextDependency.js +1 -1
- package/lib/dependencies/ContextDependencyHelpers.js +3 -9
- package/lib/dependencies/ContextElementDependency.js +1 -1
- package/lib/dependencies/CssIcssExportDependency.js +6 -8
- package/lib/dependencies/CssIcssImportDependency.js +3 -6
- package/lib/dependencies/CssUrlDependency.js +3 -5
- package/lib/dependencies/HarmonyCompatibilityDependency.js +11 -20
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +3 -4
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +2 -4
- package/lib/dependencies/HarmonyExportExpressionDependency.js +3 -4
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +3 -4
- package/lib/dependencies/HarmonyExportInitFragment.js +26 -19
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +7 -28
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +103 -16
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +3 -4
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +16 -2
- package/lib/dependencies/HtmlEntryDependency.js +74 -102
- package/lib/dependencies/HtmlInlineScriptDependency.js +3 -4
- package/lib/dependencies/HtmlInlineStyleDependency.js +3 -4
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/ImportMetaGlobHelpers.js +1 -1
- package/lib/dependencies/ImportMetaPlugin.js +8 -10
- package/lib/dependencies/ImportParserPlugin.js +1 -1
- package/lib/dependencies/LoaderPlugin.js +26 -1
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/URLContextDependency.js +1 -1
- package/lib/dependencies/URLDependency.js +6 -5
- package/lib/dependencies/WorkerAndWorkletPlugin.js +15 -21
- package/lib/dependencies/WorkerDependency.js +6 -5
- package/lib/dependencies/WorkletDependency.js +6 -9
- package/lib/errors/HookWebpackError.js +3 -2
- package/lib/hmr/LazyCompilationPlugin.js +3 -5
- package/lib/html/HtmlGenerator.js +61 -82
- package/lib/html/HtmlModulesPlugin.js +88 -139
- package/lib/html/HtmlParser.js +97 -141
- package/lib/html/data.js +21 -0
- package/lib/html/htmlMinify.js +10 -11
- package/lib/html/syntax.js +883 -993
- package/lib/index.js +46 -3
- package/lib/javascript/ChunkFormatHelpers.js +4 -3
- package/lib/javascript/JavascriptGenerator.js +8 -1
- package/lib/javascript/JavascriptModulesPlugin.js +21 -48
- package/lib/javascript/JavascriptParser.js +721 -178
- package/lib/javascript/parser.js +6 -0
- package/lib/javascript/syntax.js +420 -92
- package/lib/json/JsonGenerator.js +7 -1
- package/lib/library/ModuleLibraryPlugin.js +64 -136
- package/lib/loaders/LoaderRunner.js +137 -9
- package/lib/node/NodeWatchFileSystem.js +3 -9
- package/lib/optimize/AggressiveMergingPlugin.js +3 -5
- package/lib/optimize/ConcatenatedModule.js +81 -100
- package/lib/optimize/FlagIncludedChunksPlugin.js +3 -11
- package/lib/optimize/InnerGraphPlugin.js +7 -13
- package/lib/optimize/LimitChunkCountPlugin.js +5 -8
- package/lib/optimize/MangleExportsPlugin.js +3 -4
- package/lib/optimize/ModuleConcatenationPlugin.js +3 -4
- package/lib/optimize/SideEffectsFlagPlugin.js +7 -19
- package/lib/optimize/SplitChunksPlugin.js +2 -4
- package/lib/performance/BroadContextsPlugin.js +1 -1
- package/lib/performance/CacheEffectivenessPlugin.js +3 -4
- package/lib/performance/SizeLimitsPlugin.js +2 -4
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +6 -8
- package/lib/prefetch/ResourceHintPlugin.js +17 -21
- package/lib/prefetch/StartupAssetHintRuntimeModule.js +7 -10
- package/lib/runtime/AsyncModuleRuntimeModule.js +3 -5
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -4
- package/lib/runtime/GlobalRuntimeModule.js +2 -4
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +55 -85
- package/lib/schemes/DataUriPlugin.js +3 -6
- package/lib/schemes/VirtualUrlPlugin.js +1 -1
- package/lib/serialization/BinaryMiddleware.js +9 -9
- package/lib/serialization/FileMiddleware.js +16 -16
- package/lib/serialization/ObjectMiddleware.js +30 -33
- package/lib/stats/DefaultStatsFactoryPlugin.js +3 -4
- package/lib/typescript/TypeScriptPlugin.js +2 -3
- package/lib/url/URLParserPlugin.js +6 -8
- package/lib/util/LocConverter.js +4 -7
- package/lib/util/SourceProcessor.js +15 -22
- package/lib/util/chainedImports.js +3 -4
- package/lib/util/concatenate.js +4 -4
- package/lib/util/createHooksRegistry.js +1 -2
- package/lib/util/dataURL.js +2 -3
- package/lib/util/deterministicGrouping.js +8 -13
- package/lib/util/findGraphRoots.js +6 -13
- package/lib/util/globUtils.js +1 -1
- package/lib/util/hash/wasm-hash.js +3 -4
- package/lib/util/internalSerializables.js +1 -1
- package/lib/util/semver.js +5 -3
- package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -1
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -1
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +3 -4
- package/lib/wasm-sync/WebAssemblyGenerator.js +6 -1
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -1
- package/lib/wasm-sync/WebAssemblyUtils.js +2 -4
- package/package.json +30 -23
- package/types.d.ts +299 -280
package/lib/RuntimeTemplate.js
CHANGED
|
@@ -745,8 +745,7 @@ class RuntimeTemplate {
|
|
|
745
745
|
: undefined;
|
|
746
746
|
// A reassigned `__webpack_public_path__` cannot reach a baked literal, and `.p`
|
|
747
747
|
// belongs to a runtime, so only the runtimes it reaches keep the runtime form.
|
|
748
|
-
// `url-inline` is unaffected:
|
|
749
|
-
// the reassigned value at the call site rather than through the wrapper.
|
|
748
|
+
// `url-inline` is unaffected: it reads the value at the call site.
|
|
750
749
|
if (
|
|
751
750
|
form !== "url-inline" &&
|
|
752
751
|
APIPlugin.runtimeUsesPublicPathOverride(
|
|
@@ -774,12 +773,13 @@ class RuntimeTemplate {
|
|
|
774
773
|
return true;
|
|
775
774
|
}
|
|
776
775
|
|
|
777
|
-
// `url-inline` asks whether the file can be named at the call site
|
|
778
|
-
// its `.p + <file>` fallback spells that without `import.meta
|
|
779
|
-
// below does not rule it out
|
|
776
|
+
// `url-inline` asks only whether the file can be named at the call site, and
|
|
777
|
+
// its `.p + <file>` fallback spells that without `import.meta`, so the gate
|
|
778
|
+
// below does not rule it out.
|
|
779
|
+
|
|
780
780
|
// `environment.module` is deliberately not consulted: ESM output writes
|
|
781
|
-
// `import.meta` regardless
|
|
782
|
-
//
|
|
781
|
+
// `import.meta` regardless, so the url forms match what the rest of the
|
|
782
|
+
// bundle already assumes the target reads.
|
|
783
783
|
if (form === "url-inline") return true;
|
|
784
784
|
// `eval` devtool wraps each module in `eval(...)`, where `import.meta` is a
|
|
785
785
|
// syntax error. Runtime modules are emitted beside them, never wrapped.
|
|
@@ -1124,10 +1124,9 @@ class RuntimeTemplate {
|
|
|
1124
1124
|
const chunks = this._moduleChunks(module, chunkGraph);
|
|
1125
1125
|
const parts = this._resolvePublicPathPrefix(publicPath);
|
|
1126
1126
|
if (parts === null) return null;
|
|
1127
|
-
// A protocol-relative base names a host but no scheme, and the runtime reads
|
|
1128
|
-
// against the
|
|
1129
|
-
//
|
|
1130
|
-
// here. Nothing walks back to the output root first: the base replaces it.
|
|
1127
|
+
// A protocol-relative base names a host but no scheme, and the runtime reads
|
|
1128
|
+
// it against the very url this literal resolves against, so it may stay that
|
|
1129
|
+
// way. Nothing walks back to the output root: the base replaces it.
|
|
1131
1130
|
if (base.startsWith("//")) {
|
|
1132
1131
|
return this._specifierOf(
|
|
1133
1132
|
[["literal", base], ...rootedParts(parts), ["literal", filename]],
|
|
@@ -1192,10 +1191,9 @@ class RuntimeTemplate {
|
|
|
1192
1191
|
let base;
|
|
1193
1192
|
let found = false;
|
|
1194
1193
|
for (const chunk of this.compilation.chunks) {
|
|
1195
|
-
//
|
|
1196
|
-
//
|
|
1197
|
-
//
|
|
1198
|
-
// chunk already share the base it sets, however their descriptors differ.
|
|
1194
|
+
// A literal must agree with the one value `BaseUriRuntimeModule` writes, and
|
|
1195
|
+
// that reads the entry options off the chunk it is emitted into, so only a
|
|
1196
|
+
// chunk carrying a runtime has a say.
|
|
1199
1197
|
if (!chunk.hasRuntime()) continue;
|
|
1200
1198
|
const entryOptions = chunk.getEntryOptions();
|
|
1201
1199
|
// An entry this code cannot run under has no say in the base it resolves to.
|
|
@@ -1483,14 +1481,13 @@ class RuntimeTemplate {
|
|
|
1483
1481
|
}
|
|
1484
1482
|
if (!this.supportTemplateLiteral()) return this._es5Concatenation(args);
|
|
1485
1483
|
|
|
1486
|
-
// cost comparison between template literal and concatenation
|
|
1487
|
-
//
|
|
1488
|
-
//
|
|
1489
|
-
//
|
|
1490
|
-
//
|
|
1491
|
-
//
|
|
1492
|
-
//
|
|
1493
|
-
// e. g. `x${a}x${b}x${c}x` (3*3 = 9) is shorter than "x"+a+"x"+b+"x"+c+"x" (4+4+4 = 12)
|
|
1484
|
+
// WHY: cost comparison between a template literal and a concatenation, both
|
|
1485
|
+
// needing equal surroundings (`xxx` against "xxx"). A template literal costs
|
|
1486
|
+
// a constant 3 chars per expression; an es5 concatenation costs 3 + n chars
|
|
1487
|
+
// for n expressions in a row, and reduces by 3 where it ends with an
|
|
1488
|
+
// expression or starts with a single one. So `${a}${b}${c}` (3*3 = 9) is
|
|
1489
|
+
// longer than ""+a+b+c ((3+3)-3 = 3), while `x${a}x${b}x${c}x` (3*3 = 9) is
|
|
1490
|
+
// shorter than "x"+a+"x"+b+"x"+c+"x" (4+4+4 = 12).
|
|
1494
1491
|
|
|
1495
1492
|
let templateCost = 0;
|
|
1496
1493
|
let concatenationCost = 0;
|
|
@@ -2353,10 +2350,9 @@ class RuntimeTemplate {
|
|
|
2353
2350
|
request,
|
|
2354
2351
|
weak
|
|
2355
2352
|
});
|
|
2356
|
-
//
|
|
2357
|
-
//
|
|
2358
|
-
//
|
|
2359
|
-
// block-scoped (`let`/`const`).
|
|
2353
|
+
// A harmony import may sit inside a runtime-condition `if` block yet be
|
|
2354
|
+
// referenced outside it, so it stays function-scoped with `var` rather than
|
|
2355
|
+
// block-scoped.
|
|
2360
2356
|
const optDeclaration = update ? "" : "var ";
|
|
2361
2357
|
|
|
2362
2358
|
const exportsType = module.getExportsType(
|
|
@@ -2495,10 +2491,8 @@ class RuntimeTemplate {
|
|
|
2495
2491
|
}
|
|
2496
2492
|
// accessing the .default property is same thing as `require()` the module.
|
|
2497
2493
|
|
|
2498
|
-
//
|
|
2499
|
-
//
|
|
2500
|
-
// is translated to
|
|
2501
|
-
// var mod = require("cjs"); mod.x;
|
|
2494
|
+
// So `import mod from "cjs"; mod.default.x` translates to
|
|
2495
|
+
// `var mod = require("cjs"); mod.x`.
|
|
2502
2496
|
switch (exportsType) {
|
|
2503
2497
|
case "dynamic":
|
|
2504
2498
|
if (isCall) {
|
|
@@ -2538,10 +2532,9 @@ class RuntimeTemplate {
|
|
|
2538
2532
|
exportsType === "default-only" ||
|
|
2539
2533
|
exportsType === "default-with-named"
|
|
2540
2534
|
) {
|
|
2541
|
-
//
|
|
2542
|
-
//
|
|
2543
|
-
//
|
|
2544
|
-
// we will need to createFakeNamespaceObject that simulates ES Module namespace object
|
|
2535
|
+
// `exportName.length` is 0, so the namespace object is used in an unknown
|
|
2536
|
+
// way — `import * as ns from "cjs"; console.log(ns)` — and needs
|
|
2537
|
+
// `createFakeNamespaceObject` to simulate an ES module namespace.
|
|
2545
2538
|
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
|
2546
2539
|
initFragments.push(
|
|
2547
2540
|
new InitFragment(
|
|
@@ -3443,9 +3436,8 @@ class RuntimeTemplate {
|
|
|
3443
3436
|
// emitted and filled in once the hash exists.
|
|
3444
3437
|
const deferred = template === undefined || HASH_IN_FILENAME.test(template);
|
|
3445
3438
|
// An id names the chunk in the stand-in, and one nothing could resolve would
|
|
3446
|
-
// reach the bundle verbatim. The whole name is re-resolved later
|
|
3447
|
-
//
|
|
3448
|
-
// One of the two always names where the reference goes.
|
|
3439
|
+
// reach the bundle verbatim. The whole name is re-resolved later, so any hash
|
|
3440
|
+
// spelling is fine here; one of the two always names the destination.
|
|
3449
3441
|
const chunks =
|
|
3450
3442
|
consumingChunks ||
|
|
3451
3443
|
this._moduleChunks(/** @type {Module} */ (consumingModule), chunkGraph);
|
|
@@ -4355,11 +4347,9 @@ class RuntimeTemplate {
|
|
|
4355
4347
|
compilation.hooks.processAssets.tapPromise(
|
|
4356
4348
|
{
|
|
4357
4349
|
name: PASS_NAME,
|
|
4358
|
-
// Before source maps are written and before a minifier runs
|
|
4359
|
-
// the asset
|
|
4360
|
-
// Every hash it reads is
|
|
4361
|
-
// every `processAssets` stage — and `RealContentHashPlugin` still repairs
|
|
4362
|
-
// the names afterwards.
|
|
4350
|
+
// Before source maps are written and before a minifier runs, since both
|
|
4351
|
+
// read the asset and a stand-in differs in length from what replaces it.
|
|
4352
|
+
// Every hash it reads is settled: `createHash` precedes every stage.
|
|
4363
4353
|
stage: getCompilation().PROCESS_ASSETS_STAGE_DERIVED
|
|
4364
4354
|
},
|
|
4365
4355
|
async () => {
|
|
@@ -152,11 +152,9 @@ const extractSourceAndMap = (file, asset, options, registry) => {
|
|
|
152
152
|
if (!registry.has(file)) registry.set(file, asset);
|
|
153
153
|
return { source, sourceMap, mapSource: asset };
|
|
154
154
|
}
|
|
155
|
-
// The current asset
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
// `source` from the current asset so that any prior wrappers (e.g.
|
|
159
|
-
// appended sourceMappingURL comments) are preserved.
|
|
155
|
+
// The current asset, typically a `RawSource` an earlier instance left, has no
|
|
156
|
+
// internal map, so re-extract one from the pinned original. `source` still
|
|
157
|
+
// comes from the current asset, preserving any wrappers it gained.
|
|
160
158
|
const original = registry.get(file);
|
|
161
159
|
if (!original) return;
|
|
162
160
|
sourceMap = original.sourceAndMap
|
|
@@ -262,12 +260,9 @@ class SourceMapDevToolPlugin {
|
|
|
262
260
|
this.namespace = options.namespace || "";
|
|
263
261
|
/** @type {SourceMapDevToolPluginOptions} */
|
|
264
262
|
this.options = options;
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
// `JSON.stringify` rather than a homemade separator so that any
|
|
269
|
-
// special characters (e.g. `|` inside a publicPath or sourceRoot)
|
|
270
|
-
// can't accidentally make two different option sets collide.
|
|
263
|
+
// Salt from the output-affecting options, so two instances on the same asset
|
|
264
|
+
// never share a cache entry. Serialized with `JSON.stringify` rather than a
|
|
265
|
+
// separator, which a `|` in a publicPath could collide through.
|
|
271
266
|
/** @type {string} */
|
|
272
267
|
this._cacheSalt = JSON.stringify([
|
|
273
268
|
toCacheKeyValue(options.filename),
|
|
@@ -326,12 +321,9 @@ class SourceMapDevToolPlugin {
|
|
|
326
321
|
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
|
327
322
|
new SourceMapDevToolModuleOptionsPlugin(options).apply(compilation);
|
|
328
323
|
|
|
329
|
-
//
|
|
330
|
-
//
|
|
331
|
-
//
|
|
332
|
-
// has replaced the asset with a `RawSource`. The registry lives on a
|
|
333
|
-
// module-scoped `WeakMap` keyed by compilation so it is released
|
|
334
|
-
// automatically and never pollutes the compilation object.
|
|
324
|
+
// Every instance on a compilation shares this registry of pristine
|
|
325
|
+
// sources, so a later one still recovers the original map after the first
|
|
326
|
+
// replaced the asset. Keyed by compilation, so it releases on its own.
|
|
335
327
|
const originalSources = getOriginalSourceRegistry(compilation);
|
|
336
328
|
|
|
337
329
|
compilation.hooks.processAssets.tapAsync(
|
|
@@ -372,23 +364,12 @@ class SourceMapDevToolPlugin {
|
|
|
372
364
|
const tasks = [];
|
|
373
365
|
let fileIndex = 0;
|
|
374
366
|
|
|
375
|
-
//
|
|
376
|
-
//
|
|
377
|
-
//
|
|
378
|
-
//
|
|
379
|
-
//
|
|
380
|
-
//
|
|
381
|
-
// caches, churning allocations (measured: +700 MB peak RSS,
|
|
382
|
-
// +6 s wall time on a 50×1000 synthetic build).
|
|
383
|
-
//
|
|
384
|
-
// Sharing one set lets each shared subtree be walked exactly
|
|
385
|
-
// once. The trade-off is that subsequent chunks' `sourceAndMap`
|
|
386
|
-
// calls can repopulate a shared module's `_cachedMaps` after
|
|
387
|
-
// its own clear was skipped (because the module is already in
|
|
388
|
-
// the visited set), leaving at most one populated cache entry
|
|
389
|
-
// per shared module at the end of the run — bounded to a few
|
|
390
|
-
// MB even at the scale of #20961. That's strictly preferable
|
|
391
|
-
// to the alternative's hundreds of MB of transient peak RSS.
|
|
367
|
+
// WHY: chunks share module-level `CachedSource` instances, so a
|
|
368
|
+
// per-call set re-walks each shared subtree once per chunk and every
|
|
369
|
+
// `sourceAndMap` then recomputes the cleared caches — measured at
|
|
370
|
+
// +700 MB peak RSS and +6 s on a 50×1000 build. One shared set walks
|
|
371
|
+
// each subtree once, at the cost of leaving at most one populated
|
|
372
|
+
// cache entry per shared module, a few MB even at #20961's scale.
|
|
392
373
|
const clearCacheVisited = new WeakSet();
|
|
393
374
|
|
|
394
375
|
asyncLib.each(
|
|
@@ -403,14 +384,12 @@ class SourceMapDevToolPlugin {
|
|
|
403
384
|
chunk
|
|
404
385
|
});
|
|
405
386
|
|
|
406
|
-
//
|
|
407
|
-
//
|
|
408
|
-
//
|
|
409
|
-
//
|
|
410
|
-
//
|
|
411
|
-
//
|
|
412
|
-
// in an asset filename can't be spoofed to collide with the
|
|
413
|
-
// salt portion of the identifier.
|
|
387
|
+
// WHY: the cache item identifier carries the per-instance salt, or
|
|
388
|
+
// two SourceMapDevToolPlugin instances targeting the same `file`
|
|
389
|
+
// would write different content to one key and invalidate every pack
|
|
390
|
+
// on each build. `JSON.stringify` encodes it, so a special character
|
|
391
|
+
// such as `|` in an asset filename cannot be spoofed to collide with
|
|
392
|
+
// the salt portion.
|
|
414
393
|
const cacheItem = cache.getItemCache(
|
|
415
394
|
JSON.stringify([file, this._cacheSalt]),
|
|
416
395
|
cache.mergeEtags(
|
|
@@ -427,12 +406,9 @@ class SourceMapDevToolPlugin {
|
|
|
427
406
|
* If presented in cache, reassigns assets. Cache assets already have source maps.
|
|
428
407
|
*/
|
|
429
408
|
if (cacheEntry) {
|
|
430
|
-
// Pin the still-unwrapped
|
|
431
|
-
//
|
|
432
|
-
//
|
|
433
|
-
// it lets a subsequent SourceMapDevToolPlugin instance
|
|
434
|
-
// extract the original map on demand even though the
|
|
435
|
-
// persistent cache hit lets us skip processing here.
|
|
409
|
+
// Pin the still-unwrapped source before `updateAsset` replaces
|
|
410
|
+
// it — a pointer assignment, no extraction — so a later
|
|
411
|
+
// instance can still reach the original map past this cache hit.
|
|
436
412
|
if (!originalSources.has(file)) {
|
|
437
413
|
originalSources.set(file, asset.source);
|
|
438
414
|
}
|
|
@@ -489,33 +465,21 @@ class SourceMapDevToolPlugin {
|
|
|
489
465
|
originalSources
|
|
490
466
|
);
|
|
491
467
|
|
|
492
|
-
//
|
|
493
|
-
//
|
|
494
|
-
//
|
|
495
|
-
// `
|
|
496
|
-
//
|
|
497
|
-
//
|
|
498
|
-
// spike on builds with thousands of chunks
|
|
499
|
-
// (webpack#20961). Keep `source` since downstream
|
|
500
|
-
// consumers reading the original asset still need it;
|
|
501
|
-
// `hash`/`size` default to retained because they're
|
|
502
|
-
// cheap to keep but expensive to rebuild.
|
|
503
|
-
// `clearCacheVisited` is shared across every call (see
|
|
504
|
-
// its declaration above for the rationale).
|
|
468
|
+
// WHY: the map `sourceAndMap` just composed otherwise sits on
|
|
469
|
+
// the CachedSource and every shared child until phase 2
|
|
470
|
+
// replaces the asset, which is the OOM spike of webpack#20961
|
|
471
|
+
// on builds with thousands of chunks. `source` is kept for
|
|
472
|
+
// downstream consumers, `hash` and `size` because they are
|
|
473
|
+
// cheap to hold and expensive to rebuild.
|
|
505
474
|
//
|
|
506
|
-
//
|
|
507
|
-
//
|
|
508
|
-
//
|
|
509
|
-
//
|
|
510
|
-
|
|
511
|
-
//
|
|
512
|
-
//
|
|
513
|
-
//
|
|
514
|
-
// `webpack-sources` 3.5, but `compilation.assets` may
|
|
515
|
-
// hold `Source`-like instances from a third-party
|
|
516
|
-
// plugin built against an older copy of
|
|
517
|
-
// `webpack-sources` (or a hand-rolled implementation).
|
|
518
|
-
// Calling it unconditionally would throw on those.
|
|
475
|
+
// `task.mapSource`, not `asset.source`: where the fallback to
|
|
476
|
+
// the pinned original ran — the current asset being a
|
|
477
|
+
// `RawSource` an earlier instance left — the original's caches
|
|
478
|
+
// are the ones `extractSourceAndMap` populated.
|
|
479
|
+
|
|
480
|
+
// Feature-detected, since `clearCache` landed in
|
|
481
|
+
// `webpack-sources` 3.5 and a third-party plugin may hand us a
|
|
482
|
+
// `Source` built against an older copy.
|
|
519
483
|
if (task && typeof task.mapSource.clearCache === "function") {
|
|
520
484
|
task.mapSource.clearCache(
|
|
521
485
|
{
|
|
@@ -660,14 +624,9 @@ class SourceMapDevToolPlugin {
|
|
|
660
624
|
const moduleFilenames =
|
|
661
625
|
/** @type {string[]} */
|
|
662
626
|
(modules.map((m) => moduleToSourceNameMapping.get(m)));
|
|
663
|
-
//
|
|
664
|
-
//
|
|
665
|
-
//
|
|
666
|
-
// object (webpack-sources keeps it cached). A second
|
|
667
|
-
// `SourceMapDevToolPlugin` instance that reads the original
|
|
668
|
-
// source through the registry would otherwise see our
|
|
669
|
-
// rewrites. Instead we build a fresh `outputSourceMap` for
|
|
670
|
-
// the .map file and leave the original alone.
|
|
627
|
+
// `sourceMap` is never mutated in place: the reference may be
|
|
628
|
+
// the same object a `SourceMapSource` has cached, so a second
|
|
629
|
+
// instance reading through the registry would see the rewrites.
|
|
671
630
|
/** @type {number[] | undefined} */
|
|
672
631
|
let ignoreList;
|
|
673
632
|
if (options.ignoreList) {
|
|
@@ -736,10 +695,9 @@ class SourceMapDevToolPlugin {
|
|
|
736
695
|
} else if (
|
|
737
696
|
typeof currentSourceMappingURLComment === "function"
|
|
738
697
|
) {
|
|
739
|
-
// Wrap the user's append function so the debug-id
|
|
740
|
-
//
|
|
741
|
-
//
|
|
742
|
-
// and lose its dynamic behavior.
|
|
698
|
+
// Wrap the user's append function so the debug-id comment is
|
|
699
|
+
// prepended at call time; concatenating would coerce the
|
|
700
|
+
// function to a string and lose its behavior.
|
|
743
701
|
const wrappedFn = currentSourceMappingURLComment;
|
|
744
702
|
currentSourceMappingURLComment = (pathData, assetInfo) =>
|
|
745
703
|
`${debugIdComment}${wrappedFn(pathData, assetInfo)}`;
|
|
@@ -766,14 +724,9 @@ class SourceMapDevToolPlugin {
|
|
|
766
724
|
}
|
|
767
725
|
|
|
768
726
|
if (sourceMapFilename) {
|
|
769
|
-
//
|
|
770
|
-
//
|
|
771
|
-
//
|
|
772
|
-
// `compilation.assets` until the build finishes — so
|
|
773
|
-
// storing the bytes off the V8 heap (where Buffers
|
|
774
|
-
// live, accounted as `external` memory) avoids keeping
|
|
775
|
-
// a large V8 string alive for the rest of the build
|
|
776
|
-
// and reduces heap pressure on `--max-old-space-size`.
|
|
727
|
+
// Hold the serialized map as a `Buffer`, which `RawSource`
|
|
728
|
+
// takes directly: the asset lives in `compilation.assets`
|
|
729
|
+
// until the build ends, and these bytes stay off the V8 heap.
|
|
777
730
|
const sourceMapBuffer = Buffer.from(
|
|
778
731
|
JSON.stringify(outputSourceMap),
|
|
779
732
|
"utf8"
|
|
@@ -820,10 +773,9 @@ class SourceMapDevToolPlugin {
|
|
|
820
773
|
})
|
|
821
774
|
);
|
|
822
775
|
}
|
|
823
|
-
// Preserve
|
|
824
|
-
//
|
|
825
|
-
//
|
|
826
|
-
// info (the schema allows string or string[]).
|
|
776
|
+
// Preserve the `related.sourceMap` entries earlier runs left on
|
|
777
|
+
// this asset, so every generated map stays discoverable; the
|
|
778
|
+
// schema allows a string or an array.
|
|
827
779
|
const existingSourceMap =
|
|
828
780
|
task.assetInfo.related &&
|
|
829
781
|
task.assetInfo.related.sourceMap;
|
|
@@ -879,11 +831,9 @@ class SourceMapDevToolPlugin {
|
|
|
879
831
|
`${PLUGIN_NAME}: append can't be a function when no filename is provided`
|
|
880
832
|
);
|
|
881
833
|
}
|
|
882
|
-
// Inline data-URL form: `[map]`
|
|
883
|
-
//
|
|
884
|
-
//
|
|
885
|
-
// than one `[url]` placeholder would otherwise re-encode
|
|
886
|
-
// the same JSON per match. Pre-compute both once.
|
|
834
|
+
// Inline data-URL form: `[map]` takes the raw JSON and `[url]`
|
|
835
|
+
// the same base64-encoded. Both are precomputed, or a template
|
|
836
|
+
// with two `[url]`s would re-encode per match.
|
|
887
837
|
const sourceMapString = JSON.stringify(outputSourceMap);
|
|
888
838
|
const sourceMapBase64 = Buffer.from(
|
|
889
839
|
sourceMapString,
|
|
@@ -77,10 +77,9 @@ const getPresentKinds = (path) => {
|
|
|
77
77
|
return kinds;
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
-
// `[fullhash:<
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
// to be inlined instead.
|
|
80
|
+
// In `[fullhash:<arg>]` a non-numeric argument names a digest, a numeric one just
|
|
81
|
+
// a length. A digest re-encodes the hash rather than reading it, so no stand-in
|
|
82
|
+
// can stand for it and the settled value must be inlined.
|
|
84
83
|
const FULL_HASH_DIGEST_REGEXP = /\[(?:fullhash|hash):(?!\d+\])\w/;
|
|
85
84
|
|
|
86
85
|
/**
|
|
@@ -408,11 +407,9 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
408
407
|
return path;
|
|
409
408
|
}
|
|
410
409
|
|
|
411
|
-
//
|
|
412
|
-
//
|
|
413
|
-
//
|
|
414
|
-
// when a replacer is invoked, which happens for present kinds), so this is
|
|
415
|
-
// output-identical.
|
|
410
|
+
// Build replacers only for the placeholders a template uses, since most use a
|
|
411
|
+
// handful. Construction has no side effects — those fire on invocation — so
|
|
412
|
+
// the output is identical either way.
|
|
416
413
|
const presentKinds = getPresentKinds(path);
|
|
417
414
|
|
|
418
415
|
const chunkGraph = data.chunkGraph;
|
|
@@ -422,21 +419,9 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
422
419
|
/** @type {Map<string, Replacer>} */
|
|
423
420
|
const replacements = new Map();
|
|
424
421
|
|
|
425
|
-
// Filename context
|
|
426
|
-
//
|
|
427
|
-
//
|
|
428
|
-
//
|
|
429
|
-
// for /some/path/file.js?query#fragment:
|
|
430
|
-
// [file] - /some/path/file.js
|
|
431
|
-
// [query] - ?query
|
|
432
|
-
// [fragment] - #fragment
|
|
433
|
-
// [base] - file.js
|
|
434
|
-
// [path] - /some/path/
|
|
435
|
-
// [name] - file
|
|
436
|
-
// [ext] - .js
|
|
437
|
-
//
|
|
438
|
-
// [containedfile] and [containedpath] are [file] and [path] kept inside
|
|
439
|
-
// `output.path`
|
|
422
|
+
// Filename context. Of `/some/path/file.js?query#fragment`, `[file]` is the
|
|
423
|
+
// path without query or fragment, `[base]` its basename, `[path]` its
|
|
424
|
+
// directory, `[name]`/`[ext]` its halves; `contained*` stay under `output.path`.
|
|
440
425
|
if (
|
|
441
426
|
typeof data.filename === "string" &&
|
|
442
427
|
(presentKinds.has("file") ||
|
|
@@ -534,15 +519,7 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
534
519
|
}
|
|
535
520
|
}
|
|
536
521
|
|
|
537
|
-
// Compilation context
|
|
538
|
-
//
|
|
539
|
-
// Placeholders
|
|
540
|
-
//
|
|
541
|
-
// [fullhash] - data.hash (3a4b5c6e7f)
|
|
542
|
-
//
|
|
543
|
-
// Legacy Placeholders
|
|
544
|
-
//
|
|
545
|
-
// [hash] - data.hash (3a4b5c6e7f)
|
|
522
|
+
// Compilation context: `[fullhash]`, with `[hash]` as its legacy spelling.
|
|
546
523
|
if (data.hash && (presentKinds.has("fullhash") || presentKinds.has("hash"))) {
|
|
547
524
|
const hashReplacer = hashLength(
|
|
548
525
|
replacer(data.hash),
|
|
@@ -574,14 +551,8 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
574
551
|
}
|
|
575
552
|
}
|
|
576
553
|
|
|
577
|
-
// Chunk
|
|
578
|
-
//
|
|
579
|
-
// Placeholders
|
|
580
|
-
//
|
|
581
|
-
// [id] - chunk.id (0.js)
|
|
582
|
-
// [name] - chunk.name (app.js)
|
|
583
|
-
// [chunkhash] - chunk.hash (7823t4t4.js)
|
|
584
|
-
// [contenthash] - chunk.contentHash[type] (3256u3zg.js)
|
|
554
|
+
// Chunk context: `[id]`, `[name]`, `[chunkhash]`, and `[contenthash]` for the
|
|
555
|
+
// chunk's content hash of the requested type.
|
|
585
556
|
if (data.chunk) {
|
|
586
557
|
const chunk = data.chunk;
|
|
587
558
|
|
|
@@ -638,17 +609,8 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
638
609
|
}
|
|
639
610
|
}
|
|
640
611
|
|
|
641
|
-
// Module
|
|
642
|
-
//
|
|
643
|
-
// Placeholders
|
|
644
|
-
//
|
|
645
|
-
// [id] - module.id (2.png)
|
|
646
|
-
// [hash] - module.hash (6237543873.png)
|
|
647
|
-
//
|
|
648
|
-
// Legacy Placeholders
|
|
649
|
-
//
|
|
650
|
-
// [moduleid] - module.id (2.png)
|
|
651
|
-
// [modulehash] - module.hash (6237543873.png)
|
|
612
|
+
// Module context: `[id]` and `[hash]`, with `[moduleid]` and `[modulehash]` as
|
|
613
|
+
// their legacy spellings.
|
|
652
614
|
if (data.module) {
|
|
653
615
|
const module = data.module;
|
|
654
616
|
const needId = presentKinds.has("id");
|
|
@@ -739,13 +701,8 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
739
701
|
}
|
|
740
702
|
}
|
|
741
703
|
|
|
742
|
-
//
|
|
743
|
-
//
|
|
744
|
-
// Placeholders
|
|
745
|
-
//
|
|
746
|
-
// [url] - data.url
|
|
747
|
-
// [uniqueName] - data.uniqueName (output.uniqueName)
|
|
748
|
-
// [uniquename] - alias of [uniqueName]
|
|
704
|
+
// Everything else: `[url]`, and `[uniqueName]` from `output.uniqueName`, which
|
|
705
|
+
// `[uniquename]` aliases.
|
|
749
706
|
if (data.url && presentKinds.has("url")) {
|
|
750
707
|
replacements.set("url", replacer(data.url));
|
|
751
708
|
}
|
|
@@ -114,7 +114,13 @@ class AssetBytesGenerator extends Generator {
|
|
|
114
114
|
generateError(error, module, generateContext) {
|
|
115
115
|
switch (generateContext.type) {
|
|
116
116
|
case JAVASCRIPT_TYPE: {
|
|
117
|
-
return new RawSource(
|
|
117
|
+
return new RawSource(
|
|
118
|
+
Generator.throwBuildErrorCode(
|
|
119
|
+
error,
|
|
120
|
+
undefined,
|
|
121
|
+
generateContext.runtimeTemplate.requestShortener
|
|
122
|
+
)
|
|
123
|
+
);
|
|
118
124
|
}
|
|
119
125
|
default:
|
|
120
126
|
return null;
|
|
@@ -791,10 +791,21 @@ class AssetGenerator extends Generator {
|
|
|
791
791
|
generateError(error, module, generateContext) {
|
|
792
792
|
switch (generateContext.type) {
|
|
793
793
|
case "asset": {
|
|
794
|
-
return new RawSource(
|
|
794
|
+
return new RawSource(
|
|
795
|
+
Generator.buildErrorMessage(
|
|
796
|
+
error,
|
|
797
|
+
generateContext.runtimeTemplate.requestShortener
|
|
798
|
+
)
|
|
799
|
+
);
|
|
795
800
|
}
|
|
796
801
|
case JAVASCRIPT_TYPE: {
|
|
797
|
-
return new RawSource(
|
|
802
|
+
return new RawSource(
|
|
803
|
+
Generator.throwBuildErrorCode(
|
|
804
|
+
error,
|
|
805
|
+
undefined,
|
|
806
|
+
generateContext.runtimeTemplate.requestShortener
|
|
807
|
+
)
|
|
808
|
+
);
|
|
798
809
|
}
|
|
799
810
|
default:
|
|
800
811
|
return null;
|
|
@@ -836,13 +847,14 @@ class AssetGenerator extends Generator {
|
|
|
836
847
|
/** @type {AssetModuleBuildInfo} */ (module.buildInfo).dataUrl
|
|
837
848
|
) && this.emit !== false;
|
|
838
849
|
|
|
839
|
-
//
|
|
840
|
-
// it every JS consumer needs the wrapper, so
|
|
841
|
-
// probe entirely and
|
|
842
|
-
// `URLDependency`
|
|
843
|
-
// call site still requires the module — except where the
|
|
844
|
-
// itself (`.p + <file>`), which needs no wrapper to
|
|
845
|
-
// Build-time execution
|
|
850
|
+
// WHY: only analyzable ESM output can drop a bare `new URL()` to an asset
|
|
851
|
+
// url; without it every JS consumer needs the wrapper, so the per-connection
|
|
852
|
+
// dependency probe is skipped entirely and the cheap path stands. This must
|
|
853
|
+
// match the condition `URLDependency` emits the literal under, or the wrapper
|
|
854
|
+
// is dropped while the call site still requires the module — except where the
|
|
855
|
+
// fallback spells the name itself (`.p + <file>`), which needs no wrapper to
|
|
856
|
+
// read it out of. Build-time execution emulates the wrapper instead
|
|
857
|
+
// (`AssetModulesPlugin`).
|
|
846
858
|
const isModule = Boolean(
|
|
847
859
|
this._compilation &&
|
|
848
860
|
this._compilation.runtimeTemplate.supportsAnalyzable(
|
|
@@ -874,9 +886,8 @@ class AssetGenerator extends Generator {
|
|
|
874
886
|
hasUrl = true;
|
|
875
887
|
} else if (
|
|
876
888
|
// Only a bare `new URL()` becomes the analyzable literal; a relative ref
|
|
877
|
-
// keeps the runtime form and
|
|
878
|
-
//
|
|
879
|
-
// the href from the asset filename when there is no wrapper.
|
|
889
|
+
// keeps the runtime form and its wrapper. A prefetch or preload ref needs
|
|
890
|
+
// none: its `<link>` resolves the href at chunk startup.
|
|
880
891
|
isModule &&
|
|
881
892
|
dependency instanceof URLDependency &&
|
|
882
893
|
!dependency.relative
|
|
@@ -961,10 +972,8 @@ class AssetGenerator extends Generator {
|
|
|
961
972
|
return 0;
|
|
962
973
|
}
|
|
963
974
|
|
|
964
|
-
//
|
|
965
|
-
//
|
|
966
|
-
// 4/3 = base64 encoding
|
|
967
|
-
// 34 = ~ data url header + footer + rounding
|
|
975
|
+
// Rough data-url size: 4/3 for the base64 encoding, plus about 34 bytes
|
|
976
|
+
// of header, footer and rounding.
|
|
968
977
|
return originalSource.size() * 1.34 + 36;
|
|
969
978
|
}
|
|
970
979
|
// it's only estimated so this number is probably fine
|
|
@@ -158,7 +158,13 @@ class AssetSourceGenerator extends Generator {
|
|
|
158
158
|
generateError(error, module, generateContext) {
|
|
159
159
|
switch (generateContext.type) {
|
|
160
160
|
case JAVASCRIPT_TYPE: {
|
|
161
|
-
return new RawSource(
|
|
161
|
+
return new RawSource(
|
|
162
|
+
Generator.throwBuildErrorCode(
|
|
163
|
+
error,
|
|
164
|
+
undefined,
|
|
165
|
+
generateContext.runtimeTemplate.requestShortener
|
|
166
|
+
)
|
|
167
|
+
);
|
|
162
168
|
}
|
|
163
169
|
default:
|
|
164
170
|
return null;
|