webpack 5.106.2 → 5.107.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/APIPlugin.js +1 -1
- package/lib/Cache.js +3 -6
- package/lib/CompatibilityPlugin.js +8 -7
- package/lib/Compilation.js +34 -26
- 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 -9
- package/lib/ExternalModule.js +76 -15
- package/lib/ExternalModuleFactoryPlugin.js +5 -0
- 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 +19 -18
- package/lib/ModuleFactory.js +1 -1
- package/lib/ModuleSourceTypeConstants.js +31 -1
- package/lib/ModuleTypeConstants.js +12 -3
- package/lib/MultiCompiler.js +2 -2
- package/lib/NodeStuffPlugin.js +1 -1
- package/lib/NormalModule.js +13 -31
- package/lib/NormalModuleFactory.js +10 -2
- 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 +11 -0
- 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 +6 -2
- package/lib/asset/AssetGenerator.js +22 -8
- package/lib/asset/AssetModulesPlugin.js +3 -1
- package/lib/asset/AssetSourceGenerator.js +6 -2
- 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 +166 -86
- 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 +4 -3
- 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 +25 -0
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +1 -1
- 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 +318 -0
- package/lib/dependencies/HtmlSourceDependency.js +127 -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/{ModuleNotFoundError.js → errors/ModuleNotFoundError.js} +2 -2
- 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 +433 -0
- package/lib/html/HtmlParser.js +1489 -0
- package/lib/html/walkHtmlTokens.js +2733 -0
- package/lib/ids/IdHelpers.js +2 -1
- package/lib/index.js +34 -15
- package/lib/javascript/JavascriptModulesPlugin.js +89 -8
- 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 +111 -3
- package/lib/optimize/SplitChunksPlugin.js +1 -1
- 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/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 +2 -2
- package/lib/sharing/ConsumeSharedRuntimeModule.js +8 -4
- package/lib/sharing/ProvideSharedModule.js +1 -1
- package/lib/sharing/ProvideSharedPlugin.js +1 -1
- 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 +2 -2
- 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 +22 -20
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +118 -3
- 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/{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 +810 -101
- 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,12 +14,14 @@ 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 */
|
|
@@ -63,6 +65,24 @@ const globToRegexp = (glob, cache) => {
|
|
|
63
65
|
return regexp;
|
|
64
66
|
};
|
|
65
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @param {JavascriptParser} parser parser
|
|
70
|
+
* @param {number} start start position
|
|
71
|
+
* @param {number} end end position
|
|
72
|
+
* @returns {boolean} if annotation is found in the range
|
|
73
|
+
*/
|
|
74
|
+
const hasNoSideEffectsNotation = (parser, start, end) => {
|
|
75
|
+
// Fast path
|
|
76
|
+
if (end - start < 18) return false;
|
|
77
|
+
|
|
78
|
+
const comments = parser.getComments([start, end]);
|
|
79
|
+
return comments.some(
|
|
80
|
+
(c) =>
|
|
81
|
+
c.type === "Block" &&
|
|
82
|
+
CompilerHintNotationRegExp.NoSideEffects.test(c.value)
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
66
86
|
const PLUGIN_NAME = "SideEffectsFlagPlugin";
|
|
67
87
|
|
|
68
88
|
class SideEffectsFlagPlugin {
|
|
@@ -129,7 +149,7 @@ class SideEffectsFlagPlugin {
|
|
|
129
149
|
* @param {JavascriptParser} parser the parser
|
|
130
150
|
* @returns {void}
|
|
131
151
|
*/
|
|
132
|
-
const
|
|
152
|
+
const applySideEffectsStmtHandler = (parser) => {
|
|
133
153
|
/** @type {undefined | Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} */
|
|
134
154
|
let sideEffectsStatement;
|
|
135
155
|
parser.hooks.program.tap(PLUGIN_NAME, () => {
|
|
@@ -260,6 +280,91 @@ class SideEffectsFlagPlugin {
|
|
|
260
280
|
}
|
|
261
281
|
});
|
|
262
282
|
};
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @param {JavascriptParser} parser the parser
|
|
286
|
+
* @returns {void}
|
|
287
|
+
*/
|
|
288
|
+
const applyNoSideEffectsNotationHandler = (parser) => {
|
|
289
|
+
/** @type {Set<string>} */
|
|
290
|
+
let noSideEffectsFnNames;
|
|
291
|
+
|
|
292
|
+
parser.hooks.program.tap(PLUGIN_NAME, () => {
|
|
293
|
+
noSideEffectsFnNames = new Set();
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Detect on function declarations
|
|
297
|
+
// Covers:
|
|
298
|
+
// 1. function foo
|
|
299
|
+
// 2. export function foo
|
|
300
|
+
// 3. export default function foo
|
|
301
|
+
parser.hooks.preStatement.tap(PLUGIN_NAME, (statement) => {
|
|
302
|
+
if (parser.scope.topLevelScope !== true) return;
|
|
303
|
+
if (statement.type !== "FunctionDeclaration" || !statement.id) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const commentsStart = parser.prevStatement
|
|
307
|
+
? /** @type {Range} */ (parser.prevStatement.range)[1]
|
|
308
|
+
: 0;
|
|
309
|
+
if (
|
|
310
|
+
hasNoSideEffectsNotation(
|
|
311
|
+
parser,
|
|
312
|
+
commentsStart,
|
|
313
|
+
/** @type {Range} */ (statement.range)[0]
|
|
314
|
+
)
|
|
315
|
+
) {
|
|
316
|
+
noSideEffectsFnNames.add(statement.id.name);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// Detect on variable declarations with function init
|
|
321
|
+
parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl, statement) => {
|
|
322
|
+
if (parser.scope.topLevelScope !== true) return;
|
|
323
|
+
if (!decl.init || decl.id.type !== "Identifier") return;
|
|
324
|
+
if (!decl.init.type.endsWith("FunctionExpression")) return;
|
|
325
|
+
|
|
326
|
+
let hasAnnotation = false;
|
|
327
|
+
// Before the VariableDeclaration (only for const)
|
|
328
|
+
if (statement.kind === "const") {
|
|
329
|
+
const commentsStart = parser.prevStatement
|
|
330
|
+
? /** @type {Range} */ (parser.prevStatement.range)[1]
|
|
331
|
+
: 0;
|
|
332
|
+
hasAnnotation = hasNoSideEffectsNotation(
|
|
333
|
+
parser,
|
|
334
|
+
commentsStart,
|
|
335
|
+
/** @type {Range} */ (statement.range)[0]
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
if (!hasAnnotation) {
|
|
340
|
+
hasAnnotation = hasNoSideEffectsNotation(
|
|
341
|
+
parser,
|
|
342
|
+
/** @type {Range} */ (decl.id.range)[1],
|
|
343
|
+
/** @type {Range} */ (decl.init.range)[0]
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
if (hasAnnotation) {
|
|
347
|
+
noSideEffectsFnNames.add(decl.id.name);
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// Mark calls to annotated functions as pure
|
|
352
|
+
parser.hooks.isPure
|
|
353
|
+
.for("CallExpression")
|
|
354
|
+
.tap(PLUGIN_NAME, (expression, commentsStartPos) => {
|
|
355
|
+
const expr = /** @type {CallExpression} */ (expression);
|
|
356
|
+
if (expr.callee.type !== "Identifier") return;
|
|
357
|
+
if (!noSideEffectsFnNames.has(expr.callee.name)) return;
|
|
358
|
+
commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
|
|
359
|
+
for (const arg of expr.arguments) {
|
|
360
|
+
if (arg.type === "SpreadElement") return;
|
|
361
|
+
if (!parser.isPure(arg, commentsStartPos)) return;
|
|
362
|
+
commentsStartPos = /** @type {Range} */ (arg.range)[1];
|
|
363
|
+
}
|
|
364
|
+
return true;
|
|
365
|
+
});
|
|
366
|
+
};
|
|
367
|
+
|
|
263
368
|
for (const key of [
|
|
264
369
|
JAVASCRIPT_MODULE_TYPE_AUTO,
|
|
265
370
|
JAVASCRIPT_MODULE_TYPE_ESM,
|
|
@@ -267,7 +372,10 @@ class SideEffectsFlagPlugin {
|
|
|
267
372
|
]) {
|
|
268
373
|
normalModuleFactory.hooks.parser
|
|
269
374
|
.for(key)
|
|
270
|
-
.tap(PLUGIN_NAME,
|
|
375
|
+
.tap(PLUGIN_NAME, (parser) => {
|
|
376
|
+
applyNoSideEffectsNotationHandler(parser);
|
|
377
|
+
applySideEffectsStmtHandler(parser);
|
|
378
|
+
});
|
|
271
379
|
}
|
|
272
380
|
}
|
|
273
381
|
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");
|
|
@@ -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
|
];
|
|
@@ -121,15 +121,40 @@ class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
|
|
|
121
121
|
? "init?.();"
|
|
122
122
|
: "if (init) init();";
|
|
123
123
|
return `${fn} = ${runtimeTemplate.basicFunction("moduleId, mode", [
|
|
124
|
+
// Per the TC39 import-defer spec, deferred namespaces are
|
|
125
|
+
// distinct from their eager counterparts and the same module
|
|
126
|
+
// referenced from multiple defer-import sites must yield the
|
|
127
|
+
// same object. Cache the Proxy / fake namespace per-moduleId so
|
|
128
|
+
// repeated calls (including across files) share identity.
|
|
129
|
+
//
|
|
130
|
+
// Bit 16 (`createFakeNamespaceObject`'s "return value when
|
|
131
|
+
// it's Promise-like" flag added by
|
|
132
|
+
// `RuntimeTemplate.moduleNamespacePromise` for dynamic
|
|
133
|
+
// imports) is irrelevant for deferred namespaces — the value
|
|
134
|
+
// passed into `createFakeNamespaceObject` here is always the
|
|
135
|
+
// resolved module exports (after unwrapping the async-module
|
|
136
|
+
// export symbol when present), never a Promise. Strip it
|
|
137
|
+
// once so all downstream behavior, the cache key, and the
|
|
138
|
+
// `createFakeNamespaceObject` call below see the same shape
|
|
139
|
+
// mode. This keeps static defer (mode 8) and dynamic
|
|
140
|
+
// `await import.defer` (mode 8 | 16) sharing the same
|
|
141
|
+
// Deferred Module Namespace object, while still keying by
|
|
142
|
+
// `(moduleId, mode)` so distinct exports-type shapes
|
|
143
|
+
// (e.g. one importer treats a CJS module as
|
|
144
|
+
// "default-with-named", another as "namespace") get
|
|
145
|
+
// distinct cache entries.
|
|
146
|
+
"mode &= ~16;",
|
|
147
|
+
"var byMode = __webpack_module_deferred_namespace_cache__[moduleId];",
|
|
148
|
+
"if (byMode && byMode[mode] !== undefined) return byMode[mode];",
|
|
149
|
+
"if (!byMode) byMode = __webpack_module_deferred_namespace_cache__[moduleId] = {};",
|
|
124
150
|
"var cachedModule = __webpack_module_cache__[moduleId];",
|
|
125
|
-
"if (cachedModule && cachedModule.error === undefined) {",
|
|
151
|
+
"if (cachedModule && cachedModule.error === undefined && !(mode & 8)) {",
|
|
126
152
|
Template.indent([
|
|
127
153
|
"var exports = cachedModule.exports;",
|
|
128
154
|
hasAsync
|
|
129
155
|
? `if (${RuntimeGlobals.asyncModuleExportSymbol} in exports) exports = exports[${RuntimeGlobals.asyncModuleExportSymbol}];`
|
|
130
156
|
: "",
|
|
131
|
-
|
|
132
|
-
`return ${RuntimeGlobals.createFakeNamespaceObject}(exports, mode);`
|
|
157
|
+
`return byMode[mode] = ${RuntimeGlobals.createFakeNamespaceObject}(exports, mode);`
|
|
133
158
|
]),
|
|
134
159
|
"}",
|
|
135
160
|
"",
|
|
@@ -141,9 +166,23 @@ class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
|
|
|
141
166
|
"init = null;",
|
|
142
167
|
"if (mode & 8 || mode & 4 && ns.__esModule && typeof ns === 'object') {",
|
|
143
168
|
Template.indent([
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
169
|
+
// Drop only the read-side traps after init: with the
|
|
170
|
+
// resolved namespace's own keys mirrored onto
|
|
171
|
+
// `ns_target` below, the default `Reflect` behavior
|
|
172
|
+
// returns the right values via the live-binding
|
|
173
|
+
// getters, so we no longer need to intercept `get` /
|
|
174
|
+
// `has` / `ownKeys` / `getOwnPropertyDescriptor`.
|
|
175
|
+
//
|
|
176
|
+
// The mutation traps (`set`, `deleteProperty`,
|
|
177
|
+
// `defineProperty`) are kept because per the TC39
|
|
178
|
+
// import-defer spec, `[[Set]]` / `[[Delete]]` /
|
|
179
|
+
// `[[DefineOwnProperty]]` on a Deferred Module
|
|
180
|
+
// Namespace Exotic Object never succeed — and the
|
|
181
|
+
// proxy target itself remains extensible
|
|
182
|
+
// (architecturally we cannot freeze it up-front),
|
|
183
|
+
// so without these traps `ns.notExported = "x"`
|
|
184
|
+
// after evaluation would silently create a property
|
|
185
|
+
// on the target instead of returning false.
|
|
147
186
|
"delete handler.get;",
|
|
148
187
|
"delete handler.has;",
|
|
149
188
|
"delete handler.ownKeys;",
|
|
@@ -153,13 +192,58 @@ class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
|
|
|
153
192
|
Template.indent([
|
|
154
193
|
`ns = ${RuntimeGlobals.createFakeNamespaceObject}(ns, mode);`
|
|
155
194
|
]),
|
|
195
|
+
"}",
|
|
196
|
+
// Mirror own properties from the resolved namespace onto the proxy
|
|
197
|
+
// target so that proxy invariants hold for callers that structurally
|
|
198
|
+
// introspect via `Object.keys` / `Object.getOwnPropertyNames` /
|
|
199
|
+
// `Object.getOwnPropertyDescriptor`: when our trap reports a
|
|
200
|
+
// non-configurable descriptor for a key, the target must also have
|
|
201
|
+
// that key with a matching descriptor.
|
|
202
|
+
//
|
|
203
|
+
// `__esModule` and `Symbol.toStringTag` are intentionally skipped:
|
|
204
|
+
// the proxy synthesizes "Deferred Module" / true regardless of what
|
|
205
|
+
// the underlying namespace exposes (per the TC39 import-defer
|
|
206
|
+
// proposal, the [[StringTag]] of a Deferred Module Namespace
|
|
207
|
+
// Exotic Object is "Deferred Module"), and the target was already
|
|
208
|
+
// pre-populated with those values below.
|
|
209
|
+
"var keys = Reflect.ownKeys(ns);",
|
|
210
|
+
"for (var i = 0; i < keys.length; i++) {",
|
|
211
|
+
Template.indent([
|
|
212
|
+
"var k = keys[i];",
|
|
213
|
+
'if (k === "__esModule" || k === Symbol.toStringTag) continue;',
|
|
214
|
+
"if (!Object.prototype.hasOwnProperty.call(ns_target, k)) {",
|
|
215
|
+
Template.indent([
|
|
216
|
+
"try { Object.defineProperty(ns_target, k, Reflect.getOwnPropertyDescriptor(ns, k)); } catch (_) {}"
|
|
217
|
+
]),
|
|
218
|
+
"}"
|
|
219
|
+
]),
|
|
156
220
|
"}"
|
|
157
221
|
])};`,
|
|
158
222
|
"",
|
|
159
|
-
|
|
223
|
+
// The proxy target is a fresh placeholder, separate from
|
|
224
|
+
// `__webpack_module_deferred_exports__[moduleId]` (which is reused
|
|
225
|
+
// by `__webpack_require__` as `module.exports` for deferred-loaded
|
|
226
|
+
// modules and would conflict with our pre-populated synthetic
|
|
227
|
+
// `__esModule` / `Symbol.toStringTag` non-configurable properties).
|
|
228
|
+
// Using a dedicated target keeps the proxy invariant-compliant
|
|
229
|
+
// without interfering with the module's own exports object.
|
|
230
|
+
"var ns_target = { __proto__: null };",
|
|
231
|
+
// Pre-populate the synthetic deferred-namespace properties with
|
|
232
|
+
// fully non-configurable, non-writable, non-enumerable descriptors
|
|
233
|
+
// (matching the TC39 import-defer spec for Module Namespace
|
|
234
|
+
// Exotic Objects). The trap returns the same descriptors below.
|
|
235
|
+
'Object.defineProperty(ns_target, "__esModule", { value: true });',
|
|
236
|
+
'Object.defineProperty(ns_target, Symbol.toStringTag, { value: "Deferred Module" });',
|
|
237
|
+
"var ns = ns_target;",
|
|
160
238
|
"var handler = {",
|
|
161
239
|
Template.indent([
|
|
162
240
|
"__proto__: null,",
|
|
241
|
+
// Per the TC39 import-defer proposal, `IsSymbolLikeNamespaceKey`
|
|
242
|
+
// returns true for any Symbol-keyed access (and for "then"); such
|
|
243
|
+
// accesses go through `OrdinaryGetOwnProperty` and must not
|
|
244
|
+
// trigger evaluation of the deferred module. The Symbol checks
|
|
245
|
+
// below short-circuit to the pre-populated target without
|
|
246
|
+
// running `init()`.
|
|
163
247
|
`get: ${runtimeTemplate.basicFunction("_, name", [
|
|
164
248
|
"switch (name) {",
|
|
165
249
|
Template.indent([
|
|
@@ -168,6 +252,7 @@ class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
|
|
|
168
252
|
'case "then": return undefined;'
|
|
169
253
|
]),
|
|
170
254
|
"}",
|
|
255
|
+
'if (typeof name === "symbol") return ns_target[name];',
|
|
171
256
|
init,
|
|
172
257
|
"return ns[name];"
|
|
173
258
|
])},`,
|
|
@@ -186,6 +271,7 @@ class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
|
|
|
186
271
|
].filter(Boolean)
|
|
187
272
|
),
|
|
188
273
|
"}",
|
|
274
|
+
'if (typeof name === "symbol") return name in ns_target;',
|
|
189
275
|
init,
|
|
190
276
|
"return name in ns;"
|
|
191
277
|
])},`,
|
|
@@ -197,11 +283,16 @@ class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
|
|
|
197
283
|
`getOwnPropertyDescriptor: ${runtimeTemplate.basicFunction("_, name", [
|
|
198
284
|
"switch (name) {",
|
|
199
285
|
Template.indent([
|
|
200
|
-
|
|
201
|
-
|
|
286
|
+
// Match the descriptors actually defined on `ns_target`
|
|
287
|
+
// (non-configurable, non-writable, non-enumerable) so the
|
|
288
|
+
// proxy invariant holds for both the trap result and any
|
|
289
|
+
// post-init forwarding via the deleted-handler path.
|
|
290
|
+
'case "__esModule": return { value: true, writable: false, enumerable: false, configurable: false };',
|
|
291
|
+
'case Symbol.toStringTag: return { value: "Deferred Module", writable: false, enumerable: false, configurable: false };',
|
|
202
292
|
'case "then": return undefined;'
|
|
203
293
|
]),
|
|
204
294
|
"}",
|
|
295
|
+
'if (typeof name === "symbol") return Reflect.getOwnPropertyDescriptor(ns_target, name);',
|
|
205
296
|
init,
|
|
206
297
|
"var desc = Reflect.getOwnPropertyDescriptor(ns, name);",
|
|
207
298
|
'if (mode & 2 && name == "default" && !desc) {',
|
|
@@ -209,18 +300,33 @@ class MakeDeferredNamespaceObjectRuntimeModule extends HelperRuntimeModule {
|
|
|
209
300
|
"}",
|
|
210
301
|
"return desc;"
|
|
211
302
|
])},`,
|
|
303
|
+
// `defineProperty` always rejects, but per the TC39 spec it
|
|
304
|
+
// must still trigger evaluation for string keys (the spec
|
|
305
|
+
// algorithm calls `[[GetOwnProperty]]` first, which forces
|
|
306
|
+
// evaluation on a deferred namespace). Symbol keys go through
|
|
307
|
+
// OrdinaryDefineOwnProperty and do not trigger eval.
|
|
212
308
|
`defineProperty: ${runtimeTemplate.basicFunction("_, name", [
|
|
309
|
+
'if (typeof name === "symbol" || name === "then") return false;',
|
|
310
|
+
init,
|
|
311
|
+
"return false;"
|
|
312
|
+
])},`,
|
|
313
|
+
// `deleteProperty` rejects, but per the TC39 spec it must
|
|
314
|
+
// still trigger evaluation for string keys (the spec
|
|
315
|
+
// algorithm calls `GetModuleExportsList` for non-symbol-like
|
|
316
|
+
// keys, forcing evaluation on a deferred namespace).
|
|
317
|
+
`deleteProperty: ${runtimeTemplate.basicFunction("_, name", [
|
|
318
|
+
'if (typeof name === "symbol" || name === "then") return false;',
|
|
213
319
|
init,
|
|
214
|
-
// Note: This behavior does not match the spec one, but since webpack does not do it either
|
|
215
|
-
// for a normal Module Namespace object (in MakeNamespaceObjectRuntimeModule), let's keep it simple.
|
|
216
320
|
"return false;"
|
|
217
321
|
])},`,
|
|
218
|
-
`
|
|
322
|
+
// `set` always returns false without triggering evaluation —
|
|
323
|
+
// the spec [[Set]] algorithm for Module Namespaces is just
|
|
324
|
+
// "return false" (no [[GetOwnProperty]], no eval).
|
|
219
325
|
`set: ${runtimeTemplate.returningFunction("false")},`
|
|
220
326
|
]),
|
|
221
327
|
"}",
|
|
222
328
|
// we don't fully emulate ES Module semantics in this Proxy to align with normal webpack esm namespace object.
|
|
223
|
-
"return new Proxy(
|
|
329
|
+
"return byMode[mode] = new Proxy(ns_target, handler);"
|
|
224
330
|
])};`;
|
|
225
331
|
}
|
|
226
332
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const RuntimeGlobals = require("../RuntimeGlobals");
|
|
8
|
+
const Template = require("../Template");
|
|
9
|
+
const HelperRuntimeModule = require("./HelperRuntimeModule");
|
|
10
|
+
|
|
11
|
+
/** @typedef {import("../Compilation")} Compilation */
|
|
12
|
+
|
|
13
|
+
class SetAnonymousDefaultNameRuntimeModule extends HelperRuntimeModule {
|
|
14
|
+
constructor() {
|
|
15
|
+
super("set anonymous default export name");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Generates runtime code for this runtime module.
|
|
20
|
+
* @returns {string | null} runtime code
|
|
21
|
+
*/
|
|
22
|
+
generate() {
|
|
23
|
+
const compilation = /** @type {Compilation} */ (this.compilation);
|
|
24
|
+
const { runtimeTemplate } = compilation;
|
|
25
|
+
const fn = RuntimeGlobals.setAnonymousDefaultName;
|
|
26
|
+
return Template.asString([
|
|
27
|
+
"// set .name for anonymous default exports per ES spec",
|
|
28
|
+
`${fn} = ${runtimeTemplate.basicFunction("x", [
|
|
29
|
+
'(Object.getOwnPropertyDescriptor(x, "name") || {}).writable || Object.defineProperty(x, "name", { value: "default", configurable: true });'
|
|
30
|
+
])};`
|
|
31
|
+
]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = SetAnonymousDefaultNameRuntimeModule;
|