webpack 5.111.0 → 5.111.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/APIPlugin.js +3 -4
- package/lib/CompatibilityPlugin.js +3 -4
- package/lib/Compilation.js +16 -35
- package/lib/Compiler.js +4 -5
- package/lib/ConstPlugin.js +16 -132
- package/lib/DependencyTemplate.js +2 -1
- package/lib/DotenvPlugin.js +24 -28
- package/lib/ErrorHelpers.js +113 -0
- package/lib/ExportsInfo.js +20 -16
- package/lib/ExternalModule.js +6 -8
- package/lib/FlagDependencyExportsPlugin.js +8 -13
- package/lib/FlagDependencyUsagePlugin.js +9 -13
- package/lib/Generator.js +24 -2
- package/lib/HotModuleReplacementPlugin.js +2 -0
- package/lib/IgnorePlugin.js +1 -1
- package/lib/LoaderOptionsPlugin.js +1 -1
- package/lib/Module.js +3 -3
- package/lib/ModuleGraph.js +6 -9
- package/lib/MultiCompiler.js +6 -16
- package/lib/NormalModule.js +96 -44
- package/lib/RuntimeTemplate.js +33 -43
- package/lib/SourceMapDevToolPlugin.js +53 -103
- package/lib/TemplatedPathPlugin.js +16 -59
- package/lib/asset/AssetBytesGenerator.js +7 -1
- package/lib/asset/AssetGenerator.js +25 -16
- package/lib/asset/AssetSourceGenerator.js +7 -1
- package/lib/buildChunkGraph.js +11 -15
- package/lib/cache/MemoryCachePlugin.js +4 -4
- package/lib/cache/MemoryWithGcCachePlugin.js +7 -8
- package/lib/cache/PackFileCacheStrategy.js +3 -18
- package/lib/cache/getLazyHashedEtag.js +3 -5
- package/lib/config/browserslistTargetHandler.js +2 -8
- package/lib/config/defaults.js +52 -78
- package/lib/config/getClaimedAssetTypes.js +10 -11
- package/lib/config/target.js +3 -4
- package/lib/{ContextExclusionPlugin.js → context/ContextExclusionPlugin.js} +1 -1
- package/lib/{ContextModule.js → context/ContextModule.js} +37 -34
- package/lib/{ContextModuleFactory.js → context/ContextModuleFactory.js} +19 -21
- package/lib/{ContextReplacementPlugin.js → context/ContextReplacementPlugin.js} +4 -4
- package/lib/css/CssGenerator.js +19 -11
- package/lib/css/CssParser.js +18 -20
- package/lib/css/cssMinify.js +32 -29
- package/lib/css/data.js +797 -288
- package/lib/css/syntax.js +2250 -934
- package/lib/debug/ProfilingPlugin.js +3 -4
- package/lib/dependencies/CommonJsExportRequireDependency.js +10 -11
- package/lib/dependencies/CommonJsImportsParserPlugin.js +4 -5
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +2 -4
- package/lib/dependencies/ContextDependency.js +1 -1
- package/lib/dependencies/ContextDependencyHelpers.js +3 -9
- package/lib/dependencies/ContextElementDependency.js +1 -1
- package/lib/dependencies/CssIcssExportDependency.js +6 -8
- package/lib/dependencies/CssIcssImportDependency.js +3 -6
- package/lib/dependencies/CssUrlDependency.js +3 -5
- package/lib/dependencies/HarmonyCompatibilityDependency.js +11 -20
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +3 -4
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +2 -4
- package/lib/dependencies/HarmonyExportExpressionDependency.js +3 -4
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +3 -4
- package/lib/dependencies/HarmonyExportInitFragment.js +26 -19
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +7 -28
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +103 -16
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +3 -4
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +16 -2
- package/lib/dependencies/HtmlEntryDependency.js +74 -102
- package/lib/dependencies/HtmlInlineScriptDependency.js +3 -4
- package/lib/dependencies/HtmlInlineStyleDependency.js +3 -4
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/ImportMetaGlobHelpers.js +1 -1
- package/lib/dependencies/ImportMetaPlugin.js +8 -10
- package/lib/dependencies/ImportParserPlugin.js +1 -1
- package/lib/dependencies/LoaderPlugin.js +26 -1
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +1 -1
- package/lib/dependencies/URLContextDependency.js +1 -1
- package/lib/dependencies/URLDependency.js +6 -5
- package/lib/dependencies/WorkerAndWorkletPlugin.js +15 -21
- package/lib/dependencies/WorkerDependency.js +6 -5
- package/lib/dependencies/WorkletDependency.js +6 -9
- package/lib/errors/HookWebpackError.js +3 -2
- package/lib/hmr/LazyCompilationPlugin.js +3 -5
- package/lib/html/HtmlGenerator.js +61 -82
- package/lib/html/HtmlModulesPlugin.js +88 -139
- package/lib/html/HtmlParser.js +97 -141
- package/lib/html/data.js +21 -0
- package/lib/html/htmlMinify.js +10 -11
- package/lib/html/syntax.js +883 -993
- package/lib/index.js +46 -3
- package/lib/javascript/ChunkFormatHelpers.js +4 -3
- package/lib/javascript/JavascriptGenerator.js +8 -1
- package/lib/javascript/JavascriptModulesPlugin.js +21 -48
- package/lib/javascript/JavascriptParser.js +721 -178
- package/lib/javascript/parser.js +6 -0
- package/lib/javascript/syntax.js +420 -92
- package/lib/json/JsonGenerator.js +7 -1
- package/lib/library/ModuleLibraryPlugin.js +64 -136
- package/lib/loaders/LoaderRunner.js +137 -9
- package/lib/node/NodeWatchFileSystem.js +3 -9
- package/lib/optimize/AggressiveMergingPlugin.js +3 -5
- package/lib/optimize/ConcatenatedModule.js +81 -100
- package/lib/optimize/FlagIncludedChunksPlugin.js +3 -11
- package/lib/optimize/InnerGraphPlugin.js +7 -13
- package/lib/optimize/LimitChunkCountPlugin.js +5 -8
- package/lib/optimize/MangleExportsPlugin.js +3 -4
- package/lib/optimize/ModuleConcatenationPlugin.js +3 -4
- package/lib/optimize/SideEffectsFlagPlugin.js +7 -19
- package/lib/optimize/SplitChunksPlugin.js +2 -4
- package/lib/performance/BroadContextsPlugin.js +1 -1
- package/lib/performance/CacheEffectivenessPlugin.js +3 -4
- package/lib/performance/SizeLimitsPlugin.js +2 -4
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +6 -8
- package/lib/prefetch/ResourceHintPlugin.js +17 -21
- package/lib/prefetch/StartupAssetHintRuntimeModule.js +7 -10
- package/lib/runtime/AsyncModuleRuntimeModule.js +3 -5
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +3 -4
- package/lib/runtime/GlobalRuntimeModule.js +2 -4
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +55 -85
- package/lib/schemes/DataUriPlugin.js +3 -6
- package/lib/schemes/VirtualUrlPlugin.js +1 -1
- package/lib/serialization/BinaryMiddleware.js +9 -9
- package/lib/serialization/FileMiddleware.js +16 -16
- package/lib/serialization/ObjectMiddleware.js +30 -33
- package/lib/stats/DefaultStatsFactoryPlugin.js +3 -4
- package/lib/typescript/TypeScriptPlugin.js +2 -3
- package/lib/url/URLParserPlugin.js +6 -8
- package/lib/util/LocConverter.js +4 -7
- package/lib/util/SourceProcessor.js +15 -22
- package/lib/util/chainedImports.js +3 -4
- package/lib/util/concatenate.js +4 -4
- package/lib/util/createHooksRegistry.js +1 -2
- package/lib/util/dataURL.js +2 -3
- package/lib/util/deterministicGrouping.js +8 -13
- package/lib/util/findGraphRoots.js +6 -13
- package/lib/util/globUtils.js +1 -1
- package/lib/util/hash/wasm-hash.js +3 -4
- package/lib/util/internalSerializables.js +1 -1
- package/lib/util/semver.js +5 -3
- package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -1
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +5 -1
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +3 -4
- package/lib/wasm-sync/WebAssemblyGenerator.js +6 -1
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -1
- package/lib/wasm-sync/WebAssemblyUtils.js +2 -4
- package/package.json +30 -23
- package/types.d.ts +299 -280
package/lib/html/HtmlParser.js
CHANGED
|
@@ -90,10 +90,9 @@ const STYLE_ATTR_URL_REGEXP = /url\(|src\(|image\(|image-set\(/i;
|
|
|
90
90
|
// hold a `url(...)` FuncIRI. Most are plain colors/keywords (`#fff`, `red`).
|
|
91
91
|
const FUNC_IRI_URL_REGEXP = /url\(/i;
|
|
92
92
|
|
|
93
|
-
// Cheap pre-filter for `<iframe srcdoc
|
|
94
|
-
//
|
|
95
|
-
// `
|
|
96
|
-
// formatting/text markup (`<p>hi</p>`) rewrites to itself, so skip it.
|
|
93
|
+
// Cheap pre-filter for `<iframe srcdoc>`: a nested HTML module is only worth
|
|
94
|
+
// building when the markup can reference an asset — any attribute, a CSS
|
|
95
|
+
// `url(...)` or an `@import`. Pure text markup rewrites to itself.
|
|
97
96
|
const SRCDOC_ASSET_REGEXP = /[=]|url\(|@import/i;
|
|
98
97
|
|
|
99
98
|
// A URL carrying its own scheme (`https:`, `data:`, …) ignores the document
|
|
@@ -370,10 +369,9 @@ const isLinkStylesheet = (attributes) => {
|
|
|
370
369
|
*/
|
|
371
370
|
const dict = (...bags) => Object.assign(Object.create(null), ...bags);
|
|
372
371
|
|
|
373
|
-
//
|
|
374
|
-
//
|
|
375
|
-
//
|
|
376
|
-
// `parseSrcset` parser for it and otherwise treats it like `src`.
|
|
372
|
+
// One shared `SourceItem` per kind, so the walk's lookups stay on a single V8
|
|
373
|
+
// hidden class. `srcset` is its own type: the walk picks `parseSrcset` for it
|
|
374
|
+
// and otherwise treats it like `src`.
|
|
377
375
|
/** @type {SourceItem} */
|
|
378
376
|
const PLAIN_SRC = { type: "src", filter: undefined };
|
|
379
377
|
/** @type {SourceItem} */
|
|
@@ -389,10 +387,9 @@ const LINK_HREF = {
|
|
|
389
387
|
type: (attrs, css) => {
|
|
390
388
|
if (isLinkModulePreload(attrs)) return "modulepreload";
|
|
391
389
|
if (css && isLinkStylesheet(attrs)) return "stylesheet";
|
|
392
|
-
// `rel="preload"/"prefetch"` with `as="script"`
|
|
393
|
-
// `experiments.css`
|
|
394
|
-
//
|
|
395
|
-
// font, fetch, …) stay plain asset URLs.
|
|
390
|
+
// `rel="preload"/"prefetch"` with `as="script"` — or `as="style"` under
|
|
391
|
+
// `experiments.css` — becomes a non-executing entry pointing at the built
|
|
392
|
+
// chunk; every other `as` target stays a plain asset URL.
|
|
396
393
|
const rel = getAttributeValue(attrs, "rel");
|
|
397
394
|
if (rel) {
|
|
398
395
|
const rels = rel.trim().toLowerCase().split(/\s+/);
|
|
@@ -446,11 +443,9 @@ const META_CONTENT = {
|
|
|
446
443
|
filter: filterMetaContent
|
|
447
444
|
};
|
|
448
445
|
|
|
449
|
-
//
|
|
450
|
-
//
|
|
451
|
-
//
|
|
452
|
-
// the default `sources` config just references this table and pays
|
|
453
|
-
// zero per-parser work.
|
|
446
|
+
// Written in its final resolved shape, `[tag][attribute] = item`, rather than
|
|
447
|
+
// built from an array at module load: a parser on the default `sources` config
|
|
448
|
+
// references this table and pays nothing per instance.
|
|
454
449
|
/** @type {Record<string, Record<string, SourceItem>>} */
|
|
455
450
|
const DEFAULT_SOURCES_BY_TAG = dict({
|
|
456
451
|
// Obsolete Java-applet element; `code`/`object` are single class/object URLs.
|
|
@@ -489,13 +484,14 @@ const DEFAULT_SOURCES_BY_TAG = dict({
|
|
|
489
484
|
th: dict({ background: PLAIN_SRC }),
|
|
490
485
|
track: dict({ src: PLAIN_SRC }),
|
|
491
486
|
video: dict({ poster: PLAIN_SRC, src: PLAIN_SRC }),
|
|
492
|
-
// SVG. Tag names match the tree builder's adjusted camelCase
|
|
493
|
-
// (`feImage`/`textPath`/`linearGradient`/`radialGradient`). `href
|
|
494
|
-
// `xlink:href` reference another element
|
|
495
|
-
//
|
|
496
|
-
// `color-profile`'s `xlink:href` points at an external ICC profile
|
|
497
|
-
// `cursor
|
|
498
|
-
// `glyphRef
|
|
487
|
+
// WHY: SVG. Tag names match the tree builder's adjusted camelCase
|
|
488
|
+
// (`feImage`/`textPath`/`linearGradient`/`radialGradient`). `href` and
|
|
489
|
+
// `xlink:href` reference another element or resource, and a fragment-only
|
|
490
|
+
// `#id` value is left untouched, so only an external `file.svg#id` is
|
|
491
|
+
// rewritten. `color-profile`'s `xlink:href` points at an external ICC profile
|
|
492
|
+
// file; `cursor` and `font-face-uri` at an external image or font file; and
|
|
493
|
+
// `altGlyph`, `glyphRef` and `tref` are legacy element references, removed in
|
|
494
|
+
// SVG 2.
|
|
499
495
|
altGlyph: dict({ "xlink:href": PLAIN_SRC, href: PLAIN_SRC }),
|
|
500
496
|
"color-profile": dict({ "xlink:href": PLAIN_SRC, href: PLAIN_SRC }),
|
|
501
497
|
cursor: dict({ "xlink:href": PLAIN_SRC, href: PLAIN_SRC }),
|
|
@@ -515,11 +511,11 @@ const DEFAULT_SOURCES_BY_TAG = dict({
|
|
|
515
511
|
// clip-path, …) are handled separately during the walk (`parseCssUrls`).
|
|
516
512
|
});
|
|
517
513
|
|
|
518
|
-
// SVG presentation attributes (`fill`, `stroke`, …) carry CSS `url(...)`
|
|
519
|
-
// FuncIRIs
|
|
520
|
-
// `url(#id)`
|
|
521
|
-
// the item is `namespace`-gated rather than placed in a tag bucket
|
|
522
|
-
// is a cheap pre-check skipping the common plain values (`red`, `none
|
|
514
|
+
// WHY: SVG presentation attributes (`fill`, `stroke`, …) carry CSS `url(...)`
|
|
515
|
+
// FuncIRIs, whose external refs `parseCssUrls` extracts as assets, leaving an
|
|
516
|
+
// internal `url(#id)` untouched. They apply to every SVG-namespace element, so
|
|
517
|
+
// the item is `namespace`-gated rather than placed in a tag bucket, and the
|
|
518
|
+
// filter is a cheap pre-check skipping the common plain values (`red`, `none`).
|
|
523
519
|
/** @type {SourceItem} */
|
|
524
520
|
const SVG_CSS_URL = {
|
|
525
521
|
type: "css-url",
|
|
@@ -527,21 +523,18 @@ const SVG_CSS_URL = {
|
|
|
527
523
|
namespace: NS_SVG
|
|
528
524
|
};
|
|
529
525
|
|
|
530
|
-
// The global `style=""` attribute
|
|
531
|
-
//
|
|
532
|
-
//
|
|
533
|
-
// created); the filter is a cheap pre-check skipping declarations without a
|
|
534
|
-
// `url()`/`src()`/… .
|
|
526
|
+
// The global `style=""` attribute, available on every tag and even under
|
|
527
|
+
// `sources: false`. Like every `stylesheet-style*` source it only emits when
|
|
528
|
+
// `experiments.css` is on, checked where the dependency is created.
|
|
535
529
|
/** @type {SourceItem} */
|
|
536
530
|
const STYLE_ATTRIBUTE = {
|
|
537
531
|
type: "stylesheet-style-attribute",
|
|
538
532
|
filter: (attributes, value) => STYLE_ATTR_URL_REGEXP.test(value)
|
|
539
533
|
};
|
|
540
534
|
|
|
541
|
-
// Any-tag sources
|
|
542
|
-
//
|
|
543
|
-
//
|
|
544
|
-
// unless `sources: false`; only the always-on style attribute survives `false`.
|
|
535
|
+
// Any-tag sources, folded into each tag bucket so the walk resolves one object
|
|
536
|
+
// per element and one property per attribute. `sources: false` leaves only the
|
|
537
|
+
// always-on style attribute.
|
|
545
538
|
/** @type {Record<string, SourceItem>} */
|
|
546
539
|
const DEFAULT_ANY_SOURCES = dict({ style: STYLE_ATTRIBUTE });
|
|
547
540
|
for (const name of [
|
|
@@ -625,10 +618,9 @@ const styleContentFilter = (attrs) => {
|
|
|
625
618
|
return t === "" || t === "text/css";
|
|
626
619
|
};
|
|
627
620
|
|
|
628
|
-
// Element-body sources, independent of the `sources` option
|
|
629
|
-
//
|
|
630
|
-
//
|
|
631
|
-
// created, like every `stylesheet-style*` source).
|
|
621
|
+
// Element-body sources, independent of the `sources` option: a `<script>` body
|
|
622
|
+
// is always processed, while a `<style>` body only emits when `experiments.css`
|
|
623
|
+
// is on, checked where the dependency is created.
|
|
632
624
|
/** @type {Record<string, ContentSourceItem>} */
|
|
633
625
|
const CONTENT_SOURCES = dict({
|
|
634
626
|
script: { type: scriptContentType, filter: scriptContentFilter },
|
|
@@ -649,11 +641,9 @@ class HtmlParser extends Parser {
|
|
|
649
641
|
this.template = options.template;
|
|
650
642
|
/** @type {import("../../declarations/WebpackOptions").UrlHintRule[] | undefined} */
|
|
651
643
|
this._urlHints = options.urlHints;
|
|
652
|
-
// `as` selects the parse mode
|
|
653
|
-
//
|
|
654
|
-
//
|
|
655
|
-
// so context-sensitive tags (`<tr>`, `<td>`, `<option>`, …) in a partial
|
|
656
|
-
// are kept, not dropped. `"template"` is the neutral generic fragment.
|
|
644
|
+
// `as` selects the parse mode: `"document"` parses a full page, any other
|
|
645
|
+
// value names the context element whose inner HTML this is, so that a
|
|
646
|
+
// partial's `<tr>`, `<td>` or `<option>` is kept rather than dropped.
|
|
657
647
|
/** @type {string | undefined} */
|
|
658
648
|
this.fragmentContext =
|
|
659
649
|
options.as === undefined || options.as === "document"
|
|
@@ -673,13 +663,9 @@ class HtmlParser extends Parser {
|
|
|
673
663
|
return;
|
|
674
664
|
}
|
|
675
665
|
|
|
676
|
-
//
|
|
677
|
-
//
|
|
678
|
-
//
|
|
679
|
-
// `{ attribute: "data-style", type: "stylesheet-style-attribute" }`).
|
|
680
|
-
// User entries override regardless of position. `dict()` keeps every
|
|
681
|
-
// table null-prototype (see its doc), and per-tag writes rebuild the
|
|
682
|
-
// bucket so the aliased default buckets stay intact.
|
|
666
|
+
// `"..."` anywhere opts the per-tag defaults in as the base, and a user
|
|
667
|
+
// entry with no `tag` is an any-tag source; user entries override wherever
|
|
668
|
+
// they sit. Per-tag writes rebuild the bucket, so the defaults stay intact.
|
|
683
669
|
/** @type {SourceTable} */
|
|
684
670
|
const byTag = sources.includes("...")
|
|
685
671
|
? dict(DEFAULT_SOURCES_BY_TAG)
|
|
@@ -804,14 +790,9 @@ class HtmlParser extends Parser {
|
|
|
804
790
|
const css = Boolean(compilation.options.experiments.css);
|
|
805
791
|
const urlHints = this._urlHints;
|
|
806
792
|
|
|
807
|
-
//
|
|
808
|
-
//
|
|
809
|
-
//
|
|
810
|
-
// path (a plain absolute path) — going through `contextify` against
|
|
811
|
-
// the compilation root keeps the hash machine-stable for the same
|
|
812
|
-
// project layout. Note: `module.identifier()` returns `html|<path>`
|
|
813
|
-
// for HTML modules, which doesn't start with `/`, so contextify would
|
|
814
|
-
// leave it absolute. `module.resource` is the bare path.
|
|
793
|
+
// Per-module prefix keeping generated entry names from colliding across the
|
|
794
|
+
// HTML modules of one compilation. It hashes `module.resource` rather than
|
|
795
|
+
// `identifier()`, whose `html|` prefix `contextify` would leave absolute.
|
|
815
796
|
/** @type {string} */
|
|
816
797
|
const resource =
|
|
817
798
|
/** @type {EXPECTED_ANY} */ (module).resource || module.identifier();
|
|
@@ -820,11 +801,9 @@ class HtmlParser extends Parser {
|
|
|
820
801
|
.digest("hex")
|
|
821
802
|
.slice(0, 8);
|
|
822
803
|
|
|
823
|
-
// `output.html` head injection
|
|
824
|
-
//
|
|
825
|
-
//
|
|
826
|
-
// wrappers already carry the tags and iframe srcdoc pages must stay
|
|
827
|
-
// untouched.
|
|
804
|
+
// `output.html` head injection collects facts during the walk and turns
|
|
805
|
+
// them into presentational dependencies after, so no later pass re-parses
|
|
806
|
+
// the page. `data:` documents are skipped — they already carry the tags.
|
|
828
807
|
const htmlOutputOptions =
|
|
829
808
|
compilation.options && compilation.options.output
|
|
830
809
|
? compilation.options.output.html
|
|
@@ -846,10 +825,9 @@ class HtmlParser extends Parser {
|
|
|
846
825
|
let inHead = false;
|
|
847
826
|
// `<template>` contents are inert
|
|
848
827
|
let headTemplateDepth = 0;
|
|
849
|
-
// Depth of open `<template>` elements anywhere in the tree
|
|
850
|
-
//
|
|
851
|
-
//
|
|
852
|
-
// templates seen while in `<head>`, so it can't guard body templates).
|
|
828
|
+
// Depth of open `<template>` elements anywhere in the tree: their content
|
|
829
|
+
// is an inert fragment, so a `<base>` inside one must not set the document
|
|
830
|
+
// base. `headTemplateDepth` covers only `<head>`, so it cannot guard this.
|
|
853
831
|
let templateDepth = 0;
|
|
854
832
|
let headHasTitle = false;
|
|
855
833
|
let headHasBase = false;
|
|
@@ -857,13 +835,9 @@ class HtmlParser extends Parser {
|
|
|
857
835
|
/** @type {Set<string> | undefined} */
|
|
858
836
|
let headMetaNames;
|
|
859
837
|
|
|
860
|
-
//
|
|
861
|
-
//
|
|
862
|
-
//
|
|
863
|
-
// leader-only dependOn so they share a runtime.
|
|
864
|
-
// `<link rel="modulepreload">` entries are kept independent — they
|
|
865
|
-
// must preload without running, so they can never become a runtime
|
|
866
|
-
// leader that other entries would import.
|
|
838
|
+
// Collected per type during the walk; HtmlModulesPlugin turns them into
|
|
839
|
+
// entries. `script` and `script-module` chain through a leader-only
|
|
840
|
+
// dependOn; modulepreload stays independent, as it must not run.
|
|
867
841
|
/**
|
|
868
842
|
* @typedef {object} HtmlEntryInfo
|
|
869
843
|
* @property {string} request
|
|
@@ -892,28 +866,26 @@ class HtmlParser extends Parser {
|
|
|
892
866
|
/** @type {HtmlEntryInfo[]} */
|
|
893
867
|
const prefetchEntries = [];
|
|
894
868
|
|
|
895
|
-
// Offset of the first classic blocking script tag
|
|
896
|
-
// `<link>`s stay ahead of
|
|
897
|
-
//
|
|
898
|
-
// so CSS may follow their tags (the order Vite emits).
|
|
869
|
+
// Offset of the first classic blocking script tag, which injected stylesheet
|
|
870
|
+
// `<link>`s stay ahead of. `defer`/`async`/module scripts do not anchor: they
|
|
871
|
+
// run after parsing and after pending stylesheets.
|
|
899
872
|
let firstBlockingScriptStart = -1;
|
|
900
873
|
|
|
901
874
|
let nextEntryIndex = 0;
|
|
902
875
|
|
|
903
|
-
// `<base href>` resolves the relative URLs that follow it. A relative base
|
|
904
|
-
// (`./assets/`) rewrites them into a subdirectory
|
|
905
|
-
// root-relative or absolute
|
|
906
|
-
//
|
|
907
|
-
//
|
|
876
|
+
// WHY: `<base href>` resolves the relative URLs that follow it. A relative base
|
|
877
|
+
// (`./assets/`) rewrites them into a subdirectory and they stay bundled; a
|
|
878
|
+
// root-relative or absolute one (`/`, `https://cdn/`) points outside the
|
|
879
|
+
// build, so those URLs are left untouched. Resolved in the walk below from
|
|
880
|
+
// the first `<base href>` seen, `documentBase` being undefined until then.
|
|
908
881
|
/** @type {string | undefined} */
|
|
909
882
|
let documentBase;
|
|
910
883
|
/** @type {string | undefined} */
|
|
911
884
|
let baseDir;
|
|
912
885
|
let baseIsExternal = false;
|
|
913
|
-
// Prepended to the emitted URLs' auto-public-path undo path
|
|
914
|
-
//
|
|
915
|
-
//
|
|
916
|
-
// it. Undefined for absolute publicPath (no undo path is emitted).
|
|
886
|
+
// Prepended to the emitted URLs' auto-public-path undo path: the browser
|
|
887
|
+
// resolves them against the base dir, so one `../` per base segment cancels
|
|
888
|
+
// it. Undefined for an absolute publicPath, which emits no undo path.
|
|
917
889
|
/** @type {string | undefined} */
|
|
918
890
|
let baseUrlPrefix;
|
|
919
891
|
|
|
@@ -1017,10 +989,9 @@ class HtmlParser extends Parser {
|
|
|
1017
989
|
baseIsExternal = true;
|
|
1018
990
|
return;
|
|
1019
991
|
}
|
|
1020
|
-
// Normalize the base path into
|
|
1021
|
-
//
|
|
1022
|
-
//
|
|
1023
|
-
// dot-segment; `up` counts `..`s that climb above the document dir.
|
|
992
|
+
// Normalize the base path into descending directory segments, resolving
|
|
993
|
+
// `.`/`..` as the URL spec does. The final segment names a file and is
|
|
994
|
+
// dropped; `up` counts the `..`s climbing above the document dir.
|
|
1024
995
|
const parts = documentBase.split("/");
|
|
1025
996
|
/** @type {string[]} */
|
|
1026
997
|
const dirs = [];
|
|
@@ -1070,9 +1041,8 @@ class HtmlParser extends Parser {
|
|
|
1070
1041
|
};
|
|
1071
1042
|
|
|
1072
1043
|
// TODO implement full HTML parser (WASM)
|
|
1073
|
-
// The walker descends into children
|
|
1074
|
-
//
|
|
1075
|
-
// children are done (the old `walkChildren` behaviour).
|
|
1044
|
+
// The walker descends into children and `<template>` content itself, and the
|
|
1045
|
+
// Element `exit` clears a pending `webpackIgnore` once they are done.
|
|
1076
1046
|
new SourceProcessor()
|
|
1077
1047
|
.use({
|
|
1078
1048
|
[NodeType.Comment]: (path) => {
|
|
@@ -1220,9 +1190,8 @@ class HtmlParser extends Parser {
|
|
|
1220
1190
|
pendingWebpackIgnore = undefined;
|
|
1221
1191
|
pendingWebpackInline = undefined;
|
|
1222
1192
|
|
|
1223
|
-
// `<head>` anchors are collected for every page
|
|
1224
|
-
// `inject: "head"` siblings and resource hints
|
|
1225
|
-
// title/meta/base facts only when configured. Structural, so it
|
|
1193
|
+
// `<head>` anchors are collected for every page, since they place
|
|
1194
|
+
// `inject: "head"` siblings and resource hints. Structural, so this
|
|
1226
1195
|
// runs even for `webpackIgnore`d elements.
|
|
1227
1196
|
{
|
|
1228
1197
|
const name = path.tagName();
|
|
@@ -1447,11 +1416,9 @@ class HtmlParser extends Parser {
|
|
|
1447
1416
|
module.addCodeGenerationDependency(dep);
|
|
1448
1417
|
break;
|
|
1449
1418
|
}
|
|
1450
|
-
// `<iframe srcdoc
|
|
1451
|
-
//
|
|
1452
|
-
// `
|
|
1453
|
-
// whose URL is `about:srcdoc`, so its base URL is inherited from
|
|
1454
|
-
// this document — asset URLs resolve against this file's context.
|
|
1419
|
+
// `<iframe srcdoc>` is an entity-encoded document, fed back through
|
|
1420
|
+
// the pipeline as a nested `data:text/html` module. Its URL is
|
|
1421
|
+
// `about:srcdoc`, so asset URLs resolve against this file.
|
|
1455
1422
|
case "srcdoc": {
|
|
1456
1423
|
const htmlText = decodeEntities(value, true);
|
|
1457
1424
|
// Only spin up a nested module when there is markup that can
|
|
@@ -1579,10 +1546,9 @@ class HtmlParser extends Parser {
|
|
|
1579
1546
|
}
|
|
1580
1547
|
const s = start + (map ? map[us] : us);
|
|
1581
1548
|
const e = start + (map ? map[ue] : ue);
|
|
1582
|
-
// `html` links the URL as its own emitted page: the same
|
|
1583
|
-
//
|
|
1584
|
-
//
|
|
1585
|
-
// Recorded as an independent entry (no `dependOn`), like an entry point.
|
|
1549
|
+
// `html` links the URL as its own emitted page: the same dependency
|
|
1550
|
+
// as `<script src>`, but rewriting to the page's filename and
|
|
1551
|
+
// emitting no siblings. Independent, like an entry point.
|
|
1586
1552
|
if (type === "html") {
|
|
1587
1553
|
const index = nextEntryIndex++;
|
|
1588
1554
|
const entryName = `__html_${moduleHash}_${index}`;
|
|
@@ -1598,10 +1564,9 @@ class HtmlParser extends Parser {
|
|
|
1598
1564
|
htmlLinkEntries.push({ request, entryName, index, type });
|
|
1599
1565
|
continue;
|
|
1600
1566
|
}
|
|
1601
|
-
// `rel="preload"/"prefetch"` of a bundled resource: an
|
|
1602
|
-
//
|
|
1603
|
-
//
|
|
1604
|
-
// sibling tags — a resource hint references exactly one URL.
|
|
1567
|
+
// `rel="preload"/"prefetch"` of a bundled resource: an independent,
|
|
1568
|
+
// non-executing entry rewritten to the built chunk's URL. No
|
|
1569
|
+
// siblings — a resource hint references exactly one URL.
|
|
1605
1570
|
if (type === "preload" || type === "prefetch") {
|
|
1606
1571
|
const as = getAttributeValue(getAttributesMap(), "as");
|
|
1607
1572
|
const asStyle = as
|
|
@@ -1609,10 +1574,9 @@ class HtmlParser extends Parser {
|
|
|
1609
1574
|
: false;
|
|
1610
1575
|
const index = nextEntryIndex++;
|
|
1611
1576
|
const entryName = `__html_${moduleHash}_${index}`;
|
|
1612
|
-
// Tag metadata
|
|
1613
|
-
// `integrity` onto a native `preload` `<link
|
|
1614
|
-
// eligible per the SRI spec
|
|
1615
|
-
// doesn't list it — so its `integrity` is left uncaptured.
|
|
1577
|
+
// Tag metadata letting the template mirror `crossorigin` and
|
|
1578
|
+
// `integrity` onto a native `preload` `<link>`. `prefetch` is not
|
|
1579
|
+
// integrity-eligible per the SRI spec, so its is left uncaptured.
|
|
1616
1580
|
const isNativeLink = elementName === "link";
|
|
1617
1581
|
const dep = new HtmlEntryDependency(
|
|
1618
1582
|
request,
|
|
@@ -1700,13 +1664,9 @@ class HtmlParser extends Parser {
|
|
|
1700
1664
|
}
|
|
1701
1665
|
}
|
|
1702
1666
|
}
|
|
1703
|
-
// Blocking-ness of the tag as
|
|
1704
|
-
// `reconcileScriptTypeAttr`
|
|
1705
|
-
//
|
|
1706
|
-
// authored `type="module"` otherwise — so only non-module
|
|
1707
|
-
// output without `defer`/`async` blocks. Non-native
|
|
1708
|
-
// elements anchor conservatively (their synthesized
|
|
1709
|
-
// siblings may be plain blocking `<script>`s).
|
|
1667
|
+
// Blocking-ness of the tag as emitted, not as authored:
|
|
1668
|
+
// `reconcileScriptTypeAttr` decides the final `type`, so only
|
|
1669
|
+
// non-module output without `defer`/`async` blocks.
|
|
1710
1670
|
if (
|
|
1711
1671
|
firstBlockingScriptStart === -1 &&
|
|
1712
1672
|
(type === "script" || type === "script-module") &&
|
|
@@ -1717,11 +1677,9 @@ class HtmlParser extends Parser {
|
|
|
1717
1677
|
) {
|
|
1718
1678
|
firstBlockingScriptStart = elementStart;
|
|
1719
1679
|
}
|
|
1720
|
-
// Sibling-clone attribute edits, captured
|
|
1721
|
-
//
|
|
1722
|
-
//
|
|
1723
|
-
// (content-specific) and `script-module` clones are forced
|
|
1724
|
-
// to `type="module"` (its value range, else inserted).
|
|
1680
|
+
// Sibling-clone attribute edits, captured as offsets relative to
|
|
1681
|
+
// the tag so the template need not re-parse it: `integrity` is
|
|
1682
|
+
// content-specific and dropped, `script-module` forces `type`.
|
|
1725
1683
|
const integrityRange =
|
|
1726
1684
|
elementStart >= 0 && elementName === nativeTag
|
|
1727
1685
|
? captureIntegrityRange(path, source, elementStart)
|
|
@@ -1823,10 +1781,9 @@ class HtmlParser extends Parser {
|
|
|
1823
1781
|
}
|
|
1824
1782
|
}
|
|
1825
1783
|
})
|
|
1826
|
-
// Skip AST output this walk never reads: `text
|
|
1827
|
-
// read by offset
|
|
1828
|
-
//
|
|
1829
|
-
// magic comments (`webpackIgnore`).
|
|
1784
|
+
// Skip AST output this walk never reads: `text`, since script and style
|
|
1785
|
+
// bodies are read by offset, and `doctype` unless head injection needs it
|
|
1786
|
+
// as an anchor. `comments` stays, for `webpackIgnore`.
|
|
1830
1787
|
.process(source, {
|
|
1831
1788
|
fragmentContext: this.fragmentContext,
|
|
1832
1789
|
skip: { text: true, doctype: headOptions === undefined }
|
|
@@ -1881,13 +1838,12 @@ class HtmlParser extends Parser {
|
|
|
1881
1838
|
const buildInfo = /** @type {HtmlModuleBuildInfo} */ (module.buildInfo);
|
|
1882
1839
|
buildInfo.strict = true;
|
|
1883
1840
|
if (baseUrlPrefix !== undefined) buildInfo.baseUrlPrefix = baseUrlPrefix;
|
|
1884
|
-
//
|
|
1885
|
-
// real compilation entries during the finishMake hook. The `script`
|
|
1886
|
-
//
|
|
1887
|
-
//
|
|
1888
|
-
//
|
|
1889
|
-
//
|
|
1890
|
-
// links are independent page entries too.
|
|
1841
|
+
// WHY: hand the collected entries to HtmlModulesPlugin, which creates the
|
|
1842
|
+
// real compilation entries during the finishMake hook. The `script` and
|
|
1843
|
+
// `script-module` groups chain through a leader-only `dependOn` so they share
|
|
1844
|
+
// a runtime, while `modulepreload` and `stylesheet` entries are independent:
|
|
1845
|
+
// `<link rel=modulepreload>` must preload without running, and a stylesheet
|
|
1846
|
+
// has no runtime. `html` links are independent page entries too.
|
|
1891
1847
|
if (
|
|
1892
1848
|
scriptEntries.length > 0 ||
|
|
1893
1849
|
scriptModuleEntries.length > 0 ||
|
package/lib/html/data.js
CHANGED
|
@@ -130,6 +130,7 @@ const REWRITABLE_ATTRIBUTES = new Set([
|
|
|
130
130
|
"blocking",
|
|
131
131
|
"cite",
|
|
132
132
|
"class",
|
|
133
|
+
"closedby",
|
|
133
134
|
"codebase",
|
|
134
135
|
"cols",
|
|
135
136
|
"colspan",
|
|
@@ -170,6 +171,7 @@ const REWRITABLE_ATTRIBUTES = new Set([
|
|
|
170
171
|
"part",
|
|
171
172
|
"ping",
|
|
172
173
|
"popover",
|
|
174
|
+
"popovertargetaction",
|
|
173
175
|
"poster",
|
|
174
176
|
"preload",
|
|
175
177
|
"referrerpolicy",
|
|
@@ -180,6 +182,7 @@ const REWRITABLE_ATTRIBUTES = new Set([
|
|
|
180
182
|
"scope",
|
|
181
183
|
"scrollamount",
|
|
182
184
|
"scrolldelay",
|
|
185
|
+
"shadowrootmode",
|
|
183
186
|
"size",
|
|
184
187
|
"sizes",
|
|
185
188
|
"span",
|
|
@@ -206,6 +209,7 @@ const REWRITABLE_ATTRIBUTES = new Set([
|
|
|
206
209
|
const ENUMERATED_ATTRIBUTE_NAMES = new Set([
|
|
207
210
|
"autocapitalize",
|
|
208
211
|
"autocomplete",
|
|
212
|
+
"closedby",
|
|
209
213
|
"contenteditable",
|
|
210
214
|
"crossorigin",
|
|
211
215
|
"decoding",
|
|
@@ -222,9 +226,11 @@ const ENUMERATED_ATTRIBUTE_NAMES = new Set([
|
|
|
222
226
|
"loading",
|
|
223
227
|
"method",
|
|
224
228
|
"popover",
|
|
229
|
+
"popovertargetaction",
|
|
225
230
|
"preload",
|
|
226
231
|
"referrerpolicy",
|
|
227
232
|
"scope",
|
|
233
|
+
"shadowrootmode",
|
|
228
234
|
"spellcheck",
|
|
229
235
|
"translate",
|
|
230
236
|
"type",
|
|
@@ -1767,8 +1773,12 @@ const ENUMERATED_KEYWORDS = Object.assign(Object.create(null), {
|
|
|
1767
1773
|
"text/plain"
|
|
1768
1774
|
]),
|
|
1769
1775
|
formmethod: new Set(["get", "post", "dialog"]),
|
|
1776
|
+
popovertargetaction: new Set(["toggle", "show", "hide"]),
|
|
1770
1777
|
type: new Set(["submit", "reset", "button"])
|
|
1771
1778
|
}),
|
|
1779
|
+
dialog: Object.assign(Object.create(null), {
|
|
1780
|
+
closedby: new Set(["any", "closerequest", "none"])
|
|
1781
|
+
}),
|
|
1772
1782
|
form: Object.assign(Object.create(null), {
|
|
1773
1783
|
autocomplete: new Set(["on", "off"]),
|
|
1774
1784
|
enctype: new Set([
|
|
@@ -1794,6 +1804,7 @@ const ENUMERATED_KEYWORDS = Object.assign(Object.create(null), {
|
|
|
1794
1804
|
"text/plain"
|
|
1795
1805
|
]),
|
|
1796
1806
|
formmethod: new Set(["get", "post", "dialog"]),
|
|
1807
|
+
popovertargetaction: new Set(["toggle", "show", "hide"]),
|
|
1797
1808
|
type: new Set([
|
|
1798
1809
|
"hidden",
|
|
1799
1810
|
"text",
|
|
@@ -1830,6 +1841,9 @@ const ENUMERATED_KEYWORDS = Object.assign(Object.create(null), {
|
|
|
1830
1841
|
td: Object.assign(Object.create(null), {
|
|
1831
1842
|
scope: new Set(["row", "col", "rowgroup", "colgroup"])
|
|
1832
1843
|
}),
|
|
1844
|
+
template: Object.assign(Object.create(null), {
|
|
1845
|
+
shadowrootmode: new Set(["open", "closed"])
|
|
1846
|
+
}),
|
|
1833
1847
|
th: Object.assign(Object.create(null), {
|
|
1834
1848
|
scope: new Set(["row", "col", "rowgroup", "colgroup"])
|
|
1835
1849
|
}),
|
|
@@ -1848,6 +1862,12 @@ const ENUMERATED_KEYWORDS = Object.assign(Object.create(null), {
|
|
|
1848
1862
|
})
|
|
1849
1863
|
});
|
|
1850
1864
|
|
|
1865
|
+
/**
|
|
1866
|
+
* `<element> <attribute>` for each enumerated attribute whose invalid value default names a different state from its missing value default, so a value matching no keyword may not be dropped as redundant.
|
|
1867
|
+
* @type {Set<string>}
|
|
1868
|
+
*/
|
|
1869
|
+
const INVALID_VALUE_DEFAULT_DIFFERS = new Set(["track kind"]);
|
|
1870
|
+
|
|
1851
1871
|
/**
|
|
1852
1872
|
* Elements `removeEmptyElements` never drops: with no children and no attributes each is still doing its job, so an empty one is not a leftover.
|
|
1853
1873
|
* @type {Set<string>}
|
|
@@ -1991,6 +2011,7 @@ module.exports.IGNORED_BODY_TABLE_STARTS = IGNORED_BODY_TABLE_STARTS;
|
|
|
1991
2011
|
module.exports.IMPLIED = IMPLIED;
|
|
1992
2012
|
module.exports.IMPLIED_THOROUGH = IMPLIED_THOROUGH;
|
|
1993
2013
|
module.exports.INTEGER_ATTRIBUTES = INTEGER_ATTRIBUTES;
|
|
2014
|
+
module.exports.INVALID_VALUE_DEFAULT_DIFFERS = INVALID_VALUE_DEFAULT_DIFFERS;
|
|
1994
2015
|
module.exports.IN_HEAD_NOSCRIPT_PASSTHROUGH = IN_HEAD_NOSCRIPT_PASSTHROUGH;
|
|
1995
2016
|
module.exports.IN_TABLE_IGNORED_ENDS = IN_TABLE_IGNORED_ENDS;
|
|
1996
2017
|
module.exports.JAVASCRIPT_SCRIPT_TYPES = JAVASCRIPT_SCRIPT_TYPES;
|
package/lib/html/htmlMinify.js
CHANGED
|
@@ -44,8 +44,6 @@ const htmlMinify = async (input, sourceMap, minimizerOptions = {}) => {
|
|
|
44
44
|
require(/** @type {string} */ ("webpack"))
|
|
45
45
|
);
|
|
46
46
|
|
|
47
|
-
// TODO widen the value rewrites the switches below name: an enumerated
|
|
48
|
-
// value the spec does not name.
|
|
49
47
|
const {
|
|
50
48
|
askEmbeddedRenderer,
|
|
51
49
|
builtinEmbeddedRenderer,
|
|
@@ -105,9 +103,10 @@ const htmlMinify = async (input, sourceMap, minimizerOptions = {}) => {
|
|
|
105
103
|
sortTokenLists,
|
|
106
104
|
removeImpliedTags
|
|
107
105
|
};
|
|
108
|
-
// Handed each body the print offers,
|
|
109
|
-
//
|
|
110
|
-
//
|
|
106
|
+
// Handed each body the print offers, keeping what it reported: the element or
|
|
107
|
+
// attribute around one is written from that answer, and a body declined or
|
|
108
|
+
// thrown on is spelled as an untapped run spells it.
|
|
109
|
+
|
|
111
110
|
// A caller's renderer is asked first; whatever it declines this minifies
|
|
112
111
|
// itself, for the languages webpack ships a minifier for.
|
|
113
112
|
const renderer = async (
|
|
@@ -151,8 +150,9 @@ const htmlMinify = async (input, sourceMap, minimizerOptions = {}) => {
|
|
|
151
150
|
|
|
152
151
|
// Recursion goes through this local name, never the module's own: the plugin
|
|
153
152
|
// ships this function to its workers as source, where that binding is absent.
|
|
154
|
-
|
|
155
|
-
//
|
|
153
|
+
|
|
154
|
+
// A marker cannot cross a parse, the preprocessor turning its NUL into U+FFFD,
|
|
155
|
+
// so each nested document is finished before it is spliced in.
|
|
156
156
|
/**
|
|
157
157
|
* @param {string} text a whole document
|
|
158
158
|
* @returns {Promise<string>} the same document, minified
|
|
@@ -246,10 +246,9 @@ htmlMinify.getEmbeddedTypes = () => {
|
|
|
246
246
|
return languages;
|
|
247
247
|
};
|
|
248
248
|
|
|
249
|
-
//
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
// plugin / worker pool.
|
|
249
|
+
// Sharing one `minimizer-webpack-plugin` instance, each asset reaches only the
|
|
250
|
+
// minify functions whose `filter` accepts it. This claims HTML, so terser and
|
|
251
|
+
// cssMinify coexist with it in one worker pool.
|
|
253
252
|
/**
|
|
254
253
|
* @param {string} name asset filename
|
|
255
254
|
* @returns {boolean} true for HTML assets
|