webpack 5.111.0 → 5.111.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/APIPlugin.js +3 -4
- package/lib/CompatibilityPlugin.js +3 -4
- package/lib/Compilation.js +16 -35
- package/lib/Compiler.js +4 -5
- package/lib/ConstPlugin.js +16 -132
- package/lib/DependencyTemplate.js +2 -1
- package/lib/DotenvPlugin.js +24 -28
- package/lib/ErrorHelpers.js +113 -0
- package/lib/ExportsInfo.js +20 -16
- package/lib/ExternalModule.js +6 -8
- package/lib/FlagDependencyExportsPlugin.js +8 -13
- package/lib/FlagDependencyUsagePlugin.js +9 -13
- package/lib/Generator.js +24 -2
- package/lib/HotModuleReplacementPlugin.js +2 -0
- package/lib/IgnorePlugin.js +1 -1
- package/lib/LoaderOptionsPlugin.js +1 -1
- package/lib/Module.js +3 -3
- package/lib/ModuleGraph.js +6 -9
- package/lib/MultiCompiler.js +6 -16
- package/lib/NormalModule.js +96 -44
- package/lib/RuntimeTemplate.js +33 -43
- package/lib/SourceMapDevToolPlugin.js +53 -103
- package/lib/TemplatedPathPlugin.js +16 -59
- package/lib/asset/AssetBytesGenerator.js +7 -1
- package/lib/asset/AssetGenerator.js +25 -16
- package/lib/asset/AssetSourceGenerator.js +7 -1
- package/lib/buildChunkGraph.js +11 -15
- package/lib/cache/MemoryCachePlugin.js +4 -4
- package/lib/cache/MemoryWithGcCachePlugin.js +7 -8
- package/lib/cache/PackFileCacheStrategy.js +3 -18
- package/lib/cache/getLazyHashedEtag.js +3 -5
- package/lib/config/browserslistTargetHandler.js +2 -8
- package/lib/config/defaults.js +52 -78
- package/lib/config/getClaimedAssetTypes.js +10 -11
- package/lib/config/target.js +3 -4
- package/lib/{ContextExclusionPlugin.js → context/ContextExclusionPlugin.js} +1 -1
- package/lib/{ContextModule.js → context/ContextModule.js} +37 -34
- package/lib/{ContextModuleFactory.js → context/ContextModuleFactory.js} +19 -21
- package/lib/{ContextReplacementPlugin.js → context/ContextReplacementPlugin.js} +4 -4
- package/lib/css/CssGenerator.js +19 -11
- package/lib/css/CssParser.js +18 -20
- package/lib/css/cssMinify.js +32 -29
- package/lib/css/data.js +797 -288
- package/lib/css/syntax.js +2250 -934
- package/lib/debug/ProfilingPlugin.js +3 -4
- package/lib/dependencies/CommonJsExportRequireDependency.js +10 -11
- package/lib/dependencies/CommonJsImportsParserPlugin.js +4 -5
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +2 -4
- package/lib/dependencies/ContextDependency.js +1 -1
- package/lib/dependencies/ContextDependencyHelpers.js +3 -9
- package/lib/dependencies/ContextElementDependency.js +1 -1
- package/lib/dependencies/CssIcssExportDependency.js +6 -8
- package/lib/dependencies/CssIcssImportDependency.js +3 -6
- package/lib/dependencies/CssUrlDependency.js +3 -5
- package/lib/dependencies/HarmonyCompatibilityDependency.js +11 -20
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +3 -4
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +2 -4
- package/lib/dependencies/HarmonyExportExpressionDependency.js +3 -4
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +3 -4
- package/lib/dependencies/HarmonyExportInitFragment.js +26 -19
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +7 -28
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +103 -16
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +3 -4
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +16 -2
- package/lib/dependencies/HtmlEntryDependency.js +74 -102
- package/lib/dependencies/HtmlInlineScriptDependency.js +3 -4
- package/lib/dependencies/HtmlInlineStyleDependency.js +3 -4
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/ImportMetaGlobHelpers.js +1 -1
- package/lib/dependencies/ImportMetaPlugin.js +8 -10
- package/lib/dependencies/ImportParserPlugin.js +1 -1
- package/lib/dependencies/LoaderPlugin.js +26 -1
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/URLContextDependency.js +1 -1
- package/lib/dependencies/URLDependency.js +6 -5
- package/lib/dependencies/WorkerAndWorkletPlugin.js +15 -21
- package/lib/dependencies/WorkerDependency.js +6 -5
- package/lib/dependencies/WorkletDependency.js +6 -9
- package/lib/errors/HookWebpackError.js +3 -2
- package/lib/hmr/LazyCompilationPlugin.js +3 -5
- package/lib/html/HtmlGenerator.js +61 -82
- package/lib/html/HtmlModulesPlugin.js +88 -139
- package/lib/html/HtmlParser.js +97 -141
- package/lib/html/data.js +21 -0
- package/lib/html/htmlMinify.js +10 -11
- package/lib/html/syntax.js +883 -993
- package/lib/index.js +46 -3
- package/lib/javascript/ChunkFormatHelpers.js +4 -3
- package/lib/javascript/JavascriptGenerator.js +8 -1
- package/lib/javascript/JavascriptModulesPlugin.js +21 -48
- package/lib/javascript/JavascriptParser.js +721 -178
- package/lib/javascript/parser.js +6 -0
- package/lib/javascript/syntax.js +420 -92
- package/lib/json/JsonGenerator.js +7 -1
- package/lib/library/ModuleLibraryPlugin.js +64 -136
- package/lib/loaders/LoaderRunner.js +137 -9
- package/lib/node/NodeWatchFileSystem.js +3 -9
- package/lib/optimize/AggressiveMergingPlugin.js +3 -5
- package/lib/optimize/ConcatenatedModule.js +81 -100
- package/lib/optimize/FlagIncludedChunksPlugin.js +3 -11
- package/lib/optimize/InnerGraphPlugin.js +7 -13
- package/lib/optimize/LimitChunkCountPlugin.js +5 -8
- package/lib/optimize/MangleExportsPlugin.js +3 -4
- package/lib/optimize/ModuleConcatenationPlugin.js +3 -4
- package/lib/optimize/SideEffectsFlagPlugin.js +7 -19
- package/lib/optimize/SplitChunksPlugin.js +2 -4
- package/lib/performance/BroadContextsPlugin.js +1 -1
- package/lib/performance/CacheEffectivenessPlugin.js +3 -4
- package/lib/performance/SizeLimitsPlugin.js +2 -4
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +6 -8
- package/lib/prefetch/ResourceHintPlugin.js +17 -21
- package/lib/prefetch/StartupAssetHintRuntimeModule.js +7 -10
- package/lib/runtime/AsyncModuleRuntimeModule.js +3 -5
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -4
- package/lib/runtime/GlobalRuntimeModule.js +2 -4
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +55 -85
- package/lib/schemes/DataUriPlugin.js +3 -6
- package/lib/schemes/VirtualUrlPlugin.js +1 -1
- package/lib/serialization/BinaryMiddleware.js +9 -9
- package/lib/serialization/FileMiddleware.js +16 -16
- package/lib/serialization/ObjectMiddleware.js +30 -33
- package/lib/stats/DefaultStatsFactoryPlugin.js +3 -4
- package/lib/typescript/TypeScriptPlugin.js +2 -3
- package/lib/url/URLParserPlugin.js +6 -8
- package/lib/util/LocConverter.js +4 -7
- package/lib/util/SourceProcessor.js +15 -22
- package/lib/util/chainedImports.js +3 -4
- package/lib/util/concatenate.js +4 -4
- package/lib/util/createHooksRegistry.js +1 -2
- package/lib/util/dataURL.js +2 -3
- package/lib/util/deterministicGrouping.js +8 -13
- package/lib/util/findGraphRoots.js +6 -13
- package/lib/util/globUtils.js +1 -1
- package/lib/util/hash/wasm-hash.js +3 -4
- package/lib/util/internalSerializables.js +1 -1
- package/lib/util/semver.js +5 -3
- package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -1
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -1
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +3 -4
- package/lib/wasm-sync/WebAssemblyGenerator.js +6 -1
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -1
- package/lib/wasm-sync/WebAssemblyUtils.js +2 -4
- package/package.json +30 -23
- package/types.d.ts +299 -280
|
@@ -148,10 +148,9 @@ const createCompilationHooks = () => ({
|
|
|
148
148
|
|
|
149
149
|
const PLUGIN_NAME = "HtmlModulesPlugin";
|
|
150
150
|
|
|
151
|
-
// Built-in default favicon
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
// Resolved from `__filename` (a sibling of this module) — no `path` needed.
|
|
151
|
+
// Built-in default favicon, referenced as a `file:` request so the wrapper's
|
|
152
|
+
// `<link rel="icon">` flows through the normal asset pipeline: emitted hashed,
|
|
153
|
+
// with the right publicPath and no direct IO.
|
|
155
154
|
const DEFAULT_FAVICON = new URL("./favicon.svg", pathToFileURL(__filename))
|
|
156
155
|
.href;
|
|
157
156
|
|
|
@@ -506,10 +505,9 @@ class HtmlModulesPlugin {
|
|
|
506
505
|
// several entries, so those can only be applied per emitted asset.
|
|
507
506
|
/** @type {Map<string, OutputHtmlOptions>} */
|
|
508
507
|
const htmlOptionsByEntry = new Map();
|
|
509
|
-
// SRI sentinels are emitted
|
|
510
|
-
//
|
|
511
|
-
//
|
|
512
|
-
// `.html` pages never reach the entry hook, hence the global seed.
|
|
508
|
+
// SRI sentinels are emitted before the owning entry is known, so one page
|
|
509
|
+
// asking for integrity turns them on for all and the rest drop them on emit.
|
|
510
|
+
// Authored `.html` pages never reach the entry hook, hence the global seed.
|
|
513
511
|
let anyIntegrity = isIntegrityEnabled(
|
|
514
512
|
globalHtmlOptions && globalHtmlOptions.integrity
|
|
515
513
|
);
|
|
@@ -542,13 +540,9 @@ class HtmlModulesPlugin {
|
|
|
542
540
|
return options;
|
|
543
541
|
};
|
|
544
542
|
|
|
545
|
-
// `output.html`
|
|
546
|
-
//
|
|
547
|
-
//
|
|
548
|
-
// injected first so the page loads the shared/runtime chunks before
|
|
549
|
-
// the entry's own (see `collectHtmlEntryRequests`). `crossOriginLoading`
|
|
550
|
-
// and SRI are applied to the injected tags centrally in
|
|
551
|
-
// HtmlEntryDependency.
|
|
543
|
+
// `output.html` wraps a non-HTML entry in a synthetic HTML module, so the
|
|
544
|
+
// existing pipeline injects its chunks. `dependOn` ancestors go first, so the
|
|
545
|
+
// page loads shared and runtime chunks before the entry's own.
|
|
552
546
|
EntryOptionPlugin.getHooks(compiler).entry.tap(
|
|
553
547
|
PLUGIN_NAME,
|
|
554
548
|
(context, name, desc) => {
|
|
@@ -623,19 +617,15 @@ class HtmlModulesPlugin {
|
|
|
623
617
|
/** @type {Map<string, { content: string, source: import("webpack-sources").RawSource }>} */
|
|
624
618
|
const sentinelResolvedSourceCache = new Map();
|
|
625
619
|
|
|
626
|
-
//
|
|
627
|
-
//
|
|
628
|
-
// and
|
|
629
|
-
//
|
|
630
|
-
//
|
|
631
|
-
//
|
|
632
|
-
//
|
|
633
|
-
//
|
|
634
|
-
//
|
|
635
|
-
// Per-compilation state: the HTML modules seen during make (so
|
|
636
|
-
// `finishMake` creates their entries without scanning the whole module
|
|
637
|
-
// graph), the stylesheet entry names (read in `afterChunks`) and the html
|
|
638
|
-
// options of every emitted page, keyed by its asset name.
|
|
620
|
+
// WHY: the `script` and `script-module` groups are chained through a
|
|
621
|
+
// leader-only `dependOn`, so they share a runtime: the group's first entry
|
|
622
|
+
// owns it and every later one sets `dependOn: [leader]`. A modulepreload
|
|
623
|
+
// entry is emitted independently, with no `dependOn`, so a later script can
|
|
624
|
+
// never import it as a runtime leader — which is what keeps the "preload but
|
|
625
|
+
// don't execute" contract of `<link rel="modulepreload">` intact.
|
|
626
|
+
// Per-compilation state: the HTML modules seen during make, so `finishMake`
|
|
627
|
+
// creates their entries without scanning the module graph, plus the
|
|
628
|
+
// stylesheet entry names and each emitted page's html options.
|
|
639
629
|
/** @type {WeakMap<import("../Compilation"), { htmlModules: Set<Module>, stylesheetEntries: Set<string>, pendingNames: Map<string, PendingName>, htmlAssetOptions: Map<string, OutputHtmlOptions> }>} */
|
|
640
630
|
const compilationState = new WeakMap();
|
|
641
631
|
/**
|
|
@@ -665,11 +655,9 @@ class HtmlModulesPlugin {
|
|
|
665
655
|
/** @type {Map<string, Module>} */
|
|
666
656
|
const linkedPages = new Map();
|
|
667
657
|
|
|
668
|
-
// Collect the entries an HTML module asks for. Only the script chains
|
|
669
|
-
//
|
|
670
|
-
//
|
|
671
|
-
// independent entries (a CSS or page entry must not chain into a JS
|
|
672
|
-
// leader, or the chunk would mix unrelated outputs).
|
|
658
|
+
// Collect the entries an HTML module asks for. Only the script chains share
|
|
659
|
+
// a runtime, through a leader-only `dependOn`; chaining a CSS or page entry
|
|
660
|
+
// into a JS leader would mix unrelated outputs into one chunk.
|
|
673
661
|
/** @type {(module: Module) => { context: string, request: string, name: string, dependOn: string[] | undefined }[]} */
|
|
674
662
|
const collectEntrySpecs = (module) => {
|
|
675
663
|
const { htmlEntries } = /** @type {HtmlModuleBuildInfo} */ (
|
|
@@ -808,10 +796,9 @@ class HtmlModulesPlugin {
|
|
|
808
796
|
})
|
|
809
797
|
);
|
|
810
798
|
};
|
|
811
|
-
// Seed with the HTML modules seen during make
|
|
812
|
-
//
|
|
813
|
-
//
|
|
814
|
-
// order, which the names must not depend on.
|
|
799
|
+
// Seed with the HTML modules seen during make; linked pages are reached by
|
|
800
|
+
// the recursion above. Sorted because they are tracked in build-completion
|
|
801
|
+
// order, which the generated names must not depend on.
|
|
815
802
|
const seeds = [...htmlModules].sort(compareModulesByIdentifier);
|
|
816
803
|
Promise.all(seeds.map(processEntry)).then(() => {
|
|
817
804
|
/** @type {Set<Module>} */
|
|
@@ -822,12 +809,11 @@ class HtmlModulesPlugin {
|
|
|
822
809
|
});
|
|
823
810
|
|
|
824
811
|
// `csp` injects a `<meta http-equiv="Content-Security-Policy">` and
|
|
825
|
-
// `integrity` resolves the SRI sentinels
|
|
826
|
-
// content is final
|
|
827
|
-
|
|
828
|
-
// `"auto"` marks implicit enablement
|
|
829
|
-
//
|
|
830
|
-
// (e.g. html-webpack-plugin's template loader in its child compiler).
|
|
812
|
+
// `integrity` resolves the SRI sentinels, both per page once its inline
|
|
813
|
+
// content is final, so an entry's `html` can override them.
|
|
814
|
+
|
|
815
|
+
// `"auto"` marks implicit enablement, the one case where loaders win over
|
|
816
|
+
// the built-in type — see `applyExperimentsDefaults`.
|
|
831
817
|
// TODO webpack 6: html defaults to `true`, drop this implicit-only fallback.
|
|
832
818
|
const implicitlyEnabled = compiler.options.experiments.html === "auto";
|
|
833
819
|
compiler.hooks.compilation.tap(
|
|
@@ -860,13 +846,12 @@ class HtmlModulesPlugin {
|
|
|
860
846
|
compilation.hooks.succeedModule.tap(PLUGIN_NAME, trackHtmlModule);
|
|
861
847
|
compilation.hooks.stillValidModule.tap(PLUGIN_NAME, trackHtmlModule);
|
|
862
848
|
|
|
863
|
-
// Resolve integrity and inline sentinels after `RealContentHashPlugin
|
|
864
|
-
// so final bytes are in place. Only HTML pages carry
|
|
865
|
-
|
|
866
|
-
// SRI
|
|
867
|
-
//
|
|
868
|
-
//
|
|
869
|
-
// so a CDN deployment doesn't ship no-op integrity attributes.
|
|
849
|
+
// Resolve integrity and inline sentinels after `RealContentHashPlugin`,
|
|
850
|
+
// so final bytes are in place. Only HTML pages carry them.
|
|
851
|
+
|
|
852
|
+
// SRI takes effect only on a cross-origin subresource fetched with CORS,
|
|
853
|
+
// so without `output.crossOriginLoading` the browser ignores `integrity`.
|
|
854
|
+
// Warn once, rather than let a CDN deployment ship no-op attributes.
|
|
870
855
|
if (anyIntegrity && !compilation.outputOptions.crossOriginLoading) {
|
|
871
856
|
compilation.warnings.push(
|
|
872
857
|
new WebpackError(
|
|
@@ -912,12 +897,9 @@ class HtmlModulesPlugin {
|
|
|
912
897
|
inlinedFiles
|
|
913
898
|
);
|
|
914
899
|
}
|
|
915
|
-
// `injectTags
|
|
916
|
-
//
|
|
917
|
-
//
|
|
918
|
-
// render every edit — placement, attribute rewrites, moves,
|
|
919
|
-
// removals, CSP hashes/nonce/meta — in one pass. Injected inline
|
|
920
|
-
// `<script>`/`<style>` are hashed like the page's own.
|
|
900
|
+
// `injectTags`, `transformTags` and CSP all run over a single parse:
|
|
901
|
+
// collect the tags and anchors once, let the hooks act, then render
|
|
902
|
+
// every edit in one pass.
|
|
921
903
|
const injected = await hooks.injectTags.promise([], {
|
|
922
904
|
outputName: name,
|
|
923
905
|
html: resolved
|
|
@@ -991,14 +973,9 @@ class HtmlModulesPlugin {
|
|
|
991
973
|
}
|
|
992
974
|
);
|
|
993
975
|
|
|
994
|
-
//
|
|
995
|
-
//
|
|
996
|
-
//
|
|
997
|
-
// Compilation only flows `options.filename` to `chunk.filenameTemplate`,
|
|
998
|
-
// which controls JS emit — there's no entry-level `cssFilename`.
|
|
999
|
-
// Set it ourselves after chunks are created so each stylesheet
|
|
1000
|
-
// entry emits to a distinct file derived from `output.cssFilename`
|
|
1001
|
-
// (or `output.cssChunkFilename` for non-initial CSS chunks).
|
|
976
|
+
// There is no entry-level `cssFilename`: Compilation flows
|
|
977
|
+
// `options.filename` only to `chunk.filenameTemplate`, which drives JS
|
|
978
|
+
// emit. So set `chunk.cssFilenameTemplate` here, once chunks exist.
|
|
1002
979
|
compilation.hooks.afterChunks.tap(PLUGIN_NAME, () => {
|
|
1003
980
|
const { stylesheetEntries, pendingNames } = getState(compilation);
|
|
1004
981
|
if (pendingNames.size === 0) return;
|
|
@@ -1057,10 +1034,9 @@ class HtmlModulesPlugin {
|
|
|
1057
1034
|
StaticExportsDependency,
|
|
1058
1035
|
new StaticExportsDependency.Template()
|
|
1059
1036
|
);
|
|
1060
|
-
// `ConstDependency`
|
|
1061
|
-
// `
|
|
1062
|
-
//
|
|
1063
|
-
// generator runs the insertion.
|
|
1037
|
+
// HtmlParser uses `ConstDependency` to insert ` type="module"` into a
|
|
1038
|
+
// rewritten `<script>` under `output.module`; its template has to be
|
|
1039
|
+
// registered for the HTML generator to run that insertion.
|
|
1064
1040
|
compilation.dependencyTemplates.set(
|
|
1065
1041
|
ConstDependency,
|
|
1066
1042
|
new ConstDependency.Template()
|
|
@@ -1092,10 +1068,9 @@ class HtmlModulesPlugin {
|
|
|
1092
1068
|
HtmlEntryDependency,
|
|
1093
1069
|
new HtmlEntryDependency.Template()
|
|
1094
1070
|
);
|
|
1095
|
-
// Inline `<script>` content
|
|
1096
|
-
//
|
|
1097
|
-
//
|
|
1098
|
-
// template rewrites the original tag to `<script src=…>`.
|
|
1071
|
+
// Inline `<script>` content becomes its own entry through a
|
|
1072
|
+
// `data:text/javascript,...` request, the same pipeline as
|
|
1073
|
+
// `<script src>`; the template then rewrites the tag.
|
|
1099
1074
|
compilation.dependencyFactories.set(
|
|
1100
1075
|
HtmlInlineScriptDependency,
|
|
1101
1076
|
normalModuleFactory
|
|
@@ -1104,11 +1079,9 @@ class HtmlModulesPlugin {
|
|
|
1104
1079
|
HtmlInlineScriptDependency,
|
|
1105
1080
|
new HtmlInlineScriptDependency.Template()
|
|
1106
1081
|
);
|
|
1107
|
-
// Inline `<style>` content
|
|
1108
|
-
//
|
|
1109
|
-
//
|
|
1110
|
-
// generation data (`css-text` channel set by CssGenerator
|
|
1111
|
-
// when `exportType` is `"text"`).
|
|
1082
|
+
// Inline `<style>` content goes through the CSS pipeline as a
|
|
1083
|
+
// `data:text/css` module; the template reads the processed text
|
|
1084
|
+
// from the `css-text` code-generation channel.
|
|
1112
1085
|
compilation.dependencyFactories.set(
|
|
1113
1086
|
HtmlInlineStyleDependency,
|
|
1114
1087
|
normalModuleFactory
|
|
@@ -1178,10 +1151,9 @@ class HtmlModulesPlugin {
|
|
|
1178
1151
|
(result, module) => {
|
|
1179
1152
|
if (module.type === HTML_MODULE_TYPE) {
|
|
1180
1153
|
const [source, ...rest] = removeBOMFromResult(result);
|
|
1181
|
-
//
|
|
1182
|
-
//
|
|
1183
|
-
//
|
|
1184
|
-
// and the generator's render base in sync.
|
|
1154
|
+
// Run here, where the returned source becomes the module's stored
|
|
1155
|
+
// source, so the parser's dependency offsets and the generator's
|
|
1156
|
+
// render base stay in sync.
|
|
1185
1157
|
const parser = /** @type {HtmlParser} */ (module.parser);
|
|
1186
1158
|
|
|
1187
1159
|
return [parser.applyTemplate(source, module), ...rest];
|
|
@@ -1191,35 +1163,20 @@ class HtmlModulesPlugin {
|
|
|
1191
1163
|
}
|
|
1192
1164
|
);
|
|
1193
1165
|
|
|
1194
|
-
//
|
|
1195
|
-
//
|
|
1196
|
-
// `
|
|
1197
|
-
//
|
|
1198
|
-
//
|
|
1199
|
-
//
|
|
1200
|
-
//
|
|
1201
|
-
//
|
|
1202
|
-
//
|
|
1203
|
-
//
|
|
1204
|
-
|
|
1205
|
-
// `
|
|
1206
|
-
//
|
|
1207
|
-
//
|
|
1208
|
-
// intentionally omitted so `[name]` resolves to the HTML
|
|
1209
|
-
// source's basename (e.g. `page` for `./page.html`) rather
|
|
1210
|
-
// than the importing chunk's name (e.g. `main`). A per-module
|
|
1211
|
-
// content hash is computed from the rewritten HTML so the
|
|
1212
|
-
// template's `[contenthash]` placeholder works; the
|
|
1213
|
-
// compilation hash is also forwarded so `[fullhash]` /
|
|
1214
|
-
// `[hash]` work in user-supplied templates.
|
|
1215
|
-
|
|
1216
|
-
// Sentinel-resolved content and its content hash depend only on
|
|
1217
|
-
// the HTML-type module source — not on the chunk or output
|
|
1218
|
-
// filename — yet `renderManifest` runs per `(chunk, module)`.
|
|
1219
|
-
// Memoize so a module landing in multiple chunks resolves and
|
|
1220
|
-
// hashes its sentinels once. Scoped to this compilation because
|
|
1221
|
-
// sentinel resolution embeds chunk filenames, which change
|
|
1222
|
-
// across rebuilds; weakly keyed by source so entries release.
|
|
1166
|
+
// WHY: emit extracted `.html` files for any HTML module that opted in.
|
|
1167
|
+
// `HtmlGenerator#_shouldExtract` computes that opt-in —
|
|
1168
|
+
// `module.generator.html.extract: true` always extracts, `false` never,
|
|
1169
|
+
// and unset extracts only a compilation entry — and the iteration below
|
|
1170
|
+
// picks up only modules whose generator reported the `html` source type,
|
|
1171
|
+
// so that decision is honoured implicitly. The filename comes from
|
|
1172
|
+
// `output.htmlFilename` for initial chunks and `output.htmlChunkFilename`
|
|
1173
|
+
// otherwise, mirroring the CSS pipeline, and the path data follows the
|
|
1174
|
+
// asset-module pattern with `chunk` deliberately left out, so `[name]`
|
|
1175
|
+
// resolves to the HTML source's basename rather than the chunk's.
|
|
1176
|
+
|
|
1177
|
+
// `renderManifest` runs per `(chunk, module)`, but resolved content and
|
|
1178
|
+
// its hash depend only on the module source, so memoize. Scoped to this
|
|
1179
|
+
// compilation, since resolution embeds chunk filenames.
|
|
1223
1180
|
/** @type {WeakMap<import("webpack-sources").Source, { resolvedContent: string, contentHash: string }>} */
|
|
1224
1181
|
const resolvedSentinelHashCache = new WeakMap();
|
|
1225
1182
|
|
|
@@ -1241,15 +1198,12 @@ class HtmlModulesPlugin {
|
|
|
1241
1198
|
if (!placeholderSource) return undefined;
|
|
1242
1199
|
let cached = resolvedSentinelHashCache.get(placeholderSource);
|
|
1243
1200
|
if (cached === undefined) {
|
|
1244
|
-
// Resolve chunk-URL sentinels
|
|
1245
|
-
// `[contenthash]`
|
|
1246
|
-
//
|
|
1247
|
-
|
|
1248
|
-
//
|
|
1249
|
-
//
|
|
1250
|
-
// Asset URL sentinels (from `HtmlEntryDependency` resource-hint
|
|
1251
|
-
// tags) resolve here too — deferred from template.apply so it
|
|
1252
|
-
// doesn't race with asset-module codegen.
|
|
1201
|
+
// Resolve chunk-URL sentinels before hashing, so the page's
|
|
1202
|
+
// `[contenthash]` tracks the referenced chunks. An inlined chunk has
|
|
1203
|
+
// no URL, so its sentinel carries the chunk content hash instead.
|
|
1204
|
+
|
|
1205
|
+
// Asset URL sentinels resolve here rather than in `template.apply`,
|
|
1206
|
+
// which would race with asset-module codegen.
|
|
1253
1207
|
const resolvedContent = getHtmlGenerator().resolveAssetUrlSentinels(
|
|
1254
1208
|
getHtmlGenerator().embedInlineChunkHashes(
|
|
1255
1209
|
getHtmlGenerator().resolveChunkUrlSentinels(
|
|
@@ -1345,9 +1299,8 @@ class HtmlModulesPlugin {
|
|
|
1345
1299
|
compilation.hooks.renderManifest.tap(
|
|
1346
1300
|
PLUGIN_NAME,
|
|
1347
1301
|
(result, { chunk }) => {
|
|
1348
|
-
// HMR's `HotUpdateChunk`s
|
|
1349
|
-
//
|
|
1350
|
-
// for them would create stray hot-update HTML files.
|
|
1302
|
+
// HMR's `HotUpdateChunk`s reach this hook but are not output chunks,
|
|
1303
|
+
// so extracting `.html` for them would emit stray hot-update files.
|
|
1351
1304
|
// `CssModulesPlugin` early-returns for the same reason.
|
|
1352
1305
|
if (chunk instanceof HotUpdateChunk) return result;
|
|
1353
1306
|
const { chunkGraph } = compilation;
|
|
@@ -1361,12 +1314,13 @@ class HtmlModulesPlugin {
|
|
|
1361
1314
|
const outputOptions = compilation.outputOptions;
|
|
1362
1315
|
for (const module of modules) {
|
|
1363
1316
|
const normalModule = /** @type {NormalModule} */ (module);
|
|
1364
|
-
// `<iframe srcdoc>`
|
|
1365
|
-
// can write the processed markup back
|
|
1366
|
-
//
|
|
1367
|
-
//
|
|
1368
|
-
//
|
|
1369
|
-
//
|
|
1317
|
+
// WHY: an `<iframe srcdoc>` module exposes `html` only so that
|
|
1318
|
+
// `HtmlInlineHtmlDependency` can write the processed markup back
|
|
1319
|
+
// into the host attribute; it is never a standalone page.
|
|
1320
|
+
// `generator.extract: "inline"` marks it so no `.html` file is
|
|
1321
|
+
// emitted — without it they would collide on the `data:text/html`
|
|
1322
|
+
// to chunk-name path, every srcdoc module in a chunk emitting
|
|
1323
|
+
// `<chunk>.html`. An O(1) flag check rather than a scan.
|
|
1370
1324
|
const generatorOptions = normalModule.generatorOptions;
|
|
1371
1325
|
if (generatorOptions && generatorOptions.extract === "inline") {
|
|
1372
1326
|
continue;
|
|
@@ -1376,11 +1330,9 @@ class HtmlModulesPlugin {
|
|
|
1376
1330
|
if (!emit) continue;
|
|
1377
1331
|
const { resolvedContent, contentHash, filename, info } = emit;
|
|
1378
1332
|
|
|
1379
|
-
// Resolve
|
|
1380
|
-
//
|
|
1381
|
-
//
|
|
1382
|
-
// a subdirectory. A relative `<base href>` prepends `../`s so the
|
|
1383
|
-
// base can't misdirect the rewritten URLs (see `HtmlParser`).
|
|
1333
|
+
// Resolve the remaining `[webpack/auto]` placeholders against the
|
|
1334
|
+
// emitted page's own location, so URLs stay relative to `output.path`
|
|
1335
|
+
// from a subdirectory. A relative `<base href>` prepends `../`s.
|
|
1384
1336
|
const basePrefix =
|
|
1385
1337
|
/** @type {HtmlModuleBuildInfo} */ (normalModule.buildInfo)
|
|
1386
1338
|
.baseUrlPrefix || "";
|
|
@@ -1402,12 +1354,9 @@ class HtmlModulesPlugin {
|
|
|
1402
1354
|
.split(autoPlaceholder)
|
|
1403
1355
|
.join(undoPath);
|
|
1404
1356
|
const finalSource = new RawSource(finalContent);
|
|
1405
|
-
//
|
|
1406
|
-
//
|
|
1407
|
-
//
|
|
1408
|
-
// the asset cache key and the post-undo-path content in the hash so the
|
|
1409
|
-
// asset cache can't reuse one variant's bytes at another variant's URL.
|
|
1410
|
-
// Unchanged content reuses the memoized hash instead of re-digesting.
|
|
1357
|
+
// One module can land in several chunks whose filename shapes give
|
|
1358
|
+
// different undo paths, so the emitted filename joins the cache key
|
|
1359
|
+
// and the post-undo content the hash — else variants alias.
|
|
1411
1360
|
const finalContentHash =
|
|
1412
1361
|
finalContent === resolvedContent
|
|
1413
1362
|
? contentHash
|