webpack 5.106.2 → 5.107.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/README.md +2 -2
- package/lib/APIPlugin.js +1 -1
- package/lib/BannerPlugin.js +3 -4
- package/lib/Cache.js +3 -6
- package/lib/Chunk.js +21 -25
- package/lib/ChunkGroup.js +57 -15
- package/lib/CompatibilityPlugin.js +8 -7
- package/lib/Compilation.js +67 -37
- package/lib/Compiler.js +4 -13
- package/lib/ContextModule.js +2 -2
- package/lib/DefinePlugin.js +2 -2
- package/lib/Dependency.js +22 -1
- package/lib/DependencyTemplate.js +2 -1
- package/lib/EnvironmentPlugin.js +1 -1
- package/lib/EvalSourceMapDevToolPlugin.js +8 -10
- package/lib/ExportsInfo.js +30 -34
- package/lib/ExternalModule.js +91 -26
- package/lib/ExternalModuleFactoryPlugin.js +7 -1
- package/lib/FileSystemInfo.js +187 -72
- package/lib/Generator.js +3 -3
- package/lib/HotModuleReplacementPlugin.js +26 -8
- package/lib/IgnorePlugin.js +2 -1
- package/lib/Module.js +20 -19
- package/lib/ModuleFactory.js +1 -1
- package/lib/ModuleNotFoundError.js +3 -84
- package/lib/ModuleSourceTypeConstants.js +51 -19
- package/lib/ModuleTypeConstants.js +12 -3
- package/lib/MultiCompiler.js +2 -2
- package/lib/NodeStuffPlugin.js +1 -1
- package/lib/NormalModule.js +119 -77
- package/lib/NormalModuleFactory.js +47 -27
- package/lib/Parser.js +1 -1
- package/lib/ProgressPlugin.js +129 -56
- package/lib/RuntimeGlobals.js +5 -5
- package/lib/RuntimeModule.js +9 -7
- package/lib/RuntimePlugin.js +12 -1
- package/lib/SourceMapDevToolPlugin.js +250 -49
- package/lib/Template.js +1 -1
- package/lib/TemplatedPathPlugin.js +22 -4
- package/lib/WarnCaseSensitiveModulesPlugin.js +70 -2
- package/lib/WarnDeprecatedOptionPlugin.js +1 -1
- package/lib/WarnNoModeSetPlugin.js +16 -1
- package/lib/Watching.js +2 -3
- package/lib/WebpackError.js +3 -77
- package/lib/WebpackIsIncludedPlugin.js +1 -1
- package/lib/WebpackOptionsApply.js +13 -1
- package/lib/asset/AssetBytesGenerator.js +12 -8
- package/lib/asset/AssetGenerator.js +36 -22
- package/lib/asset/AssetModulesPlugin.js +6 -8
- package/lib/asset/AssetSourceGenerator.js +12 -8
- package/lib/buildChunkGraph.js +4 -6
- package/lib/cache/PackFileCacheStrategy.js +4 -4
- package/lib/cli.js +3 -1
- package/lib/config/defaults.js +197 -10
- package/lib/config/normalization.js +3 -1
- package/lib/css/CssGenerator.js +320 -105
- package/lib/css/CssInjectStyleRuntimeModule.js +44 -42
- package/lib/css/CssLoadingRuntimeModule.js +22 -4
- package/lib/{CssModule.js → css/CssModule.js} +15 -15
- package/lib/css/CssModulesPlugin.js +168 -88
- package/lib/css/CssParser.js +566 -269
- package/lib/css/walkCssTokens.js +148 -2
- package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +1 -1
- package/lib/dependencies/CommonJsDependencyHelpers.js +63 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +54 -10
- package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -1
- package/lib/dependencies/CommonJsFullRequireDependency.js +32 -9
- package/lib/dependencies/CommonJsImportsParserPlugin.js +112 -4
- package/lib/dependencies/CommonJsRequireDependency.js +67 -4
- package/lib/dependencies/ContextDependency.js +1 -1
- package/lib/dependencies/ContextDependencyHelpers.js +1 -1
- package/lib/dependencies/CreateRequireParserPlugin.js +1 -1
- package/lib/dependencies/CriticalDependencyWarning.js +1 -1
- package/lib/dependencies/CssIcssExportDependency.js +332 -67
- package/lib/dependencies/CssIcssImportDependency.js +49 -7
- package/lib/dependencies/CssIcssSymbolDependency.js +11 -3
- package/lib/dependencies/CssImportDependency.js +8 -0
- package/lib/dependencies/CssUrlDependency.js +28 -2
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +22 -2
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -7
- package/lib/dependencies/HarmonyExportExpressionDependency.js +22 -14
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +110 -3
- package/lib/dependencies/HarmonyImportDependency.js +10 -2
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +22 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +1 -1
- package/lib/{HarmonyLinkingError.js → dependencies/HarmonyLinkingError.js} +5 -3
- package/lib/dependencies/HtmlInlineScriptDependency.js +133 -0
- package/lib/dependencies/HtmlInlineStyleDependency.js +101 -0
- package/lib/dependencies/HtmlScriptSrcDependency.js +557 -0
- package/lib/dependencies/HtmlSourceDependency.js +128 -0
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/ImportParserPlugin.js +2 -2
- package/lib/dependencies/ImportPhase.js +1 -1
- package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +1 -1
- package/lib/{RequireJsStuffPlugin.js → dependencies/RequireJsStuffPlugin.js} +7 -7
- package/lib/dependencies/SystemPlugin.js +1 -1
- package/lib/dependencies/WebAssemblyImportDependency.js +1 -1
- package/lib/dependencies/WorkerPlugin.js +2 -2
- package/lib/{DelegatedModule.js → dll/DelegatedModule.js} +31 -31
- package/lib/{DelegatedModuleFactoryPlugin.js → dll/DelegatedModuleFactoryPlugin.js} +4 -4
- package/lib/{DelegatedPlugin.js → dll/DelegatedPlugin.js} +2 -2
- package/lib/{DllEntryPlugin.js → dll/DllEntryPlugin.js} +4 -4
- package/lib/{DllModule.js → dll/DllModule.js} +24 -24
- package/lib/{DllModuleFactory.js → dll/DllModuleFactory.js} +4 -4
- package/lib/{DllPlugin.js → dll/DllPlugin.js} +6 -5
- package/lib/{DllReferencePlugin.js → dll/DllReferencePlugin.js} +14 -14
- package/lib/{LibManifestPlugin.js → dll/LibManifestPlugin.js} +9 -9
- package/lib/{AsyncDependencyToInitialChunkError.js → errors/AsyncDependencyToInitialChunkError.js} +2 -2
- package/lib/errors/BuildCycleError.js +1 -1
- package/lib/{ChunkRenderError.js → errors/ChunkRenderError.js} +1 -1
- package/lib/{CodeGenerationError.js → errors/CodeGenerationError.js} +1 -1
- package/lib/{CommentCompilationWarning.js → errors/CommentCompilationWarning.js} +3 -3
- package/lib/{ConcurrentCompilationError.js → errors/ConcurrentCompilationError.js} +4 -2
- package/lib/{EnvironmentNotSupportAsyncWarning.js → errors/EnvironmentNotSupportAsyncWarning.js} +4 -4
- package/lib/{HookWebpackError.js → errors/HookWebpackError.js} +5 -5
- package/lib/{IgnoreErrorModuleFactory.js → errors/IgnoreErrorModuleFactory.js} +4 -4
- package/lib/{InvalidDependenciesModuleWarning.js → errors/InvalidDependenciesModuleWarning.js} +3 -3
- package/lib/errors/JSONParseError.js +114 -0
- package/lib/{ModuleBuildError.js → errors/ModuleBuildError.js} +5 -5
- package/lib/{ModuleDependencyError.js → errors/ModuleDependencyError.js} +2 -2
- package/lib/{ModuleDependencyWarning.js → errors/ModuleDependencyWarning.js} +4 -4
- package/lib/{ModuleError.js → errors/ModuleError.js} +5 -5
- package/lib/{ModuleHashingError.js → errors/ModuleHashingError.js} +1 -1
- package/lib/errors/ModuleNotFoundError.js +91 -0
- package/lib/{ModuleParseError.js → errors/ModuleParseError.js} +8 -6
- package/lib/{ModuleRestoreError.js → errors/ModuleRestoreError.js} +1 -1
- package/lib/{ModuleStoreError.js → errors/ModuleStoreError.js} +1 -1
- package/lib/{ModuleWarning.js → errors/ModuleWarning.js} +5 -5
- package/lib/{NodeStuffInWebError.js → errors/NodeStuffInWebError.js} +4 -4
- package/lib/errors/NonErrorEmittedError.js +28 -0
- package/lib/{UnhandledSchemeError.js → errors/UnhandledSchemeError.js} +2 -2
- package/lib/{UnsupportedFeatureWarning.js → errors/UnsupportedFeatureWarning.js} +3 -3
- package/lib/errors/WebpackError.js +84 -0
- package/lib/html/HtmlGenerator.js +379 -0
- package/lib/html/HtmlModulesPlugin.js +429 -0
- package/lib/html/HtmlParser.js +1489 -0
- package/lib/html/walkHtmlTokens.js +3249 -0
- package/lib/ids/IdHelpers.js +2 -1
- package/lib/index.js +36 -15
- package/lib/javascript/JavascriptModulesPlugin.js +91 -10
- package/lib/javascript/JavascriptParser.js +197 -16
- package/lib/javascript/JavascriptParserHelpers.js +1 -1
- package/lib/json/JsonParser.js +7 -16
- package/lib/library/AbstractLibraryPlugin.js +1 -1
- package/lib/library/EnableLibraryPlugin.js +1 -1
- package/lib/{FalseIIFEUmdWarning.js → library/FalseIIFEUmdWarning.js} +1 -1
- package/lib/library/ModuleLibraryPlugin.js +74 -0
- package/lib/node/NodeEnvironmentPlugin.js +4 -2
- package/lib/node/nodeConsole.js +113 -64
- package/lib/optimize/ConcatenatedModule.js +51 -6
- package/lib/optimize/InnerGraph.js +1 -1
- package/lib/optimize/InnerGraphPlugin.js +11 -1
- package/lib/optimize/MinMaxSizeWarning.js +4 -4
- package/lib/optimize/ModuleConcatenationPlugin.js +15 -7
- package/lib/optimize/RealContentHashPlugin.js +89 -26
- package/lib/optimize/SideEffectsFlagPlugin.js +112 -5
- package/lib/optimize/SplitChunksPlugin.js +5 -5
- package/lib/performance/AssetsOverSizeLimitWarning.js +2 -2
- package/lib/performance/EntrypointsOverSizeLimitWarning.js +2 -2
- package/lib/performance/NoAsyncChunksWarning.js +5 -3
- package/lib/performance/SizeLimitsPlugin.js +1 -1
- package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +4 -1
- package/lib/rules/UseEffectRulePlugin.js +4 -3
- package/lib/runtime/AutoPublicPathRuntimeModule.js +3 -3
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +5 -5
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +119 -13
- package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +35 -0
- package/lib/schemes/DataUriPlugin.js +13 -1
- package/lib/schemes/VirtualUrlPlugin.js +1 -1
- package/lib/serialization/SerializerMiddleware.js +2 -2
- package/lib/sharing/ConsumeSharedPlugin.js +4 -10
- package/lib/sharing/ConsumeSharedRuntimeModule.js +8 -4
- package/lib/sharing/ProvideSharedModule.js +1 -1
- package/lib/sharing/ProvideSharedPlugin.js +5 -5
- package/lib/sharing/resolveMatchedConfigs.js +1 -1
- package/lib/stats/DefaultStatsFactoryPlugin.js +2 -2
- package/lib/stats/DefaultStatsPresetPlugin.js +1 -1
- package/lib/stats/DefaultStatsPrinterPlugin.js +1 -1
- package/lib/stats/StatsFactory.js +1 -1
- package/lib/typescript/TypeScriptPlugin.js +210 -0
- package/lib/url/URLParserPlugin.js +2 -2
- package/lib/util/AsyncQueue.js +2 -2
- package/lib/util/Hash.js +2 -2
- package/lib/util/LocConverter.js +53 -0
- package/lib/util/SortableSet.js +1 -1
- package/lib/util/cleverMerge.js +2 -2
- package/lib/util/comparators.js +3 -3
- package/lib/util/concatenate.js +3 -3
- package/lib/util/conventions.js +42 -1
- package/lib/util/createMappings.js +118 -0
- package/lib/{formatLocation.js → util/formatLocation.js} +2 -2
- package/lib/{SizeFormatHelpers.js → util/formatSize.js} +3 -1
- package/lib/util/fs.js +8 -8
- package/lib/util/hash/md4.js +1 -1
- package/lib/util/hash/xxhash64.js +1 -1
- package/lib/util/identifier.js +48 -0
- package/lib/util/internalSerializables.js +35 -19
- package/lib/util/magicComment.js +10 -7
- package/lib/util/parseJson.js +2 -73
- package/lib/util/source.js +21 -0
- package/lib/util/topologicalSort.js +69 -0
- package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +3 -4
- package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
- package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +5 -3
- package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +1 -1
- package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +5 -3
- package/lib/webpack.js +3 -1
- package/package.json +24 -22
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +129 -12
- package/schemas/plugins/{DllPlugin.check.d.ts → HtmlGeneratorOptions.check.d.ts} +1 -1
- package/schemas/plugins/HtmlGeneratorOptions.check.js +6 -0
- package/schemas/plugins/HtmlGeneratorOptions.json +3 -0
- package/schemas/plugins/ProgressPlugin.check.js +1 -1
- package/schemas/plugins/ProgressPlugin.json +22 -0
- package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerReferencePlugin.json +1 -0
- package/schemas/plugins/container/ExternalsType.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.json +1 -0
- package/schemas/plugins/{DllReferencePlugin.check.d.ts → css/CssAutoOrModuleParserOptions.check.d.ts} +1 -1
- package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +6 -0
- package/schemas/plugins/css/CssAutoOrModuleParserOptions.json +3 -0
- package/schemas/plugins/dll/DllPlugin.check.d.ts +7 -0
- package/schemas/plugins/dll/DllReferencePlugin.check.d.ts +7 -0
- package/types.d.ts +1153 -233
- package/lib/CaseSensitiveModulesWarning.js +0 -80
- package/lib/GraphHelpers.js +0 -49
- package/lib/NoModeWarning.js +0 -23
- package/lib/css/CssMergeStyleSheetsRuntimeModule.js +0 -57
- /package/lib/{AbstractMethodError.js → errors/AbstractMethodError.js} +0 -0
- /package/schemas/plugins/{DllPlugin.check.js → dll/DllPlugin.check.js} +0 -0
- /package/schemas/plugins/{DllPlugin.json → dll/DllPlugin.json} +0 -0
- /package/schemas/plugins/{DllReferencePlugin.check.js → dll/DllReferencePlugin.check.js} +0 -0
- /package/schemas/plugins/{DllReferencePlugin.json → dll/DllReferencePlugin.json} +0 -0
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
const { SyncBailHook } = require("tapable");
|
|
9
9
|
const { CachedSource, CompatSource, RawSource } = require("webpack-sources");
|
|
10
10
|
const Compilation = require("../Compilation");
|
|
11
|
-
const WebpackError = require("../WebpackError");
|
|
11
|
+
const WebpackError = require("../errors/WebpackError");
|
|
12
12
|
const { compareSelect, compareStrings } = require("../util/comparators");
|
|
13
13
|
const createHash = require("../util/createHash");
|
|
14
14
|
|
|
@@ -46,24 +46,77 @@ const addToList = (itemOrItems, list) => {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* Compares two non-empty buffer chunk arrays for byte-equality without
|
|
50
|
+
* allocating a concatenated buffer.
|
|
51
|
+
* @param {Buffer[]} a first chunk array
|
|
52
|
+
* @param {Buffer[]} b second chunk array
|
|
53
|
+
* @returns {boolean} true if the concatenations are byte-equal
|
|
54
|
+
*/
|
|
55
|
+
const bufferArraysEqual = (a, b) => {
|
|
56
|
+
let aIdx = 0;
|
|
57
|
+
let aOff = 0;
|
|
58
|
+
let bIdx = 0;
|
|
59
|
+
let bOff = 0;
|
|
60
|
+
while (aIdx < a.length && bIdx < b.length) {
|
|
61
|
+
const aBuf = a[aIdx];
|
|
62
|
+
const bBuf = b[bIdx];
|
|
63
|
+
const len = Math.min(aBuf.length - aOff, bBuf.length - bOff);
|
|
64
|
+
if (aBuf.compare(bBuf, bOff, bOff + len, aOff, aOff + len) !== 0) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
aOff += len;
|
|
68
|
+
bOff += len;
|
|
69
|
+
if (aOff === aBuf.length) {
|
|
70
|
+
aIdx++;
|
|
71
|
+
aOff = 0;
|
|
72
|
+
}
|
|
73
|
+
if (bOff === bBuf.length) {
|
|
74
|
+
bIdx++;
|
|
75
|
+
bOff = 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return aIdx === a.length && bIdx === b.length;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Map sources to their buffer chunks and deduplicate by total byte content,
|
|
83
|
+
* grouping by total length first to avoid full comparisons.
|
|
50
84
|
* @template T
|
|
51
85
|
* @param {T[]} input list
|
|
52
|
-
* @param {(item: T) =>
|
|
53
|
-
* @returns {Buffer[]}
|
|
86
|
+
* @param {(item: T) => Source} fn map function returning a Source
|
|
87
|
+
* @returns {Buffer[][]} unique chunk arrays
|
|
54
88
|
*/
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
/** @type {Buffer[]} */
|
|
89
|
+
const mapAndDeduplicateSourceBuffers = (input, fn) => {
|
|
90
|
+
/** @type {Map<number, Buffer[][]>} */
|
|
91
|
+
const bySize = new Map();
|
|
92
|
+
/** @type {Buffer[][]} */
|
|
60
93
|
const result = [];
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
94
|
+
for (const value of input) {
|
|
95
|
+
const source = fn(value);
|
|
96
|
+
// TODO webpack 6: drop the `buffers` check, require webpack-sources >= 3.4
|
|
97
|
+
// and call `source.buffers()` unconditionally.
|
|
98
|
+
const chunks =
|
|
99
|
+
// TODO remove in webpack 6, this is protection against authors who directly use `webpack-sources` outdated version
|
|
100
|
+
typeof source.buffers === "function"
|
|
101
|
+
? source.buffers()
|
|
102
|
+
: [source.buffer()];
|
|
103
|
+
let total = 0;
|
|
104
|
+
for (const c of chunks) total += c.length;
|
|
105
|
+
const sameSize = bySize.get(total);
|
|
106
|
+
if (sameSize) {
|
|
107
|
+
let duplicate = false;
|
|
108
|
+
for (const other of sameSize) {
|
|
109
|
+
if (bufferArraysEqual(chunks, other)) {
|
|
110
|
+
duplicate = true;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (duplicate) continue;
|
|
115
|
+
sameSize.push(chunks);
|
|
116
|
+
} else {
|
|
117
|
+
bySize.set(total, [chunks]);
|
|
65
118
|
}
|
|
66
|
-
result.push(
|
|
119
|
+
result.push(chunks);
|
|
67
120
|
}
|
|
68
121
|
return result;
|
|
69
122
|
};
|
|
@@ -437,24 +490,34 @@ ${referencingAssets
|
|
|
437
490
|
: computeNewContent(asset)
|
|
438
491
|
)
|
|
439
492
|
);
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
493
|
+
const uniqueChunkArrays = mapAndDeduplicateSourceBuffers(
|
|
494
|
+
assets,
|
|
495
|
+
(asset) => {
|
|
496
|
+
if (/** @type {Hashes} */ (asset.ownHashes).has(oldHash)) {
|
|
497
|
+
return asset.newSourceWithoutOwn || asset.source;
|
|
498
|
+
}
|
|
499
|
+
return asset.newSource || asset.source;
|
|
445
500
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
501
|
+
);
|
|
502
|
+
/** @type {string | undefined} */
|
|
503
|
+
let newHash;
|
|
504
|
+
// Only materialize the public `Buffer[]` (one entry per unique
|
|
505
|
+
// asset) when something is tapped; otherwise the hot path feeds
|
|
506
|
+
// chunks into the hash directly, avoiding per-asset Buffer.concat.
|
|
507
|
+
if (hooks.updateHash.isUsed()) {
|
|
508
|
+
const assetsContent = uniqueChunkArrays.map((chunks) =>
|
|
509
|
+
chunks.length === 1 ? chunks[0] : Buffer.concat(chunks)
|
|
510
|
+
);
|
|
511
|
+
newHash =
|
|
512
|
+
hooks.updateHash.call(assetsContent, oldHash) || undefined;
|
|
513
|
+
}
|
|
451
514
|
if (!newHash) {
|
|
452
515
|
const hash = createHash(this._hashFunction);
|
|
453
516
|
if (compilation.outputOptions.hashSalt) {
|
|
454
517
|
hash.update(compilation.outputOptions.hashSalt);
|
|
455
518
|
}
|
|
456
|
-
for (const
|
|
457
|
-
hash.update(
|
|
519
|
+
for (const chunks of uniqueChunkArrays) {
|
|
520
|
+
for (const c of chunks) hash.update(c);
|
|
458
521
|
}
|
|
459
522
|
const digest = hash.digest(this._hashDigest);
|
|
460
523
|
newHash = digest.slice(0, oldHash.length);
|
|
@@ -14,18 +14,19 @@ const {
|
|
|
14
14
|
const { STAGE_DEFAULT } = require("../OptimizationStages");
|
|
15
15
|
const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
|
|
16
16
|
const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
|
|
17
|
-
const formatLocation = require("../formatLocation");
|
|
17
|
+
const formatLocation = require("../util/formatLocation");
|
|
18
|
+
const { CompilerHintNotationRegExp } = require("../util/magicComment");
|
|
18
19
|
|
|
19
20
|
/** @typedef {import("estree").MaybeNamedClassDeclaration} MaybeNamedClassDeclaration */
|
|
20
21
|
/** @typedef {import("estree").MaybeNamedFunctionDeclaration} MaybeNamedFunctionDeclaration */
|
|
21
22
|
/** @typedef {import("estree").ModuleDeclaration} ModuleDeclaration */
|
|
22
23
|
/** @typedef {import("estree").Statement} Statement */
|
|
24
|
+
/** @typedef {import("estree").CallExpression} CallExpression */
|
|
23
25
|
/** @typedef {import("../Compiler")} Compiler */
|
|
24
26
|
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
|
|
25
27
|
/** @typedef {import("../Module")} Module */
|
|
26
28
|
/** @typedef {import("../Module").BuildMeta} BuildMeta */
|
|
27
29
|
/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
|
|
28
|
-
/** @typedef {import("../NormalModuleFactory").ModuleSettings} ModuleSettings */
|
|
29
30
|
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
|
30
31
|
/** @typedef {import("../javascript/JavascriptParser").Range} Range */
|
|
31
32
|
|
|
@@ -63,6 +64,24 @@ const globToRegexp = (glob, cache) => {
|
|
|
63
64
|
return regexp;
|
|
64
65
|
};
|
|
65
66
|
|
|
67
|
+
/**
|
|
68
|
+
* @param {JavascriptParser} parser parser
|
|
69
|
+
* @param {number} start start position
|
|
70
|
+
* @param {number} end end position
|
|
71
|
+
* @returns {boolean} if annotation is found in the range
|
|
72
|
+
*/
|
|
73
|
+
const hasNoSideEffectsNotation = (parser, start, end) => {
|
|
74
|
+
// Fast path
|
|
75
|
+
if (end - start < 18) return false;
|
|
76
|
+
|
|
77
|
+
const comments = parser.getComments([start, end]);
|
|
78
|
+
return comments.some(
|
|
79
|
+
(c) =>
|
|
80
|
+
c.type === "Block" &&
|
|
81
|
+
CompilerHintNotationRegExp.NoSideEffects.test(c.value)
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
66
85
|
const PLUGIN_NAME = "SideEffectsFlagPlugin";
|
|
67
86
|
|
|
68
87
|
class SideEffectsFlagPlugin {
|
|
@@ -114,7 +133,7 @@ class SideEffectsFlagPlugin {
|
|
|
114
133
|
return module;
|
|
115
134
|
});
|
|
116
135
|
normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (module, data) => {
|
|
117
|
-
const settings =
|
|
136
|
+
const settings = data.settings;
|
|
118
137
|
if (typeof settings.sideEffects === "boolean") {
|
|
119
138
|
if (module.factoryMeta === undefined) {
|
|
120
139
|
module.factoryMeta = {};
|
|
@@ -129,7 +148,7 @@ class SideEffectsFlagPlugin {
|
|
|
129
148
|
* @param {JavascriptParser} parser the parser
|
|
130
149
|
* @returns {void}
|
|
131
150
|
*/
|
|
132
|
-
const
|
|
151
|
+
const applySideEffectsStmtHandler = (parser) => {
|
|
133
152
|
/** @type {undefined | Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} */
|
|
134
153
|
let sideEffectsStatement;
|
|
135
154
|
parser.hooks.program.tap(PLUGIN_NAME, () => {
|
|
@@ -260,6 +279,91 @@ class SideEffectsFlagPlugin {
|
|
|
260
279
|
}
|
|
261
280
|
});
|
|
262
281
|
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* @param {JavascriptParser} parser the parser
|
|
285
|
+
* @returns {void}
|
|
286
|
+
*/
|
|
287
|
+
const applyNoSideEffectsNotationHandler = (parser) => {
|
|
288
|
+
/** @type {Set<string>} */
|
|
289
|
+
let noSideEffectsFnNames;
|
|
290
|
+
|
|
291
|
+
parser.hooks.program.tap(PLUGIN_NAME, () => {
|
|
292
|
+
noSideEffectsFnNames = new Set();
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// Detect on function declarations
|
|
296
|
+
// Covers:
|
|
297
|
+
// 1. function foo
|
|
298
|
+
// 2. export function foo
|
|
299
|
+
// 3. export default function foo
|
|
300
|
+
parser.hooks.preStatement.tap(PLUGIN_NAME, (statement) => {
|
|
301
|
+
if (parser.scope.topLevelScope !== true) return;
|
|
302
|
+
if (statement.type !== "FunctionDeclaration" || !statement.id) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const commentsStart = parser.prevStatement
|
|
306
|
+
? /** @type {Range} */ (parser.prevStatement.range)[1]
|
|
307
|
+
: 0;
|
|
308
|
+
if (
|
|
309
|
+
hasNoSideEffectsNotation(
|
|
310
|
+
parser,
|
|
311
|
+
commentsStart,
|
|
312
|
+
/** @type {Range} */ (statement.range)[0]
|
|
313
|
+
)
|
|
314
|
+
) {
|
|
315
|
+
noSideEffectsFnNames.add(statement.id.name);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// Detect on variable declarations with function init
|
|
320
|
+
parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl, statement) => {
|
|
321
|
+
if (parser.scope.topLevelScope !== true) return;
|
|
322
|
+
if (!decl.init || decl.id.type !== "Identifier") return;
|
|
323
|
+
if (!decl.init.type.endsWith("FunctionExpression")) return;
|
|
324
|
+
|
|
325
|
+
let hasAnnotation = false;
|
|
326
|
+
// Before the VariableDeclaration (only for const)
|
|
327
|
+
if (statement.kind === "const") {
|
|
328
|
+
const commentsStart = parser.prevStatement
|
|
329
|
+
? /** @type {Range} */ (parser.prevStatement.range)[1]
|
|
330
|
+
: 0;
|
|
331
|
+
hasAnnotation = hasNoSideEffectsNotation(
|
|
332
|
+
parser,
|
|
333
|
+
commentsStart,
|
|
334
|
+
/** @type {Range} */ (statement.range)[0]
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (!hasAnnotation) {
|
|
339
|
+
hasAnnotation = hasNoSideEffectsNotation(
|
|
340
|
+
parser,
|
|
341
|
+
/** @type {Range} */ (decl.id.range)[1],
|
|
342
|
+
/** @type {Range} */ (decl.init.range)[0]
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
if (hasAnnotation) {
|
|
346
|
+
noSideEffectsFnNames.add(decl.id.name);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
// Mark calls to annotated functions as pure
|
|
351
|
+
parser.hooks.isPure
|
|
352
|
+
.for("CallExpression")
|
|
353
|
+
.tap(PLUGIN_NAME, (expression, commentsStartPos) => {
|
|
354
|
+
const expr = /** @type {CallExpression} */ (expression);
|
|
355
|
+
if (expr.callee.type !== "Identifier") return;
|
|
356
|
+
if (!noSideEffectsFnNames.has(expr.callee.name)) return;
|
|
357
|
+
commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
|
|
358
|
+
for (const arg of expr.arguments) {
|
|
359
|
+
if (arg.type === "SpreadElement") return;
|
|
360
|
+
if (!parser.isPure(arg, commentsStartPos)) return;
|
|
361
|
+
commentsStartPos = /** @type {Range} */ (arg.range)[1];
|
|
362
|
+
}
|
|
363
|
+
return true;
|
|
364
|
+
});
|
|
365
|
+
};
|
|
366
|
+
|
|
263
367
|
for (const key of [
|
|
264
368
|
JAVASCRIPT_MODULE_TYPE_AUTO,
|
|
265
369
|
JAVASCRIPT_MODULE_TYPE_ESM,
|
|
@@ -267,7 +371,10 @@ class SideEffectsFlagPlugin {
|
|
|
267
371
|
]) {
|
|
268
372
|
normalModuleFactory.hooks.parser
|
|
269
373
|
.for(key)
|
|
270
|
-
.tap(PLUGIN_NAME,
|
|
374
|
+
.tap(PLUGIN_NAME, (parser) => {
|
|
375
|
+
applyNoSideEffectsNotationHandler(parser);
|
|
376
|
+
applySideEffectsStmtHandler(parser);
|
|
377
|
+
});
|
|
271
378
|
}
|
|
272
379
|
}
|
|
273
380
|
compilation.hooks.optimizeDependencies.tap(
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const Chunk = require("../Chunk");
|
|
9
9
|
const { STAGE_ADVANCED } = require("../OptimizationStages");
|
|
10
|
-
const WebpackError = require("../WebpackError");
|
|
10
|
+
const WebpackError = require("../errors/WebpackError");
|
|
11
11
|
const { requestToId } = require("../ids/IdHelpers");
|
|
12
12
|
const { isSubset } = require("../util/SetHelpers");
|
|
13
13
|
const SortableSet = require("../util/SortableSet");
|
|
@@ -32,7 +32,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
|
32
32
|
/** @typedef {import("../Module")} Module */
|
|
33
33
|
/** @typedef {import("../Module").SourceType} SourceType */
|
|
34
34
|
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
|
35
|
-
/** @typedef {import("../
|
|
35
|
+
/** @typedef {import("../Chunk").ChunkFilenameTemplate} ChunkFilenameTemplate */
|
|
36
36
|
/** @typedef {import("../util/deterministicGrouping").GroupedItems<Module>} DeterministicGroupingGroupedItemsForModule */
|
|
37
37
|
/** @typedef {import("../util/deterministicGrouping").Options<Module>} DeterministicGroupingOptionsForModule */
|
|
38
38
|
/** @typedef {import("../util/deterministicGrouping").Sizes} Sizes */
|
|
@@ -78,7 +78,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
|
78
78
|
* @property {CountOfChunk=} minChunks
|
|
79
79
|
* @property {CountOfRequest=} maxAsyncRequests
|
|
80
80
|
* @property {CountOfRequest=} maxInitialRequests
|
|
81
|
-
* @property {
|
|
81
|
+
* @property {ChunkFilenameTemplate=} filename
|
|
82
82
|
* @property {string=} idHint
|
|
83
83
|
* @property {string=} automaticNameDelimiter
|
|
84
84
|
* @property {boolean=} reuseExistingChunk
|
|
@@ -101,7 +101,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
|
101
101
|
* @property {CountOfChunk} minChunks
|
|
102
102
|
* @property {CountOfRequest} maxAsyncRequests
|
|
103
103
|
* @property {CountOfRequest} maxInitialRequests
|
|
104
|
-
* @property {
|
|
104
|
+
* @property {ChunkFilenameTemplate=} filename
|
|
105
105
|
* @property {string} idHint
|
|
106
106
|
* @property {string} automaticNameDelimiter
|
|
107
107
|
* @property {boolean} reuseExistingChunk
|
|
@@ -163,7 +163,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
|
163
163
|
* @property {CountOfRequest} maxAsyncRequests
|
|
164
164
|
* @property {CountOfRequest} maxInitialRequests
|
|
165
165
|
* @property {boolean} hidePathInfo
|
|
166
|
-
* @property {
|
|
166
|
+
* @property {ChunkFilenameTemplate=} filename
|
|
167
167
|
* @property {string} automaticNameDelimiter
|
|
168
168
|
* @property {GetCacheGroups} getCacheGroups
|
|
169
169
|
* @property {GetNameFn} getName
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const WebpackError = require("../errors/WebpackError");
|
|
9
|
+
const formatSize = require("../util/formatSize");
|
|
10
10
|
|
|
11
11
|
/** @typedef {import("./SizeLimitsPlugin").AssetDetails} AssetDetails */
|
|
12
12
|
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const WebpackError = require("../errors/WebpackError");
|
|
9
|
+
const formatSize = require("../util/formatSize");
|
|
10
10
|
|
|
11
11
|
/** @typedef {import("./SizeLimitsPlugin").EntrypointDetails} EntrypointDetails */
|
|
12
12
|
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
-
const WebpackError = require("../WebpackError");
|
|
8
|
+
const WebpackError = require("../errors/WebpackError");
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
class NoAsyncChunksWarning extends WebpackError {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(
|
|
13
13
|
"webpack performance recommendations: \n" +
|
|
@@ -18,4 +18,6 @@ module.exports = class NoAsyncChunksWarning extends WebpackError {
|
|
|
18
18
|
/** @type {string} */
|
|
19
19
|
this.name = "NoAsyncChunksWarning";
|
|
20
20
|
}
|
|
21
|
-
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = NoAsyncChunksWarning;
|
|
@@ -16,7 +16,7 @@ const NoAsyncChunksWarning = require("./NoAsyncChunksWarning");
|
|
|
16
16
|
/** @typedef {import("../Compilation").Asset} Asset */
|
|
17
17
|
/** @typedef {import("../Compiler")} Compiler */
|
|
18
18
|
/** @typedef {import("../Entrypoint")} Entrypoint */
|
|
19
|
-
/** @typedef {import("../WebpackError")} WebpackError */
|
|
19
|
+
/** @typedef {import("../errors/WebpackError")} WebpackError */
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Defines the asset details type used by this module.
|
|
@@ -39,10 +39,13 @@ class ChunkPrefetchTriggerRuntimeModule extends RuntimeModule {
|
|
|
39
39
|
`${
|
|
40
40
|
RuntimeGlobals.ensureChunkHandlers
|
|
41
41
|
}.prefetch = ${runtimeTemplate.expressionFunction(
|
|
42
|
+
// Prefetch is best-effort; silence rejections so a failed chunk
|
|
43
|
+
// load (e.g. chunkLoadTimeout) doesn't surface as an unhandled
|
|
44
|
+
// rejection through this dangling Promise.all chain.
|
|
42
45
|
`Promise.all(promises).then(${runtimeTemplate.basicFunction(
|
|
43
46
|
"",
|
|
44
47
|
body
|
|
45
|
-
)})`,
|
|
48
|
+
)}, ${runtimeTemplate.basicFunction("", "")})`,
|
|
46
49
|
"chunkId, promises"
|
|
47
50
|
)};`
|
|
48
51
|
])
|
|
@@ -13,6 +13,7 @@ const util = require("util");
|
|
|
13
13
|
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
|
|
14
14
|
/** @typedef {import("../../declarations/WebpackOptions").RuleSetUse} RuleSetUse */
|
|
15
15
|
/** @typedef {import("../../declarations/WebpackOptions").RuleSetUseItem} RuleSetUseItem */
|
|
16
|
+
/** @typedef {import("../../declarations/WebpackOptions").RuleSetUseFunction} RuleSetUseFunction */
|
|
16
17
|
/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */
|
|
17
18
|
/** @typedef {import("./RuleSetCompiler").Effect} Effect */
|
|
18
19
|
/** @typedef {import("./RuleSetCompiler").EffectData} EffectData */
|
|
@@ -82,7 +83,7 @@ class UseEffectRulePlugin {
|
|
|
82
83
|
* Returns effect.
|
|
83
84
|
* @param {string} path options path
|
|
84
85
|
* @param {string} defaultIdent default ident when none is provided
|
|
85
|
-
* @param {Exclude<NonNullable<RuleSetUseItem>,
|
|
86
|
+
* @param {Exclude<NonNullable<RuleSetUseItem>, RuleSetUseFunction>} item user provided use value
|
|
86
87
|
* @returns {Effect} effect
|
|
87
88
|
*/
|
|
88
89
|
const useToEffectRaw = (path, defaultIdent, item) => {
|
|
@@ -132,7 +133,7 @@ class UseEffectRulePlugin {
|
|
|
132
133
|
useToEffectRaw(
|
|
133
134
|
`${path}[${idx}]`,
|
|
134
135
|
"[[missing ident]]",
|
|
135
|
-
/** @type {Exclude<RuleSetUseItem,
|
|
136
|
+
/** @type {Exclude<RuleSetUseItem, RuleSetUseFunction>} */
|
|
136
137
|
(item)
|
|
137
138
|
)
|
|
138
139
|
);
|
|
@@ -141,7 +142,7 @@ class UseEffectRulePlugin {
|
|
|
141
142
|
useToEffectRaw(
|
|
142
143
|
path,
|
|
143
144
|
"[[missing ident]]",
|
|
144
|
-
/** @type {Exclude<RuleSetUseItem,
|
|
145
|
+
/** @type {Exclude<RuleSetUseItem, RuleSetUseFunction>} */
|
|
145
146
|
(items)
|
|
146
147
|
)
|
|
147
148
|
];
|
|
@@ -26,14 +26,14 @@ class AutoPublicPathRuntimeModule extends RuntimeModule {
|
|
|
26
26
|
const compilation = /** @type {Compilation} */ (this.compilation);
|
|
27
27
|
const { scriptType, importMetaName, path, environment } =
|
|
28
28
|
compilation.outputOptions;
|
|
29
|
+
const chunk = /** @type {Chunk} */ (this.chunk);
|
|
29
30
|
const chunkName = compilation.getPath(
|
|
30
31
|
JavascriptModulesPlugin.getChunkFilenameTemplate(
|
|
31
|
-
|
|
32
|
-
(this.chunk),
|
|
32
|
+
chunk,
|
|
33
33
|
compilation.outputOptions
|
|
34
34
|
),
|
|
35
35
|
{
|
|
36
|
-
chunk
|
|
36
|
+
chunk,
|
|
37
37
|
contentHashType: "javascript"
|
|
38
38
|
}
|
|
39
39
|
);
|
|
@@ -14,14 +14,14 @@ const { first } = require("../util/SetHelpers");
|
|
|
14
14
|
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
|
15
15
|
/** @typedef {import("../Compilation")} Compilation */
|
|
16
16
|
/** @typedef {import("../Compilation").HashWithLengthFunction} HashWithLengthFunction */
|
|
17
|
-
/** @typedef {import("../
|
|
17
|
+
/** @typedef {import("../Chunk").ChunkFilenameTemplate} ChunkFilenameTemplate */
|
|
18
18
|
|
|
19
19
|
class GetChunkFilenameRuntimeModule extends RuntimeModule {
|
|
20
20
|
/**
|
|
21
21
|
* @param {string} contentType the contentType to use the content hash for
|
|
22
22
|
* @param {string} name kind of filename
|
|
23
23
|
* @param {string} global function name to be assigned
|
|
24
|
-
* @param {(chunk: Chunk) =>
|
|
24
|
+
* @param {(chunk: Chunk) => ChunkFilenameTemplate | false} getFilenameForChunk functor to get the filename or function
|
|
25
25
|
* @param {boolean} allChunks when false, only async chunks are included
|
|
26
26
|
*/
|
|
27
27
|
constructor(contentType, name, global, getFilenameForChunk, allChunks) {
|
|
@@ -30,7 +30,7 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
|
|
|
30
30
|
this.contentType = contentType;
|
|
31
31
|
/** @type {string} */
|
|
32
32
|
this.global = global;
|
|
33
|
-
/** @type {(chunk: Chunk) =>
|
|
33
|
+
/** @type {(chunk: Chunk) => ChunkFilenameTemplate | false} */
|
|
34
34
|
this.getFilenameForChunk = getFilenameForChunk;
|
|
35
35
|
/** @type {boolean} */
|
|
36
36
|
this.allChunks = allChunks;
|
|
@@ -49,7 +49,7 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
|
|
|
49
49
|
const chunk = /** @type {Chunk} */ (this.chunk);
|
|
50
50
|
const { runtimeTemplate } = compilation;
|
|
51
51
|
|
|
52
|
-
/** @type {Map<
|
|
52
|
+
/** @type {Map<ChunkFilenameTemplate, Set<Chunk>>} */
|
|
53
53
|
const chunkFilenames = new Map();
|
|
54
54
|
let maxChunks = 0;
|
|
55
55
|
/** @type {string | undefined} */
|
|
@@ -126,7 +126,7 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
|
|
|
126
126
|
|
|
127
127
|
/**
|
|
128
128
|
* @param {Chunk} c the chunk
|
|
129
|
-
* @param {
|
|
129
|
+
* @param {ChunkFilenameTemplate} chunkFilename the filename template for the chunk
|
|
130
130
|
* @returns {void}
|
|
131
131
|
*/
|
|
132
132
|
const addStaticUrl = (c, chunkFilename) => {
|