Skip to content

Broaden HTML module source URL coverage (SVG, legacy & obsolete attributes)#21241

Merged
alexander-akait merged 6 commits into
mainfrom
claude/html-module-coverage-ssl7ib
Jun 22, 2026
Merged

Broaden HTML module source URL coverage (SVG, legacy & obsolete attributes)#21241
alexander-akait merged 6 commits into
mainfrom
claude/html-module-coverage-ssl7ib

Conversation

@alexander-akait

Copy link
Copy Markdown
Member

Summary

Expands the set of URL-bearing tags/attributes the experimental HTML module (experiments.html) extracts as webpack dependencies, closing several gaps found while auditing HtmlParser:

  • SVG paint-server / reference elements href/xlink:href: <linearGradient>, <radialGradient>, <pattern>, <filter>, plus <color-profile> (external ICC profile).
  • SVG presentation attributes that take CSS FuncIRI values (fill, stroke, clip-path, mask, filter, marker-*, cursor) — their url(...) references, by reusing webpack's CSS lexer (TokenStream) to locate the spans; internal url(#id) is left untouched.
  • Deprecated presentational background attribute on <body>/<table>/<td>/<th>.
  • Legacy preview-image hints (<link rel="image_src">, <meta name="thumbnail">) and obsolete element attributes (<object classid>, <param valuetype="ref" value>, <applet code/object>, MathML <mglyph src>).

External (https:, data:, …) and fragment-only (#id) references are left untouched, consistent with existing behavior. A TODO is left for parsing web app manifest contents (icons/screenshots/shortcuts URLs), which needs a dedicated webmanifest module type rather than a source-table entry.

What kind of change does this PR introduce?

feat — new extraction coverage in the experimental HTML modules support.

Did you add tests for your changes?

Yes — new test/configCases/html/ cases: svg-paint-server-references, svg-presentation-url, legacy-background, and legacy-and-obsolete-sources (each also covering the negative cases, e.g. fragment-only refs and a <param> without valuetype="ref" are left untouched).

Does this PR introduce a breaking change?

No. It only adds new default source extraction for HTML modules, which is behind the experimental experiments.html flag.

If relevant, what needs to be documented once your changes are merged or what have you already documented?

When HTML module support is documented, the expanded default source list (the tags/attributes above) should be reflected in the module.parser.html.sources reference.

Use of AI

AI (Claude) was used to investigate the source-coverage gaps, implement the additions, and write the tests; all changes were reviewed and verified against the existing test suite before submitting.


Generated by Claude Code

…und URLs

Add SVG reference elements (color-profile, filter, pattern,
linearGradient, radialGradient) and the deprecated presentational
background attribute (body, table, td, th) to the HTML module's
default source list so their external URLs are emitted as assets.
Handle CSS FuncIRI url(...) values in SVG presentation attributes
(fill, stroke, clip-path, mask, filter, marker-*, cursor) by reusing
webpack's CSS lexer (TokenStream) to locate the url spans. External
url(file.svg#id) references become assets; internal url(#id) refs are
left untouched. Gated to the SVG namespace and disabled with
`sources: false`.
Add legacy preview-image hints (`<link rel=image_src>`,
`<meta name=thumbnail>`) and obsolete element source attributes
(`<object classid>`, `<param valuetype=ref value>`, `<applet code/object>`,
MathML `<mglyph src>`) to the HTML module's default source list.
The manifest file is emitted as an asset, but its JSON icons/screenshots/
shortcuts URLs are not yet rewritten; this needs a dedicated webmanifest
module type rather than a source-table entry.
@changeset-bot

changeset-bot Bot commented Jun 22, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3c86c87

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
webpack Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

This PR is packaged and the instant preview is available (3aec563).

Install it locally:

  • npm
npm i -D webpack@https://pkg.pr.new/webpack@3aec563
  • yarn
yarn add -D webpack@https://pkg.pr.new/webpack@3aec563
  • pnpm
pnpm add -D webpack@https://pkg.pr.new/webpack@3aec563

@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.80%. Comparing base (0fce20d) to head (3c86c87).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #21241      +/-   ##
==========================================
+ Coverage   92.76%   92.80%   +0.03%     
==========================================
  Files         591      589       -2     
  Lines       64565    64594      +29     
  Branches    17957    17968      +11     
==========================================
+ Hits        59896    59946      +50     
+ Misses       4669     4648      -21     
Flag Coverage Δ
css-parsing 28.68% <ø> (+<0.01%) ⬆️
html5lib 31.10% <12.28%> (-0.03%) ⬇️
integration 88.92% <92.98%> (+0.22%) ⬆️
test262 45.38% <ø> (+2.22%) ⬆️
unit 41.37% <100.00%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Codecov only counts the unit flag, so the configCases integration tests
don't register. Add HtmlParser.unittest.js cases driving real ASTs through
the new SVG presentation url(), paint-server/reference, and legacy/obsolete
attribute paths so the patch coverage reflects them.
@codspeed-hq

codspeed-hq Bot commented Jun 22, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

⚡ 3 improved benchmarks
❌ 4 regressed benchmarks
✅ 137 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory benchmark "asset-modules-inline", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 389 KB 1,230.1 KB -68.38%
Memory benchmark "many-modules-esm", scenario '{"name":"mode-development","mode":"development"}' 1.2 MB 1.9 MB -40.73%
Memory benchmark "wasm-modules-async", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 193.6 KB 248.6 KB -22.12%
Memory benchmark "many-chunks-commonjs", scenario '{"name":"mode-production","mode":"production"}' 7.8 MB 9.7 MB -20.3%
Memory benchmark "side-effects-reexport", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 851.1 KB 132.5 KB ×6.4
Memory benchmark "asset-modules-bytes", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 860.5 KB 247.3 KB ×3.5
Memory benchmark "css-modules", scenario '{"name":"mode-production","mode":"production"}' 11.1 MB 8.8 MB +27.08%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing claude/html-module-coverage-ssl7ib (3c86c87) with main (cda325e)

Open in CodSpeed

The svg-paint-server-references snapshot embeds the content hash of the
emitted sRGB.icc asset. Under `* text=auto`, Windows checkout rewrote the
fixture's newline to CRLF, changing the hash and failing the snapshot.
Add `eol=lf` for the new html test dirs (matching the existing html
fixtures) so the bytes — and the hash — are identical on every platform.
@github-actions

Copy link
Copy Markdown
Contributor

Types Coverage

Coverage after merging claude/html-module-coverage-ssl7ib into main will be
99.35%
Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
bin
   webpack.js98.77%100%100%98.77%91
examples
   build-common.js100%100%100%100%
   buildAll.js100%100%100%100%
   examples.js100%100%100%100%
   template-common.js98.21%100%100%98.21%72
examples/custom-javascript-parser
   test.filter.js100%100%100%100%
examples/custom-javascript-parser/internals
   acorn-parse.js100%100%100%100%
   meriyah-parse.js100%100%100%100%
   oxc-parse.js91.30%100%100%91.30%140, 142–143, 145, 147, 153–154, 161, 168, 90
examples/markdown
   webpack.config.mjs100%100%100%100%
examples/typescript
   test.filter.js100%100%100%100%
examples/typescript-non-erasable
   test.filter.js50%100%100%50%5
examples/virtual-modules
   test.filter.js100%100%100%100%
examples/wasm-bindgen-esm
   test.filter.js100%100%100%100%
examples/wasm-complex
   test.filter.js100%100%100%100%
examples/wasm-emscripten
   test.filter.js100%100%100%100%
examples/wasm-simple
   test.filter.js100%100%100%100%
examples/wasm-simple-source-phase
   test.filter.js100%100%100%100%
lib
   APIPlugin.js100%100%100%100%
   AsyncDependenciesBlock.js100%100%100%100%
   AutomaticPrefetchPlugin.js100%100%100%100%
   BannerPlugin.js100%100%100%100%
   Cache.js98.21%100%100%98.21%101
   CacheFacade.js100%100%100%100%
   Chunk.js99.72%100%100%99.72%39
   ChunkGraph.js100%100%100%100%
   ChunkGroup.js100%100%100%100%
   ChunkTemplate.js100%100%100%100%
   CircularModulesPlugin.js98.73%100%100%98.73%128
   CleanPlugin.js99.15%100%100%99.15%207, 227
   CodeGenerationResults.js100%100%100%100%
   CompatibilityPlugin.js100%100%100%100%
   Compilation.js98.43%100%100%98.43%1618, 1937, 1944, 1952, 1974, 1977, 2917, 3396–3397, 3429, 4095, 4125, 4178–4179, 4183, 4188, 4204–4205, 4219–4220, 4225–4226, 4703, 4729, 514, 519, 5537, 5569, 5586, 5602, 5618, 5633, 5658–5659, 5661, 5989, 5994, 6000, 6003, 6015, 6017, 6021, 6037, 6052, 6084, 6138, 6162, 6276, 764–765
   Compiler.js99.56%100%100%99.56%1139–1140, 1148
   ConcatenationScope.js98.59%100%100%98.59%189
   ConditionalInitFragment.js100%100%100%100%
   ConstPlugin.js100%100%100%100%
   ContextExclusionPlugin.js100%100%100%100%
   ContextModule.js100%100%100%100%
   ContextModuleFactory.js97.40%100%100%97.40%258, 395, 418, 420, 424, 433–434
   ContextReplacementPlugin.js100%100%100%100%
   DefinePlugin.js99%100%100%99%171–172, 188, 207, 281
   DependenciesBlock.js100%100%100%100%
   Dependency.js98.50%100%100%98.50%470, 516
   DependencyTemplate.js100%100%100%100%
   DependencyTemplates.js100%100%100%100%
   DotenvPlugin.js98.41%100%100%98.41%378, 391–392
   DynamicEntryPlugin.js100%100%100%100%
   EntryOptionPlugin.js100%100%100%100%
   EntryPlugin.js100%100%100%100%
   Entrypoint.js100%100%100%100%
   EnvironmentPlugin.js97.14%100%100%97.14%49
   ErrorHelpers.js100%100%100%100%
   EvalDevToolModulePlugin.js100%100%100%100%
   EvalSourceMapDevToolPlugin.js100%100%100%100%
   ExportsInfo.js100%100%100%100%
   ExportsInfoApiPlugin.js100%100%100%100%
   ExternalModule.js98.50%100%100%98.50%1057, 1060, 445–449, 451, 597
   ExternalModuleFactoryPlugin.js100%100%100%100%
   ExternalsPlugin.js100%100%100%100%
   FileSystemInfo.js99.52%100%100%99.52%182, 2354–2355, 2358, 2369, 2380, 2391, 278, 3795, 3810, 3834
   FlagAllModulesAsUsedPlugin.js100%100%100%100%
   FlagDependencyExportsPlugin.js98.42%100%100%98.42%413, 422, 424, 428
   FlagDependencyUsagePlugin.js100%100%100%100%
   FlagEntryExportAsUsedPlugin.js100%100%100%100%
   Generator.js100%100%100%100%
   HotModuleReplacementPlugin.js100%100%100%100%
   HotUpdateChunk.js100%100%100%100%
   IgnorePlugin.js100%100%100%100%
   IgnoreWarningsPlugin.js100%100%100%100%
   InitFragment.js100%100%100%100%
   JavascriptMetaInfoPlugin.js100%100%100%100%
   LazyBarrel.js100%100%100%100%
   LibraryTemplatePlugin.js100%100%100%100%
   LoaderOptionsPlugin.js100%100%100%100%
   LoaderTargetPlugin.js100%100%100%100%
   MainTemplate.js100%100%100%100%
   ManifestPlugin.js100%100%100%100%
   Module.js98.50%100%100%98.50%1285, 1290, 1350, 1364, 1426, 1435
   ModuleFactory.js100%100%100%100%
   ModuleFilenameHelpers.js98.85%100%100%98.85%106, 108
   ModuleGraph.js99.73%100%100%99.73%1005
   ModuleGraphConnection.js100%100%100%100%
   ModuleInfoHeaderPlugin.js100%100%100%100%
   ModuleNotFoundError.js100%100%100%100%
   ModuleProfile.js100%100%100%100%
   ModuleSourceTypeConstants.js100%100%100%100%
   ModuleTemplate.js100%100%100%100%
   ModuleTypeConstants.js100%100%100%100%
   MultiCompiler.js99.69%100%100%99.69%659
   MultiStats.js100%100%100%100%
   MultiWatching.js100%100%100%100%
   NoEmitOnErrorsPlugin.js100%100%100%100%
   NodeStuffPlugin.js100%100%100%100%
   NormalModule.js97.90%100%100%97.90%1237, 1240, 1257, 1274, 1521, 1555, 1571, 1658, 2014, 2313, 2318–2328, 418, 422, 576
   NormalModuleFactory.js99.47%100%100%99.47%1083, 1392, 486, 498
   NormalModuleReplacementPlugin.js100%100%100%100%
   NullFactory.js100%100%100%100%
   OptimizationStages.js100%100%100%100%
   OptionsApply.js100%100%100%100%
   Parser.js100%100%100%100%
   PlatformPlugin.js100%100%100%100%
   PrefetchPlugin.js100%100%100%100%
   ProgressPlugin.js98.85%100%100%98.85%519–520, 525, 527, 591
   ProvidePlugin.js100%100%100%100%
   RawModule.js100%100%100%100%
   RecordIdsPlugin.js100%100%100%100%
   RequestShortener.js100%100%100%100%
   ResolverFactory.js100%100%100%100%
   RuntimeGlobals.js100%100%100%100%
   RuntimeModule.js100%100%100%100%
   RuntimePlugin.js100%100%100%100%
   RuntimeTemplate.js100%100%100%100%
   SelfModuleFactory.js100%100%100%100%
   SingleEntryPlugin.js100%100%100%100%
   SourceMapDevToolModuleOptionsPlugin.js100%100%100%100%
   SourceMapDevToolPlugin.js98.62%100%100%98.62%220, 224, 226, 419, 430, 891
   Stats.js100%100%100%100%
   Template.js100%100%100%100%
   TemplatedPathPlugin.js99.17%100%100%99.17%176–177
   UseStrictPlugin.js100%100%100%100%
   WarnCaseSensitiveModulesPlugin.js100%100%100%100%
   WarnDeprecatedOptionPlugin.js100%100%100%100%
   WarnNoModeSetPlugin.js100%100%100%100%
   WatchIgnorePlugin.js100%100%100%100%
   Watching.js100%100%100%100%
   WebpackError.js100%100%100%100%
   WebpackIsIncludedPlugin.js100%100%100%100%
   WebpackOptionsApply.js100%100%100%100%
   WebpackOptionsDefaulter.js100%100%100%100%
   buildChunkGraph.js99.87%100%100%99.87%371
   cli.js98.62%100%100%98.62%10, 119, 545, 577, 627, 897
   index.js99.72%100%100%99.72%184
   validateSchema.js94.67%100%100%94.67%100, 87, 89, 98
   webpack.js96.33%100%100%96.33%10, 198, 220, 222
lib/asset
   AssetBytesGenerator.js100%100%100%100%
   AssetBytesParser.js100%100%100%100%
   AssetGenerator.js100%100%100%100%
   AssetModule.js100%100%100%100%
   AssetModulesPlugin.js97.32%100%100%97.32%281, 305, 308, 36, 360, 41
   AssetParser.js100%100%100%100%
   AssetSourceGenerator.js100%100%100%100%
   AssetSourceParser.js100%100%100%100%
   RawDataUrlModule.js100%100%100%100%
lib/async-modules
   AsyncModuleHelpers.js100%100%100%100%
   AwaitDependenciesInitFragment.js100%100%100%100%
   InferAsyncModulesPlugin.js100%100%100%100%
lib/cache
   AddBuildDependenciesPlugin.js100%100%100%100%
   AddManagedPathsPlugin.js100%100%100%100%
   IdleFileCachePlugin.js97.92%100%100%97.92%71, 83, 91
   MemoryCachePlugin.js95.83%100%100%95.83%33
   MemoryWithGcCachePlugin.js93.15%100%100%93.15%106, 113–114, 122, 89
   PackFileCacheStrategy.js96.40%100%100%96.40%1250, 1350, 1354, 1416, 628, 647, 657–659, 661, 677–678, 683, 686, 688, 693, 698, 722, 728, 762, 768, 774, 779, 790, 799, 804–805, 807, 824, 830–831, 833
   ResolverCachePlugin.js100%100%100%100%
   getLazyHashedEtag.js100%100%100%100%
   mergeEtags.js100%100%100%100%
lib/config
   browserslistTargetHandler.js100%100%100%100%
   defaults.js99.31%100%100%99.31%1444–1446, 1454, 274, 277, 282, 286
   defineConfig.js100%100%100%100%
   normalization.js99.02%100%100%99.02%

@alexander-akait alexander-akait merged commit 3aec563 into main Jun 22, 2026
68 checks passed
@alexander-akait alexander-akait deleted the claude/html-module-coverage-ssl7ib branch June 22, 2026 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant