webpack 5.107.1 → 5.108.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/hot/dev-server.js +2 -0
- package/lib/APIPlugin.js +8 -4
- package/lib/CacheFacade.js +7 -0
- package/lib/Chunk.js +4 -0
- package/lib/ChunkGraph.js +30 -9
- package/lib/CircularModulesPlugin.js +190 -0
- package/lib/CleanPlugin.js +2 -1
- package/lib/Compilation.js +396 -65
- package/lib/Compiler.js +52 -14
- package/lib/ConcatenationScope.js +10 -3
- package/lib/ContextExclusionPlugin.js +1 -0
- package/lib/ContextModule.js +92 -47
- package/lib/ContextModuleFactory.js +45 -38
- package/lib/ContextReplacementPlugin.js +4 -0
- package/lib/DefinePlugin.js +89 -15
- package/lib/Dependency.js +111 -7
- package/lib/EntryOptionPlugin.js +39 -2
- package/lib/EntryPlugin.js +2 -0
- package/lib/ExportsInfo.js +314 -73
- package/lib/ExternalModule.js +82 -34
- package/lib/ExternalModuleFactoryPlugin.js +1 -0
- package/lib/ExternalsPlugin.js +1 -0
- package/lib/FileSystemInfo.js +173 -23
- package/lib/FlagAllModulesAsUsedPlugin.js +1 -5
- package/lib/FlagDependencyExportsPlugin.js +23 -0
- package/lib/FlagDependencyUsagePlugin.js +87 -5
- package/lib/FlagEntryExportAsUsedPlugin.js +2 -0
- package/lib/Generator.js +8 -0
- package/lib/HotModuleReplacementPlugin.js +65 -28
- package/lib/IgnorePlugin.js +1 -0
- package/lib/InitFragment.js +5 -0
- package/lib/JavascriptMetaInfoPlugin.js +7 -5
- package/lib/LazyBarrel.js +361 -0
- package/lib/LoaderTargetPlugin.js +1 -0
- package/lib/Module.js +21 -42
- package/lib/ModuleGraph.js +3 -2
- package/lib/ModuleProfile.js +27 -1
- package/lib/ModuleTemplate.js +2 -0
- package/lib/MultiCompiler.js +16 -0
- package/lib/MultiStats.js +1 -0
- package/lib/MultiWatching.js +2 -0
- package/lib/NodeStuffPlugin.js +22 -17
- package/lib/NormalModule.js +557 -77
- package/lib/NormalModuleReplacementPlugin.js +2 -0
- package/lib/PrefetchPlugin.js +2 -0
- package/lib/ProgressPlugin.js +9 -1
- package/lib/ProvidePlugin.js +1 -0
- package/lib/RawModule.js +20 -16
- package/lib/RecordIdsPlugin.js +1 -0
- package/lib/RuntimeGlobals.js +5 -0
- package/lib/RuntimePlugin.js +58 -26
- package/lib/RuntimeTemplate.js +278 -21
- package/lib/SelfModuleFactory.js +1 -0
- package/lib/SourceMapDevToolPlugin.js +105 -30
- package/lib/Stats.js +1 -0
- package/lib/Template.js +8 -2
- package/lib/TemplatedPathPlugin.js +473 -131
- package/lib/WarnCaseSensitiveModulesPlugin.js +1 -0
- package/lib/WarnDeprecatedOptionPlugin.js +4 -0
- package/lib/WarnNoModeSetPlugin.js +1 -0
- package/lib/WatchIgnorePlugin.js +1 -0
- package/lib/Watching.js +9 -0
- package/lib/WebpackOptionsApply.js +50 -5
- package/lib/asset/AssetBytesGenerator.js +11 -3
- package/lib/asset/AssetGenerator.js +47 -22
- package/lib/asset/AssetModule.js +47 -0
- package/lib/asset/AssetModulesPlugin.js +14 -14
- package/lib/asset/AssetParser.js +2 -2
- package/lib/asset/AssetSourceGenerator.js +8 -0
- package/lib/asset/RawDataUrlModule.js +12 -13
- package/lib/buildChunkGraph.js +88 -9
- package/lib/bun/BunTargetPlugin.js +48 -0
- package/lib/cache/AddBuildDependenciesPlugin.js +1 -0
- package/lib/cache/AddManagedPathsPlugin.js +3 -0
- package/lib/cache/IdleFileCachePlugin.js +4 -0
- package/lib/cache/MemoryWithGcCachePlugin.js +1 -0
- package/lib/cache/PackFileCacheStrategy.js +1 -0
- package/lib/cache/ResolverCachePlugin.js +2 -0
- package/lib/cache/getLazyHashedEtag.js +9 -2
- package/lib/cache/mergeEtags.js +2 -0
- package/lib/cli.js +109 -19
- package/lib/config/browserslistTargetHandler.js +99 -0
- package/lib/config/defaults.js +147 -7
- package/lib/config/defineConfig.js +31 -0
- package/lib/config/normalization.js +5 -0
- package/lib/config/target.js +181 -2
- package/lib/container/ContainerEntryModule.js +15 -14
- package/lib/container/ContainerExposedDependency.js +2 -2
- package/lib/container/ContainerReferencePlugin.js +1 -1
- package/lib/container/FallbackDependency.js +5 -7
- package/lib/container/FallbackModule.js +10 -9
- package/lib/container/RemoteModule.js +20 -10
- package/lib/container/RemoteRuntimeModule.js +14 -12
- package/lib/css/CssGenerator.js +353 -327
- package/lib/css/CssInjectStyleRuntimeModule.js +36 -8
- package/lib/css/CssLoadingRuntimeModule.js +118 -47
- package/lib/css/CssModule.js +52 -23
- package/lib/css/CssModulesPlugin.js +107 -124
- package/lib/css/CssParser.js +2759 -2205
- package/lib/css/syntax.js +2859 -0
- package/lib/debug/ProfilingPlugin.js +2 -0
- package/lib/deno/DenoTargetPlugin.js +47 -0
- package/lib/dependencies/AMDDefineDependency.js +22 -17
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +1 -0
- package/lib/dependencies/AMDRequireArrayDependency.js +7 -11
- package/lib/dependencies/AMDRequireContextDependency.js +7 -11
- package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +1 -0
- package/lib/dependencies/AMDRequireDependency.js +24 -20
- package/lib/dependencies/CachedConstDependency.js +3 -0
- package/lib/dependencies/CommonJsDependencyHelpers.js +1 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +79 -31
- package/lib/dependencies/CommonJsExportsDependency.js +21 -16
- package/lib/dependencies/CommonJsExportsParserPlugin.js +230 -7
- package/lib/dependencies/CommonJsFullRequireDependency.js +27 -19
- package/lib/dependencies/CommonJsImportsParserPlugin.js +51 -16
- package/lib/dependencies/CommonJsPlugin.js +1 -1
- package/lib/dependencies/CommonJsRequireContextDependency.js +10 -13
- package/lib/dependencies/CommonJsRequireDependency.js +42 -11
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +22 -14
- package/lib/dependencies/ConstDependency.js +16 -11
- package/lib/dependencies/ContextDependency.js +4 -0
- package/lib/dependencies/ContextDependencyTemplateAsId.js +1 -1
- package/lib/dependencies/ContextElementDependency.js +23 -14
- package/lib/dependencies/CreateRequireParserPlugin.js +1 -0
- package/lib/dependencies/CreateScriptUrlDependency.js +5 -7
- package/lib/dependencies/CriticalDependencyWarning.js +1 -0
- package/lib/dependencies/CssIcssExportDependency.js +512 -574
- package/lib/dependencies/CssIcssImportDependency.js +9 -9
- package/lib/dependencies/CssIcssSymbolDependency.js +22 -15
- package/lib/dependencies/CssImportDependency.js +25 -1
- package/lib/dependencies/CssUrlDependency.js +23 -14
- package/lib/dependencies/DllEntryDependency.js +9 -13
- package/lib/dependencies/ExportBindingInitFragment.js +164 -0
- package/lib/dependencies/ExportsInfoDependency.js +12 -12
- package/lib/dependencies/ExternalModuleDependency.js +8 -5
- package/lib/dependencies/ExternalModuleInitFragment.js +7 -5
- package/lib/dependencies/ExternalModuleInitFragmentDependency.js +13 -10
- package/lib/dependencies/HarmonyAcceptDependency.js +11 -11
- package/lib/dependencies/HarmonyAcceptImportDependency.js +1 -0
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +47 -22
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +28 -2
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +46 -22
- package/lib/dependencies/HarmonyExportExpressionDependency.js +107 -30
- package/lib/dependencies/HarmonyExportHeaderDependency.js +7 -9
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +109 -31
- package/lib/dependencies/HarmonyExportInitFragment.js +22 -20
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +83 -18
- package/lib/dependencies/HarmonyExports.js +4 -1
- package/lib/dependencies/HarmonyImportDependency.js +24 -0
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +110 -74
- package/lib/dependencies/HarmonyImportGuard.js +254 -0
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +18 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +118 -14
- package/lib/dependencies/HarmonyLinkingError.js +1 -0
- package/lib/dependencies/HarmonyModulesPlugin.js +1 -0
- package/lib/dependencies/{HtmlScriptSrcDependency.js → HtmlEntryDependency.js} +267 -154
- package/lib/dependencies/HtmlInlineHtmlDependency.js +107 -0
- package/lib/dependencies/HtmlInlineScriptDependency.js +20 -27
- package/lib/dependencies/HtmlInlineStyleDependency.js +62 -11
- package/lib/dependencies/HtmlSourceDependency.js +18 -0
- package/lib/dependencies/ImportContextDependency.js +5 -9
- package/lib/dependencies/ImportDependency.js +44 -2
- package/lib/dependencies/ImportMetaHotAcceptDependency.js +1 -0
- package/lib/dependencies/ImportMetaHotDeclineDependency.js +1 -0
- package/lib/dependencies/ImportMetaPlugin.js +74 -30
- package/lib/dependencies/ImportParserPlugin.js +19 -0
- package/lib/dependencies/ImportWeakDependency.js +1 -0
- package/lib/dependencies/JsonExportsDependency.js +9 -9
- package/lib/dependencies/LoaderImportDependency.js +1 -0
- package/lib/dependencies/LocalModule.js +11 -12
- package/lib/dependencies/LocalModuleDependency.js +11 -13
- package/lib/dependencies/ModuleDecoratorDependency.js +9 -9
- package/lib/dependencies/ModuleDependency.js +7 -0
- package/lib/dependencies/ModuleHotAcceptDependency.js +1 -0
- package/lib/dependencies/ModuleHotDeclineDependency.js +1 -0
- package/lib/dependencies/ModuleInitFragmentDependency.js +15 -11
- package/lib/dependencies/ProvidedDependency.js +31 -27
- package/lib/dependencies/PureExpressionDependency.js +7 -9
- package/lib/dependencies/RequireEnsureDependency.js +12 -13
- package/lib/dependencies/RequireHeaderDependency.js +3 -4
- package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +3 -0
- package/lib/dependencies/RequireResolveContextDependency.js +7 -11
- package/lib/dependencies/RequireResolveDependency.js +1 -0
- package/lib/dependencies/RequireResolveHeaderDependency.js +3 -5
- package/lib/dependencies/RuntimeRequirementsDependency.js +6 -7
- package/lib/dependencies/StaticExportsDependency.js +10 -10
- package/lib/dependencies/SystemPlugin.js +2 -0
- package/lib/dependencies/URLContextDependency.js +5 -7
- package/lib/dependencies/URLDependency.js +14 -16
- package/lib/dependencies/UnsupportedDependency.js +8 -13
- package/lib/dependencies/WebAssemblyExportImportedDependency.js +11 -16
- package/lib/dependencies/WebAssemblyImportDependency.js +14 -16
- package/lib/dependencies/WebpackIsIncludedDependency.js +1 -0
- package/lib/dependencies/WorkerDependency.js +19 -8
- package/lib/dependencies/WorkerPlugin.js +40 -10
- package/lib/dependencies/processExportInfo.js +13 -11
- package/lib/dll/DelegatedModule.js +29 -15
- package/lib/dll/DelegatedModuleFactoryPlugin.js +1 -0
- package/lib/dll/DelegatedPlugin.js +1 -0
- package/lib/dll/DllEntryPlugin.js +3 -0
- package/lib/dll/DllModule.js +3 -2
- package/lib/dll/DllPlugin.js +16 -0
- package/lib/dll/DllReferencePlugin.js +3 -0
- package/lib/dll/LibManifestPlugin.js +1 -0
- package/lib/electron/ElectronTargetPlugin.js +22 -4
- package/lib/errors/ConcurrentCompilationError.js +1 -0
- package/lib/errors/HookWebpackError.js +11 -13
- package/lib/errors/IgnoreErrorModuleFactory.js +1 -0
- package/lib/errors/InvalidDependenciesModuleWarning.js +2 -0
- package/lib/errors/JSONParseError.js +9 -8
- package/lib/errors/ModuleBuildError.js +16 -13
- package/lib/errors/ModuleDependencyError.js +8 -1
- package/lib/errors/ModuleDependencyWarning.js +8 -1
- package/lib/errors/ModuleError.js +5 -11
- package/lib/errors/ModuleHashingError.js +4 -0
- package/lib/errors/ModuleNotFoundError.js +3 -0
- package/lib/errors/ModuleParseError.js +5 -11
- package/lib/errors/ModuleRestoreError.js +2 -0
- package/lib/errors/ModuleStoreError.js +3 -0
- package/lib/errors/ModuleWarning.js +7 -11
- package/lib/errors/NodeStuffInWebError.js +1 -0
- package/lib/errors/NonErrorEmittedError.js +2 -0
- package/lib/errors/UnhandledSchemeError.js +1 -0
- package/lib/esm/ModuleChunkLoadingPlugin.js +0 -1
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +28 -23
- package/lib/hmr/HotModuleReplacement.runtime.js +175 -30
- package/lib/hmr/HotModuleReplacementRuntimeModule.js +7 -0
- package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +173 -26
- package/lib/hmr/LazyCompilationPlugin.js +134 -6
- package/lib/html/HtmlGenerator.js +292 -50
- package/lib/html/HtmlModule.js +40 -0
- package/lib/html/HtmlModulesPlugin.js +287 -60
- package/lib/html/HtmlParser.js +1108 -1099
- package/lib/html/{walkHtmlTokens.js → syntax.js} +4701 -212
- package/lib/ids/IdHelpers.js +4 -2
- package/lib/index.js +19 -0
- package/lib/javascript/BasicEvaluatedExpression.js +1 -0
- package/lib/javascript/EnableChunkLoadingPlugin.js +1 -0
- package/lib/javascript/JavascriptGenerator.js +6 -2
- package/lib/javascript/JavascriptModule.js +54 -0
- package/lib/javascript/JavascriptModulesPlugin.js +257 -102
- package/lib/javascript/JavascriptParser.js +286 -159
- package/lib/json/JsonModule.js +40 -0
- package/lib/json/JsonModulesPlugin.js +7 -0
- package/lib/json/JsonParser.js +4 -2
- package/lib/library/AssignLibraryPlugin.js +5 -3
- package/lib/library/ExportPropertyLibraryPlugin.js +1 -0
- package/lib/library/FalseIIFEUmdWarning.js +1 -0
- package/lib/library/ModuleLibraryPlugin.js +54 -29
- package/lib/library/SystemLibraryPlugin.js +3 -3
- package/lib/node/NodeTargetPlugin.js +1 -0
- package/lib/node/NodeWatchFileSystem.js +38 -22
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +10 -9
- package/lib/node/RequireChunkLoadingRuntimeModule.js +18 -16
- package/lib/optimize/ConcatenatedModule.js +397 -78
- package/lib/optimize/ConstExportsPlugin.js +211 -0
- package/lib/optimize/InlineExports.js +178 -0
- package/lib/optimize/InnerGraph.js +372 -275
- package/lib/optimize/InnerGraphPlugin.js +196 -99
- package/lib/optimize/ModuleConcatenationPlugin.js +56 -25
- package/lib/optimize/RealContentHashPlugin.js +14 -1
- package/lib/optimize/SideEffectsFlagPlugin.js +234 -64
- package/lib/runtime/AsyncModuleRuntimeModule.js +32 -30
- package/lib/runtime/AutoPublicPathRuntimeModule.js +11 -5
- package/lib/runtime/CompatGetDefaultExportRuntimeModule.js +1 -1
- package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +6 -4
- package/lib/runtime/DefinePropertyGettersRuntimeModule.js +33 -4
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +82 -3
- package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +1 -1
- package/lib/runtime/HasOwnPropertyRuntimeModule.js +1 -1
- package/lib/runtime/LoadScriptRuntimeModule.js +18 -13
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +39 -26
- package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +1 -1
- package/lib/runtime/OnChunksLoadedRuntimeModule.js +4 -4
- package/lib/runtime/RelativeUrlRuntimeModule.js +3 -2
- package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +1 -1
- package/lib/runtime/StartupEntrypointRuntimeModule.js +4 -3
- package/lib/runtime/WorkerRuntimeModule.js +33 -0
- package/lib/schemes/HttpUriPlugin.js +3 -2
- package/lib/serialization/AggregateErrorSerializer.js +7 -6
- package/lib/serialization/ArraySerializer.js +4 -8
- package/lib/serialization/BinaryMiddleware.js +538 -468
- package/lib/serialization/DateObjectSerializer.js +2 -2
- package/lib/serialization/ErrorObjectSerializer.js +7 -6
- package/lib/serialization/MapObjectSerializer.js +5 -9
- package/lib/serialization/NullPrototypeObjectSerializer.js +7 -9
- package/lib/serialization/ObjectMiddleware.js +50 -13
- package/lib/serialization/PlainObjectSerializer.js +9 -8
- package/lib/serialization/RegExpObjectSerializer.js +2 -2
- package/lib/serialization/Serializer.js +1 -0
- package/lib/serialization/SetObjectSerializer.js +4 -8
- package/lib/sharing/ConsumeSharedModule.js +6 -7
- package/lib/sharing/ConsumeSharedPlugin.js +1 -0
- package/lib/sharing/ConsumeSharedRuntimeModule.js +46 -41
- package/lib/sharing/ProvideSharedDependency.js +30 -15
- package/lib/sharing/ProvideSharedModule.js +30 -11
- package/lib/sharing/ProvideSharedPlugin.js +4 -2
- package/lib/sharing/SharePlugin.js +3 -0
- package/lib/sharing/ShareRuntimeModule.js +18 -16
- package/lib/sharing/resolveMatchedConfigs.js +2 -1
- package/lib/sharing/utils.js +1 -1
- package/lib/stats/DefaultStatsFactoryPlugin.js +4 -6
- package/lib/stats/DefaultStatsPrinterPlugin.js +14 -14
- package/lib/stats/StatsFactory.js +11 -9
- package/lib/stats/StatsPrinter.js +9 -2
- package/lib/url/URLParserPlugin.js +5 -2
- package/lib/util/AsyncQueue.js +10 -0
- package/lib/util/LazyBucketSortedSet.js +5 -0
- package/lib/util/LazySet.js +6 -4
- package/lib/util/LocConverter.js +11 -1
- package/lib/util/Semaphore.js +1 -0
- package/lib/util/SourceProcessor.js +106 -0
- package/lib/util/TupleSet.js +1 -0
- package/lib/util/WeakTupleMap.js +27 -1
- package/lib/util/chainedImports.js +3 -3
- package/lib/util/comparators.js +2 -2
- package/lib/util/concatenate.js +31 -7
- package/lib/util/createHash.js +0 -1
- package/lib/util/deterministicGrouping.js +19 -12
- package/lib/util/extractSourceMap.js +1 -1
- package/lib/util/findGraphRoots.js +2 -0
- package/lib/util/fs.js +16 -6
- package/lib/util/hash/DebugHash.js +1 -0
- package/lib/util/hash/hash-digest.js +24 -15
- package/lib/util/identifier.js +7 -0
- package/lib/util/internalSerializables.js +11 -2
- package/lib/util/magicComment.js +42 -0
- package/lib/util/makeSerializable.js +1 -0
- package/lib/util/nonNumericOnlyHash.js +30 -1
- package/lib/util/property.js +7 -1
- package/lib/util/publicPathPlaceholder.js +64 -0
- package/lib/util/registerExternalSerializer.js +4 -4
- package/lib/wasm-async/AsyncWasmModule.js +77 -0
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +1 -1
- package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +1 -96
- package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
- package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +1 -1
- package/lib/wasm-sync/SyncWasmModule.js +39 -0
- package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +1 -0
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +6 -3
- package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +2 -1
- package/lib/wasm-sync/WebAssemblyGenerator.js +1 -0
- package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +2 -0
- package/lib/wasm-sync/WebAssemblyModulesPlugin.js +10 -0
- package/lib/wasm-sync/WebAssemblyParser.js +7 -3
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +45 -39
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +11 -10
- package/package.json +36 -28
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +212 -3
- package/schemas/plugins/HtmlGeneratorOptions.check.js +1 -1
- package/schemas/plugins/HtmlParserOptions.check.d.ts +7 -0
- package/schemas/plugins/HtmlParserOptions.check.js +6 -0
- package/schemas/plugins/HtmlParserOptions.json +3 -0
- package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +1 -1
- package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
- package/schemas/plugins/css/CssParserOptions.check.js +1 -1
- package/types.d.ts +1592 -314
- package/lib/css/walkCssTokens.js +0 -2020
- package/lib/util/AppendOnlyStackedSet.js +0 -93
|
@@ -9,6 +9,10 @@ const { basename, extname } = require("path");
|
|
|
9
9
|
const util = require("util");
|
|
10
10
|
const Chunk = require("./Chunk");
|
|
11
11
|
const Module = require("./Module");
|
|
12
|
+
const {
|
|
13
|
+
decode: decodeBase,
|
|
14
|
+
encode: encodeBase
|
|
15
|
+
} = require("./util/hash/hash-digest");
|
|
12
16
|
const { parseResource } = require("./util/identifier");
|
|
13
17
|
const memoize = require("./util/memoize");
|
|
14
18
|
|
|
@@ -17,6 +21,7 @@ const getMimeTypes = memoize(() => require("./util/mimeTypes"));
|
|
|
17
21
|
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
|
18
22
|
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
|
|
19
23
|
/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
|
|
24
|
+
/** @typedef {import("./Compilation").HashWithDigestFunction} HashWithDigestFunction */
|
|
20
25
|
/** @typedef {import("./Compilation").PathData} PathData */
|
|
21
26
|
/** @typedef {import("./Compilation").PathDataChunk} PathDataChunk */
|
|
22
27
|
/** @typedef {import("./Compilation").PathDataModule} PathDataModule */
|
|
@@ -24,6 +29,46 @@ const getMimeTypes = memoize(() => require("./util/mimeTypes"));
|
|
|
24
29
|
|
|
25
30
|
const REGEXP = /\[\\*([\w:]+)\\*\]/g;
|
|
26
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Placeholder kinds present in a template string, cached so the scan is not
|
|
34
|
+
* repeated for reused templates (e.g. `output.filename`, `localIdentName`).
|
|
35
|
+
* Bounded so dynamic (function-built) paths can't grow it without limit.
|
|
36
|
+
* @type {Map<string, Set<string>>}
|
|
37
|
+
*/
|
|
38
|
+
const presentKindsCache = new Map();
|
|
39
|
+
const PRESENT_KINDS_CACHE_MAX = 1000;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns the placeholder kinds (`[kind]` / `[kind:arg]`) a template references,
|
|
43
|
+
* matching the replace pass below so guarding replacer construction by it stays
|
|
44
|
+
* output-identical.
|
|
45
|
+
* @param {string} path template string (already known to contain `[`)
|
|
46
|
+
* @returns {Set<string>} placeholder kinds present
|
|
47
|
+
*/
|
|
48
|
+
const getPresentKinds = (path) => {
|
|
49
|
+
const cached = presentKindsCache.get(path);
|
|
50
|
+
if (cached !== undefined) return cached;
|
|
51
|
+
/** @type {Set<string>} */
|
|
52
|
+
const kinds = new Set();
|
|
53
|
+
// `RegExp.exec` loop rather than `String.matchAll` (Node.js 12+) so this
|
|
54
|
+
// stays compatible with the supported Node.js 10 range.
|
|
55
|
+
REGEXP.lastIndex = 0;
|
|
56
|
+
/** @type {RegExpExecArray | null} */
|
|
57
|
+
let m;
|
|
58
|
+
while ((m = REGEXP.exec(path)) !== null) {
|
|
59
|
+
const content = /** @type {string} */ (m[1]);
|
|
60
|
+
if (content.length + 2 === m[0].length) {
|
|
61
|
+
const cm = /^(\w+)(?::\w+)?(?::\w+)?$/.exec(content);
|
|
62
|
+
if (cm) kinds.add(cm[1]);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (presentKindsCache.size >= PRESENT_KINDS_CACHE_MAX) {
|
|
66
|
+
presentKindsCache.clear();
|
|
67
|
+
}
|
|
68
|
+
presentKindsCache.set(path, kinds);
|
|
69
|
+
return kinds;
|
|
70
|
+
};
|
|
71
|
+
|
|
27
72
|
/** @type {PathData["prepareId"]} */
|
|
28
73
|
const prepareId = (id) => {
|
|
29
74
|
if (typeof id !== "string") return id;
|
|
@@ -47,22 +92,143 @@ const prepareId = (id) => {
|
|
|
47
92
|
* @param {string} input
|
|
48
93
|
*/
|
|
49
94
|
|
|
95
|
+
/** @typedef {"26" | "32" | "36" | "49" | "52" | "58" | "62"} Base */
|
|
96
|
+
|
|
97
|
+
// `[<digest>]` placeholders may request a digest webpack does not store the
|
|
98
|
+
// hash in; loader-utils calls the URL-safe base64 `base64safe`.
|
|
99
|
+
const BASE_DIGEST = /^base(\d+)$/;
|
|
100
|
+
const SUPPORTED_BASES = new Set(["26", "32", "36", "49", "52", "58", "62"]);
|
|
101
|
+
|
|
102
|
+
// Node < 14.18 lacks the `base64url` Buffer encoding; fall back to base64 + swap.
|
|
103
|
+
let isBase64UrlSupported = false;
|
|
104
|
+
try {
|
|
105
|
+
isBase64UrlSupported = Boolean(Buffer.from("", "base64url"));
|
|
106
|
+
} catch (_err) {
|
|
107
|
+
// Nothing
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {string} digest digest name from a `[<hash>:<digest>]` placeholder
|
|
112
|
+
* @returns {boolean} whether a hash can be re-encoded into this digest
|
|
113
|
+
*/
|
|
114
|
+
const isSupportedDigest = (digest) => {
|
|
115
|
+
if (digest === "base64url" || digest === "base64safe") return true;
|
|
116
|
+
const base = BASE_DIGEST.exec(digest);
|
|
117
|
+
if (base) return base[1] === "64" || SUPPORTED_BASES.has(base[1]);
|
|
118
|
+
return Buffer.isEncoding(digest);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Decodes an already-digested hash string back into its raw bytes.
|
|
123
|
+
* @param {string} value digested hash
|
|
124
|
+
* @param {string} digest digest the value is encoded in
|
|
125
|
+
* @returns {Buffer} raw bytes
|
|
126
|
+
*/
|
|
127
|
+
const digestToBuffer = (value, digest) => {
|
|
128
|
+
const base = BASE_DIGEST.exec(digest);
|
|
129
|
+
if (base && Number(base[1]) !== 64) {
|
|
130
|
+
return decodeBase(value, /** @type {Base} */ (base[1]));
|
|
131
|
+
}
|
|
132
|
+
if (
|
|
133
|
+
(digest === "base64url" || digest === "base64safe") &&
|
|
134
|
+
!isBase64UrlSupported
|
|
135
|
+
) {
|
|
136
|
+
return Buffer.from(value.replace(/-/g, "+").replace(/_/g, "/"), "base64");
|
|
137
|
+
}
|
|
138
|
+
return Buffer.from(
|
|
139
|
+
value,
|
|
140
|
+
/** @type {BufferEncoding} */ (
|
|
141
|
+
digest === "base64safe" ? "base64url" : digest
|
|
142
|
+
)
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Encodes raw bytes into the requested digest.
|
|
148
|
+
* @param {Buffer} buffer raw bytes
|
|
149
|
+
* @param {string} digest target digest
|
|
150
|
+
* @returns {string} encoded hash
|
|
151
|
+
*/
|
|
152
|
+
const bufferToDigest = (buffer, digest) => {
|
|
153
|
+
const base = BASE_DIGEST.exec(digest);
|
|
154
|
+
if (base && Number(base[1]) !== 64) {
|
|
155
|
+
return encodeBase(buffer, /** @type {Base} */ (base[1]));
|
|
156
|
+
}
|
|
157
|
+
if (
|
|
158
|
+
(digest === "base64url" || digest === "base64safe") &&
|
|
159
|
+
!isBase64UrlSupported
|
|
160
|
+
) {
|
|
161
|
+
return buffer
|
|
162
|
+
.toString("base64")
|
|
163
|
+
.replace(/\+/g, "-")
|
|
164
|
+
.replace(/\//g, "_")
|
|
165
|
+
.replace(/[=]+$/, "");
|
|
166
|
+
}
|
|
167
|
+
return buffer.toString(
|
|
168
|
+
/** @type {BufferEncoding} */ (
|
|
169
|
+
digest === "base64safe" ? "base64url" : digest
|
|
170
|
+
)
|
|
171
|
+
);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Re-encodes a digested hash into another digest (e.g. `[contenthash:base64]`).
|
|
176
|
+
* The source is already truncated to `output.hashDigestLength`, so the result is
|
|
177
|
+
* derived from those bytes, not the full content. Throws on an unknown digest so
|
|
178
|
+
* a typo fails loudly rather than silently keeping the original encoding.
|
|
179
|
+
* @param {string} value digested hash
|
|
180
|
+
* @param {string} fromDigest digest the value is encoded in
|
|
181
|
+
* @param {string} toDigest requested digest
|
|
182
|
+
* @returns {string} re-encoded hash
|
|
183
|
+
*/
|
|
184
|
+
const reEncodeDigest = (value, fromDigest, toDigest) => {
|
|
185
|
+
if (toDigest === fromDigest) return value;
|
|
186
|
+
if (!isSupportedDigest(toDigest)) {
|
|
187
|
+
throw new Error(
|
|
188
|
+
`Unsupported hash digest "${toDigest}" in path template (use hex, base64, base64url, or base26/32/36/49/52/58/62)`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
return bufferToDigest(digestToBuffer(value, fromDigest), toDigest);
|
|
192
|
+
};
|
|
193
|
+
|
|
50
194
|
/**
|
|
51
195
|
* Returns hash replacer function.
|
|
52
196
|
* @param {ReplacerFunction} replacer replacer
|
|
53
197
|
* @param {((arg0: number) => string) | undefined} handler handler
|
|
54
198
|
* @param {AssetInfo | undefined} assetInfo asset info
|
|
55
199
|
* @param {string} hashName hash name
|
|
200
|
+
* @param {string} sourceDigest digest the stored hash is encoded in
|
|
201
|
+
* @param {string=} fullValue untruncated hash, re-encoded for `[<hash>:<digest>]` so the result carries full entropy instead of the `hashDigestLength`-truncated value
|
|
202
|
+
* @param {boolean=} recordDigest record the inline digest on `assetInfo.contenthashDigest` so `RealContentHashPlugin` re-encodes the recomputed hash in it
|
|
203
|
+
* @param {HashWithDigestFunction=} digestHandler builds the value for `[<hash>:<digest>]` in a per-chunk runtime context (the runtime chunk-filename map), where a single re-encode of the whole expression is impossible
|
|
56
204
|
* @returns {Replacer} hash replacer function
|
|
57
205
|
*/
|
|
58
|
-
const hashLength = (
|
|
206
|
+
const hashLength = (
|
|
207
|
+
replacer,
|
|
208
|
+
handler,
|
|
209
|
+
assetInfo,
|
|
210
|
+
hashName,
|
|
211
|
+
sourceDigest,
|
|
212
|
+
fullValue,
|
|
213
|
+
recordDigest,
|
|
214
|
+
digestHandler
|
|
215
|
+
) => {
|
|
59
216
|
/** @type {Replacer} */
|
|
60
|
-
const fn = (match, arg, input) => {
|
|
217
|
+
const fn = (match, arg, input, digest) => {
|
|
61
218
|
/** @type {string} */
|
|
62
219
|
let result;
|
|
63
220
|
const length = arg && Number.parseInt(arg, 10);
|
|
64
221
|
|
|
65
|
-
if (
|
|
222
|
+
if (digest && digestHandler) {
|
|
223
|
+
result = digestHandler(digest, length || undefined);
|
|
224
|
+
} else if (digest) {
|
|
225
|
+
const hash = reEncodeDigest(
|
|
226
|
+
fullValue !== undefined ? fullValue : replacer(match, arg, input),
|
|
227
|
+
sourceDigest,
|
|
228
|
+
digest
|
|
229
|
+
);
|
|
230
|
+
result = length ? hash.slice(0, length) : hash;
|
|
231
|
+
} else if (length && handler) {
|
|
66
232
|
result = handler(length);
|
|
67
233
|
} else {
|
|
68
234
|
const hash = replacer(match, arg, input);
|
|
@@ -71,6 +237,12 @@ const hashLength = (replacer, handler, assetInfo, hashName) => {
|
|
|
71
237
|
}
|
|
72
238
|
if (assetInfo) {
|
|
73
239
|
assetInfo.immutable = true;
|
|
240
|
+
if (digest && recordDigest) {
|
|
241
|
+
// `base64safe` is encoded as `base64url`; record what the value is in.
|
|
242
|
+
(assetInfo.contenthashDigest || (assetInfo.contenthashDigest = {}))[
|
|
243
|
+
result
|
|
244
|
+
] = digest === "base64safe" ? "base64url" : digest;
|
|
245
|
+
}
|
|
74
246
|
if (Array.isArray(assetInfo[hashName])) {
|
|
75
247
|
assetInfo[hashName] = [...assetInfo[hashName], result];
|
|
76
248
|
} else if (assetInfo[hashName]) {
|
|
@@ -85,7 +257,7 @@ const hashLength = (replacer, handler, assetInfo, hashName) => {
|
|
|
85
257
|
return fn;
|
|
86
258
|
};
|
|
87
259
|
|
|
88
|
-
/** @typedef {(match: string, arg: string | undefined, input: string) => string} Replacer */
|
|
260
|
+
/** @typedef {(match: string, arg: string | undefined, input: string, digest?: string) => string} Replacer */
|
|
89
261
|
|
|
90
262
|
/**
|
|
91
263
|
* Returns replacer.
|
|
@@ -167,7 +339,27 @@ const deprecated = (fn, message, code) => {
|
|
|
167
339
|
* @returns {string} the interpolated path
|
|
168
340
|
*/
|
|
169
341
|
const interpolate = (path, data, assetInfo) => {
|
|
342
|
+
if (typeof path === "function") {
|
|
343
|
+
path = path(data, assetInfo);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Literal paths carry no `[placeholder]`, so the whole replacement table
|
|
347
|
+
// and regex pass are pure overhead — building replacers has no side effects
|
|
348
|
+
// (those only fire when a replacer is invoked), so the output is identical.
|
|
349
|
+
if (!path.includes("[")) {
|
|
350
|
+
return path;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Only build replacers for placeholders the template actually uses — most
|
|
354
|
+
// templates reference a handful, so building the whole table per call is
|
|
355
|
+
// wasted work. Replacer construction has no side effects (those fire only
|
|
356
|
+
// when a replacer is invoked, which happens for present kinds), so this is
|
|
357
|
+
// output-identical.
|
|
358
|
+
const presentKinds = getPresentKinds(path);
|
|
359
|
+
|
|
170
360
|
const chunkGraph = data.chunkGraph;
|
|
361
|
+
// Digest the stored hashes are encoded in, so `[hash:<digest>]` can re-encode.
|
|
362
|
+
const sourceDigest = data.hashDigest || "hex";
|
|
171
363
|
|
|
172
364
|
/** @type {Map<string, Replacer>} */
|
|
173
365
|
const replacements = new Map();
|
|
@@ -184,7 +376,17 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
184
376
|
// [path] - /some/path/
|
|
185
377
|
// [name] - file
|
|
186
378
|
// [ext] - .js
|
|
187
|
-
if (
|
|
379
|
+
if (
|
|
380
|
+
typeof data.filename === "string" &&
|
|
381
|
+
(presentKinds.has("file") ||
|
|
382
|
+
presentKinds.has("query") ||
|
|
383
|
+
presentKinds.has("fragment") ||
|
|
384
|
+
presentKinds.has("path") ||
|
|
385
|
+
presentKinds.has("base") ||
|
|
386
|
+
presentKinds.has("name") ||
|
|
387
|
+
presentKinds.has("ext") ||
|
|
388
|
+
presentKinds.has("filebase"))
|
|
389
|
+
) {
|
|
188
390
|
// check that filename is data uri
|
|
189
391
|
const match = data.filename.match(/^data:([^;,]+)/);
|
|
190
392
|
if (match) {
|
|
@@ -197,22 +399,28 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
197
399
|
: false;
|
|
198
400
|
const baseReplacer = contentHash ? replacer(contentHash) : emptyReplacer;
|
|
199
401
|
|
|
200
|
-
replacements.set("file", emptyReplacer);
|
|
201
|
-
replacements.set("query", emptyReplacer);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
replacements.set("
|
|
206
|
-
|
|
402
|
+
if (presentKinds.has("file")) replacements.set("file", emptyReplacer);
|
|
403
|
+
if (presentKinds.has("query")) replacements.set("query", emptyReplacer);
|
|
404
|
+
if (presentKinds.has("fragment")) {
|
|
405
|
+
replacements.set("fragment", emptyReplacer);
|
|
406
|
+
}
|
|
407
|
+
if (presentKinds.has("path")) replacements.set("path", emptyReplacer);
|
|
408
|
+
if (presentKinds.has("base")) replacements.set("base", baseReplacer);
|
|
409
|
+
if (presentKinds.has("name")) replacements.set("name", baseReplacer);
|
|
410
|
+
if (presentKinds.has("ext")) {
|
|
411
|
+
replacements.set("ext", replacer(ext ? `.${ext}` : "", true));
|
|
412
|
+
}
|
|
207
413
|
// Legacy
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
414
|
+
if (presentKinds.has("filebase")) {
|
|
415
|
+
replacements.set(
|
|
416
|
+
"filebase",
|
|
417
|
+
deprecated(
|
|
418
|
+
baseReplacer,
|
|
419
|
+
"[filebase] is now [base]",
|
|
420
|
+
"DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_FILENAME"
|
|
421
|
+
)
|
|
422
|
+
);
|
|
423
|
+
}
|
|
216
424
|
} else {
|
|
217
425
|
const { path: file, query, fragment } = parseResource(data.filename);
|
|
218
426
|
|
|
@@ -221,22 +429,30 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
221
429
|
const name = base.slice(0, base.length - ext.length);
|
|
222
430
|
const path = file.slice(0, file.length - base.length);
|
|
223
431
|
|
|
224
|
-
replacements.set("file", replacer(file));
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
432
|
+
if (presentKinds.has("file")) replacements.set("file", replacer(file));
|
|
433
|
+
if (presentKinds.has("query")) {
|
|
434
|
+
replacements.set("query", replacer(query, true));
|
|
435
|
+
}
|
|
436
|
+
if (presentKinds.has("fragment")) {
|
|
437
|
+
replacements.set("fragment", replacer(fragment, true));
|
|
438
|
+
}
|
|
439
|
+
if (presentKinds.has("path")) {
|
|
440
|
+
replacements.set("path", replacer(path, true));
|
|
441
|
+
}
|
|
442
|
+
if (presentKinds.has("base")) replacements.set("base", replacer(base));
|
|
443
|
+
if (presentKinds.has("name")) replacements.set("name", replacer(name));
|
|
444
|
+
if (presentKinds.has("ext")) replacements.set("ext", replacer(ext, true));
|
|
231
445
|
// Legacy
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
446
|
+
if (presentKinds.has("filebase")) {
|
|
447
|
+
replacements.set(
|
|
448
|
+
"filebase",
|
|
449
|
+
deprecated(
|
|
450
|
+
replacer(base),
|
|
451
|
+
"[filebase] is now [base]",
|
|
452
|
+
"DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_FILENAME"
|
|
453
|
+
)
|
|
454
|
+
);
|
|
455
|
+
}
|
|
240
456
|
}
|
|
241
457
|
}
|
|
242
458
|
|
|
@@ -249,25 +465,35 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
249
465
|
// Legacy Placeholders
|
|
250
466
|
//
|
|
251
467
|
// [hash] - data.hash (3a4b5c6e7f)
|
|
252
|
-
if (data.hash) {
|
|
468
|
+
if (data.hash && (presentKinds.has("fullhash") || presentKinds.has("hash"))) {
|
|
253
469
|
const hashReplacer = hashLength(
|
|
254
470
|
replacer(data.hash),
|
|
255
471
|
data.hashWithLength,
|
|
256
472
|
assetInfo,
|
|
257
|
-
"fullhash"
|
|
473
|
+
"fullhash",
|
|
474
|
+
data.fullHashDigest || sourceDigest,
|
|
475
|
+
data.fullHash,
|
|
476
|
+
undefined,
|
|
477
|
+
data.hashWithDigest
|
|
258
478
|
);
|
|
259
479
|
|
|
260
|
-
|
|
480
|
+
if (presentKinds.has("fullhash")) {
|
|
481
|
+
replacements.set("fullhash", hashReplacer);
|
|
482
|
+
}
|
|
261
483
|
|
|
262
|
-
// Legacy
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
484
|
+
// Legacy — but a css-loader-style `[hash]` local ident is not deprecated
|
|
485
|
+
if (presentKinds.has("hash")) {
|
|
486
|
+
replacements.set(
|
|
487
|
+
"hash",
|
|
488
|
+
data.hashAsFullHash
|
|
489
|
+
? hashReplacer
|
|
490
|
+
: deprecated(
|
|
491
|
+
hashReplacer,
|
|
492
|
+
"[hash] is now [fullhash] (also consider using [chunkhash] or [contenthash], see documentation for details)",
|
|
493
|
+
"DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_HASH"
|
|
494
|
+
)
|
|
495
|
+
);
|
|
496
|
+
}
|
|
271
497
|
}
|
|
272
498
|
|
|
273
499
|
// Chunk Context
|
|
@@ -283,33 +509,55 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
283
509
|
|
|
284
510
|
const contentHashType = data.contentHashType;
|
|
285
511
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
512
|
+
if (presentKinds.has("id")) replacements.set("id", replacer(chunk.id));
|
|
513
|
+
if (presentKinds.has("name")) {
|
|
514
|
+
replacements.set("name", replacer(chunk.name || chunk.id));
|
|
515
|
+
}
|
|
516
|
+
if (presentKinds.has("chunkhash")) {
|
|
517
|
+
replacements.set(
|
|
518
|
+
"chunkhash",
|
|
519
|
+
hashLength(
|
|
520
|
+
replacer(chunk instanceof Chunk ? chunk.renderedHash : chunk.hash),
|
|
521
|
+
"hashWithLength" in chunk ? chunk.hashWithLength : undefined,
|
|
522
|
+
assetInfo,
|
|
523
|
+
"chunkhash",
|
|
524
|
+
sourceDigest,
|
|
525
|
+
chunk.hash,
|
|
526
|
+
undefined,
|
|
527
|
+
"hashWithDigest" in chunk ? chunk.hashWithDigest : undefined
|
|
528
|
+
)
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
if (presentKinds.has("contenthash")) {
|
|
532
|
+
const ct = /** @type {string} */ (contentHashType);
|
|
533
|
+
replacements.set(
|
|
534
|
+
"contenthash",
|
|
535
|
+
hashLength(
|
|
536
|
+
replacer(
|
|
537
|
+
data.contentHash ||
|
|
538
|
+
(contentHashType &&
|
|
539
|
+
chunk.contentHash &&
|
|
540
|
+
chunk.contentHash[contentHashType])
|
|
541
|
+
),
|
|
542
|
+
data.contentHashWithLength ||
|
|
543
|
+
("contentHashWithLength" in chunk && chunk.contentHashWithLength
|
|
544
|
+
? chunk.contentHashWithLength[ct]
|
|
545
|
+
: undefined),
|
|
546
|
+
assetInfo,
|
|
547
|
+
"contenthash",
|
|
548
|
+
sourceDigest,
|
|
549
|
+
// full content digest, so a static `[contenthash:<digest>]` re-encodes
|
|
550
|
+
// from full entropy (the runtime path uses `contentHashWithDigest`)
|
|
551
|
+
"contentHashFull" in chunk && chunk.contentHashFull
|
|
552
|
+
? chunk.contentHashFull[ct]
|
|
553
|
+
: undefined,
|
|
554
|
+
data.realContentHash,
|
|
555
|
+
"contentHashWithDigest" in chunk && chunk.contentHashWithDigest
|
|
556
|
+
? chunk.contentHashWithDigest[ct]
|
|
557
|
+
: undefined
|
|
558
|
+
)
|
|
559
|
+
);
|
|
560
|
+
}
|
|
313
561
|
}
|
|
314
562
|
|
|
315
563
|
// Module Context
|
|
@@ -325,78 +573,149 @@ const interpolate = (path, data, assetInfo) => {
|
|
|
325
573
|
// [modulehash] - module.hash (6237543873.png)
|
|
326
574
|
if (data.module) {
|
|
327
575
|
const module = data.module;
|
|
576
|
+
const needId = presentKinds.has("id");
|
|
577
|
+
const needModuleId = presentKinds.has("moduleid");
|
|
578
|
+
// `data.hashAsFullHash` keeps `[hash]` as the `[fullhash]` alias (CSS local
|
|
579
|
+
// idents) instead of repurposing it to the module hash; `[modulehash]` stays.
|
|
580
|
+
const needHash = presentKinds.has("hash") && !data.hashAsFullHash;
|
|
581
|
+
|
|
582
|
+
if (needId || needModuleId) {
|
|
583
|
+
const idReplacer = replacer(() =>
|
|
584
|
+
(data.prepareId || prepareId)(
|
|
585
|
+
module instanceof Module
|
|
586
|
+
? /** @type {ModuleId} */
|
|
587
|
+
(/** @type {ChunkGraph} */ (chunkGraph).getModuleId(module))
|
|
588
|
+
: module.id
|
|
589
|
+
)
|
|
590
|
+
);
|
|
591
|
+
if (needId) replacements.set("id", idReplacer);
|
|
592
|
+
// Legacy
|
|
593
|
+
if (needModuleId) {
|
|
594
|
+
replacements.set(
|
|
595
|
+
"moduleid",
|
|
596
|
+
deprecated(
|
|
597
|
+
idReplacer,
|
|
598
|
+
"[moduleid] is now [id]",
|
|
599
|
+
"DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_MODULE_ID"
|
|
600
|
+
)
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
328
604
|
|
|
329
|
-
|
|
330
|
-
|
|
605
|
+
// `[hash]` aliases module content hash when present, else module hash.
|
|
606
|
+
const wantModuleHash =
|
|
607
|
+
presentKinds.has("modulehash") || (needHash && !data.contentHash);
|
|
608
|
+
const wantContentHash =
|
|
609
|
+
presentKinds.has("contenthash") || (needHash && data.contentHash);
|
|
610
|
+
/** @type {Replacer | undefined} */
|
|
611
|
+
let moduleHashReplacer;
|
|
612
|
+
/** @type {Replacer | undefined} */
|
|
613
|
+
let contentHashReplacer;
|
|
614
|
+
if (wantModuleHash) {
|
|
615
|
+
moduleHashReplacer = hashLength(
|
|
616
|
+
replacer(() =>
|
|
617
|
+
module instanceof Module
|
|
618
|
+
? /** @type {ChunkGraph} */
|
|
619
|
+
(chunkGraph).getRenderedModuleHash(module, data.runtime)
|
|
620
|
+
: module.hash
|
|
621
|
+
),
|
|
622
|
+
"hashWithLength" in module ? module.hashWithLength : undefined,
|
|
623
|
+
assetInfo,
|
|
624
|
+
"modulehash",
|
|
625
|
+
sourceDigest,
|
|
626
|
+
// `getModuleHash` is the untruncated digest (`getRenderedModuleHash` is
|
|
627
|
+
// the truncated one), so `[modulehash:<digest>]` re-encodes full entropy
|
|
331
628
|
module instanceof Module
|
|
332
|
-
? /** @type {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
);
|
|
337
|
-
const moduleHashReplacer = hashLength(
|
|
338
|
-
replacer(() =>
|
|
339
|
-
module instanceof Module
|
|
340
|
-
? /** @type {ChunkGraph} */
|
|
341
|
-
(chunkGraph).getRenderedModuleHash(module, data.runtime)
|
|
629
|
+
? /** @type {ChunkGraph} */ (chunkGraph).getModuleHash(
|
|
630
|
+
module,
|
|
631
|
+
data.runtime
|
|
632
|
+
)
|
|
342
633
|
: module.hash
|
|
343
|
-
)
|
|
344
|
-
"
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
)
|
|
370
|
-
|
|
634
|
+
);
|
|
635
|
+
if (presentKinds.has("modulehash")) {
|
|
636
|
+
replacements.set("modulehash", moduleHashReplacer);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
if (wantContentHash) {
|
|
640
|
+
contentHashReplacer = hashLength(
|
|
641
|
+
replacer(/** @type {string} */ (data.contentHash)),
|
|
642
|
+
undefined,
|
|
643
|
+
assetInfo,
|
|
644
|
+
"contenthash",
|
|
645
|
+
sourceDigest,
|
|
646
|
+
// full content digest, so a static `[contenthash:<digest>]` re-encodes
|
|
647
|
+
// from full entropy (asset modules supply it via `contentHashFull`)
|
|
648
|
+
data.contentHashFull,
|
|
649
|
+
data.realContentHash
|
|
650
|
+
);
|
|
651
|
+
if (presentKinds.has("contenthash")) {
|
|
652
|
+
replacements.set("contenthash", contentHashReplacer);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
if (needHash) {
|
|
656
|
+
replacements.set(
|
|
657
|
+
"hash",
|
|
658
|
+
/** @type {Replacer} */
|
|
659
|
+
(data.contentHash ? contentHashReplacer : moduleHashReplacer)
|
|
660
|
+
);
|
|
661
|
+
}
|
|
371
662
|
}
|
|
372
663
|
|
|
373
664
|
// Other things
|
|
374
|
-
|
|
665
|
+
//
|
|
666
|
+
// Placeholders
|
|
667
|
+
//
|
|
668
|
+
// [url] - data.url
|
|
669
|
+
// [uniqueName] - data.uniqueName (output.uniqueName)
|
|
670
|
+
// [uniquename] - alias of [uniqueName]
|
|
671
|
+
if (data.url && presentKinds.has("url")) {
|
|
375
672
|
replacements.set("url", replacer(data.url));
|
|
376
673
|
}
|
|
377
|
-
if (
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
674
|
+
if (
|
|
675
|
+
data.uniqueName !== undefined &&
|
|
676
|
+
(presentKinds.has("uniqueName") || presentKinds.has("uniquename"))
|
|
677
|
+
) {
|
|
678
|
+
const uniqueNameReplacer = replacer(data.uniqueName);
|
|
679
|
+
if (presentKinds.has("uniqueName")) {
|
|
680
|
+
replacements.set("uniqueName", uniqueNameReplacer);
|
|
681
|
+
}
|
|
682
|
+
if (presentKinds.has("uniquename")) {
|
|
683
|
+
replacements.set("uniquename", uniqueNameReplacer);
|
|
684
|
+
}
|
|
386
685
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
686
|
+
if (presentKinds.has("runtime")) {
|
|
687
|
+
if (typeof data.runtime === "string") {
|
|
688
|
+
replacements.set(
|
|
689
|
+
"runtime",
|
|
690
|
+
replacer(() =>
|
|
691
|
+
(data.prepareId || prepareId)(/** @type {string} */ (data.runtime))
|
|
692
|
+
)
|
|
693
|
+
);
|
|
694
|
+
} else {
|
|
695
|
+
replacements.set("runtime", replacer("_"));
|
|
696
|
+
}
|
|
390
697
|
}
|
|
391
698
|
|
|
392
699
|
path = path.replace(REGEXP, (match, content) => {
|
|
393
700
|
if (content.length + 2 === match.length) {
|
|
394
|
-
const contentMatch = /^(\w+)(?::(\w+))?$/.exec(content);
|
|
701
|
+
const contentMatch = /^(\w+)(?::(\w+))?(?::(\w+))?$/.exec(content);
|
|
395
702
|
if (!contentMatch) return match;
|
|
396
|
-
const [, kind,
|
|
703
|
+
const [, kind, arg1, arg2] = contentMatch;
|
|
397
704
|
const replacer = replacements.get(kind);
|
|
398
705
|
if (replacer !== undefined) {
|
|
399
|
-
|
|
706
|
+
// `[kind:length]`, `[kind:digest]` or `[kind:digest:length]`.
|
|
707
|
+
/** @type {string | undefined} */
|
|
708
|
+
let digest;
|
|
709
|
+
/** @type {string | undefined} */
|
|
710
|
+
let length = arg1;
|
|
711
|
+
if (arg2 !== undefined) {
|
|
712
|
+
digest = arg1;
|
|
713
|
+
length = arg2;
|
|
714
|
+
} else if (arg1 !== undefined && !/^\d+$/.test(arg1)) {
|
|
715
|
+
digest = arg1;
|
|
716
|
+
length = undefined;
|
|
717
|
+
}
|
|
718
|
+
return replacer(match, length, /** @type {string} */ (path), digest);
|
|
400
719
|
}
|
|
401
720
|
} else if (match.startsWith("[\\") && match.endsWith("\\]")) {
|
|
402
721
|
return `[${match.slice(2, -2)}]`;
|
|
@@ -417,10 +736,33 @@ class TemplatedPathPlugin {
|
|
|
417
736
|
*/
|
|
418
737
|
apply(compiler) {
|
|
419
738
|
compiler.hooks.compilation.tap(plugin, (compilation) => {
|
|
420
|
-
compilation.hooks.assetPath.tap(plugin,
|
|
739
|
+
compilation.hooks.assetPath.tap(plugin, (path, data, assetInfo) => {
|
|
740
|
+
// Default from output options so `[uniqueName]` resolves in every template
|
|
741
|
+
if (data.uniqueName === undefined) {
|
|
742
|
+
data.uniqueName = compilation.outputOptions.uniqueName;
|
|
743
|
+
}
|
|
744
|
+
// Digest the stored hashes use, so `[hash:<digest>]` can re-encode them
|
|
745
|
+
if (data.hashDigest === undefined) {
|
|
746
|
+
data.hashDigest = compilation.outputOptions.hashDigest;
|
|
747
|
+
}
|
|
748
|
+
// Untruncated compilation hash, so `[fullhash:<digest>]` keeps full entropy
|
|
749
|
+
if (data.fullHash === undefined && data.hash === compilation.hash) {
|
|
750
|
+
data.fullHash = compilation.fullHash;
|
|
751
|
+
}
|
|
752
|
+
// `RealContentHashPlugin` rehashes content; flag it so an inline digest
|
|
753
|
+
// on `[contenthash]` is recorded and the recomputed hash re-encodes in it.
|
|
754
|
+
if (data.realContentHash === undefined) {
|
|
755
|
+
data.realContentHash = Boolean(
|
|
756
|
+
compilation.options.optimization.realContentHash
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
return interpolate(path, data, assetInfo);
|
|
760
|
+
});
|
|
421
761
|
});
|
|
422
762
|
}
|
|
423
763
|
}
|
|
424
764
|
|
|
425
765
|
module.exports = TemplatedPathPlugin;
|
|
766
|
+
module.exports.getPresentKinds = getPresentKinds;
|
|
426
767
|
module.exports.interpolate = interpolate;
|
|
768
|
+
module.exports.reEncodeDigest = reEncodeDigest;
|