Skip to content

Css fix charset at rule#20831

Merged
alexander-akait merged 3 commits intomainfrom
css-fix-charset-at-rule
Apr 14, 2026
Merged

Css fix charset at rule#20831
alexander-akait merged 3 commits intomainfrom
css-fix-charset-at-rule

Conversation

@alexander-akait
Copy link
Copy Markdown
Member

Summary

fix - handle @charset at-rules

What kind of change does this PR introduce?

fix

Did you add tests for your changes?

Yes

Does this PR introduce a breaking change?

No

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

Nothing

Use of AI

No

Copilot AI review requested due to automatic review settings April 13, 2026 21:06
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 13, 2026

🦋 Changeset detected

Latest commit: 0dc1659

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

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

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
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 13, 2026

This PR is packaged and the instant preview is available (8c7700b).

Install it locally:

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

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 13, 2026

Codecov Report

❌ Patch coverage is 97.50000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 91.44%. Comparing base (5c43068) to head (0dc1659).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
lib/css/CssParser.js 91.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #20831      +/-   ##
==========================================
+ Coverage   91.40%   91.44%   +0.04%     
==========================================
  Files         561      562       +1     
  Lines       55364    55438      +74     
  Branches    14604    14636      +32     
==========================================
+ Hits        50605    50695      +90     
+ Misses       4759     4743      -16     
Flag Coverage Δ
integration 90.40% <97.50%> (+0.01%) ⬆️
test262 45.97% <0.00%> (+4.01%) ⬆️
unit 36.25% <0.00%> (+0.02%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 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.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds first-class handling of CSS @charset at-rules within webpack’s CSS module pipeline, ensuring a single normalized @charset is emitted at the correct position and warning on conflicts between modules in the same chunk.

Changes:

  • Parse @charset in CssParser, storing the detected charset in module.buildInfo and removing in-module occurrences (non-style exportType).
  • Emit a single @charset header at the beginning of rendered CSS chunks and warn when charsets conflict across modules in a chunk.
  • Add a dedicated css/charset config case + snapshot updates; extend typing/docs for the new buildInfo.charset field.

Reviewed changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
lib/css/CssParser.js Adds parsing/removal of @charset and stores normalized charset in buildInfo.
lib/css/CssModulesPlugin.js Detects conflicting charsets (warnings) and prepends a single @charset to chunk CSS output.
lib/css/CssGenerator.js Prepends @charset for css-style-sheet exportType output where applicable.
lib/Module.js Documents buildInfo.charset in JSDoc.
types.d.ts Adds charset?: string to build info typing.
test/configCases/css/charset/webpack.config.js New test case configuration covering multiple exportTypes with @charset.
test/configCases/css/charset/test.config.js Test harness setup for loading emitted CSS in the browser-like environment.
test/configCases/css/charset/warnings.js Asserts warning output for conflicting @charset values.
test/configCases/css/charset/index.js New runtime assertions/snapshots for link/text/style/css-style-sheet outputs.
test/configCases/css/charset/styles-1.link.css Fixture: UTF-8 charset + imports.
test/configCases/css/charset/styles-2.link.css Fixture: utf-8 charset variant for normalization test.
test/configCases/css/charset/styles-3.link.css Fixture: conflicting/unknown charset to trigger warning.
test/configCases/css/charset/styles-4.text.css Fixture: text exportType with charset + imports.
test/configCases/css/charset/styles-5.css-style-sheet.css Fixture: css-style-sheet exportType with charset + imports.
test/configCases/css/charset/styles-6.style.css Fixture: style exportType with charset + import.
test/configCases/css/charset/import.link.css Fixture: imported link CSS with charset.
test/configCases/css/charset/import.text.css Fixture: imported text CSS with charset + nested imports.
test/configCases/css/charset/import-nested.text.css Fixture: nested import text CSS with charset.
test/configCases/css/charset/__snapshots__/ConfigTest.snap Adds snapshots for the new css/charset config case.
test/configCases/css/charset/__snapshots__/ConfigCacheTest.snap Cache-mode snapshots for the new css/charset config case.
test/configCases/css/mini-css-extract-plugin/__snapshots__/ConfigTest.snap Updates expected output to a single hoisted @charset.
test/configCases/css/mini-css-extract-plugin/__snapshots__/ConfigCacheTest.snap Cache-mode snapshot updates for hoisted @charset.
test/configCases/css/css-modules/style.module.css Fixture changes (class rename + additional declarations) impacting snapshots.
test/configCases/css/css-modules/__snapshots__/ConfigTest.snap Snapshot updates reflecting CSS modules fixture changes.
test/configCases/css/css-modules/__snapshots__/ConfigCacheTest.snap Cache-mode snapshot updates reflecting fixture changes.
test/configCases/css/pure-css/__snapshots__/ConfigTest.snap Snapshot updates reflecting fixture changes.
test/configCases/css/pure-css/__snapshots__/ConfigCacheTest.snap Cache-mode snapshot updates reflecting fixture changes.
.changeset/spicy-buckets-fetch.md Declares a patch release note for @charset handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/css/CssParser.js Outdated
Comment thread lib/css/CssModulesPlugin.js Outdated
Comment thread test/configCases/css/charset/index.js Outdated
Comment thread test/configCases/css/css-modules/style.module.css
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 13, 2026

Merging this PR will degrade performance by 45.17%

⚡ 3 improved benchmarks
❌ 1 regressed benchmark
✅ 140 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory benchmark "devtool-eval-source-map", scenario '{"name":"mode-production","mode":"production"}' 7.6 MB 6.3 MB +20.88%
Memory benchmark "css-modules", scenario '{"name":"mode-production","mode":"production"}' 9.4 MB 7.5 MB +26.2%
Memory benchmark "asset-modules-source", scenario '{"name":"mode-development","mode":"development"}' 503.8 KB 918.9 KB -45.17%
Memory benchmark "asset-modules-source", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 388.9 KB 264.1 KB +47.25%

Comparing css-fix-charset-at-rule (0dc1659) with main (5310112)

Open in CodSpeed

@github-actions
Copy link
Copy Markdown
Contributor

Types Coverage

Coverage after merging css-fix-charset-at-rule into main will be
98.93%
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.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-simple
   test.filter.js100%100%100%100%
examples/wasm-simple-source-phase
   test.filter.js100%100%100%100%
lib
   APIPlugin.js100%100%100%100%
   AbstractMethodError.js100%100%100%100%
   AsyncDependenciesBlock.js100%100%100%100%
   AsyncDependencyToInitialChunkError.js100%100%100%100%
   AutomaticPrefetchPlugin.js100%100%100%100%
   BannerPlugin.js100%100%100%100%
   Cache.js98.21%100%100%98.21%104
   CacheFacade.js100%100%100%100%
   CaseSensitiveModulesWarning.js100%100%100%100%
   Chunk.js99.72%100%100%99.72%37
   ChunkGraph.js100%100%100%100%
   ChunkGroup.js100%100%100%100%
   ChunkRenderError.js100%100%100%100%
   ChunkTemplate.js100%100%100%100%
   CleanPlugin.js98.72%100%100%98.72%206, 226, 382
   CodeGenerationError.js100%100%100%100%
   CodeGenerationResults.js100%100%100%100%
   CommentCompilationWarning.js100%100%100%100%
   CompatibilityPlugin.js100%100%100%100%
   Compilation.js98.55%100%100%98.55%1559, 1855, 1862, 1870, 1892, 2788, 3213, 3868, 3897, 3950–3951, 3955, 3960, 3976–3977, 3991–3992, 3997–3998, 4471, 4497, 498, 503, 5205, 5286, 5301, 5326–5327, 5329, 5651, 5656, 5662, 5665, 5677, 5679, 5683, 5699, 5714, 5746, 5800, 5824, 5938, 717–718
   Compiler.js99.56%100%100%99.56%1116–1117, 1125
   ConcatenationScope.js98.59%100%100%98.59%189
   ConcurrentCompilationError.js100%100%100%100%
   ConditionalInitFragment.js100%100%100%100%
   ConstPlugin.js100%100%100%100%
   ContextExclusionPlugin.js100%100%100%100%
   ContextModule.js100%100%100%100%
   ContextModuleFactory.js97.75%100%100%97.75%258, 393, 418, 443, 447, 458
   ContextReplacementPlugin.js100%100%100%100%
   CssModule.js81.32%100%100%81.32%157, 162–177
   DefinePlugin.js98.92%100%100%98.92%158–159, 175, 194, 268
   DelegatedModule.js95.24%100%100%95.24%253–257
   DelegatedModuleFactoryPlugin.js98.15%100%100%98.15%106
   DelegatedPlugin.js100%100%100%100%
   DependenciesBlock.js100%100%100%100%
   Dependency.js98.13%100%100%98.13%371, 404
   DependencyTemplate.js100%100%100%100%
   DependencyTemplates.js100%100%100%100%
   DllEntryPlugin.js100%100%100%100%
   DllModule.js100%100%100%100%
   DllModuleFactory.js100%100%100%100%
   DllPlugin.js100%100%100%100%
   DllReferencePlugin.js100%100%100%100%
   DotenvPlugin.js97.88%100%100%97.88%237, 378, 391–392
   DynamicEntryPlugin.js100%100%100%100%
   EntryOptionPlugin.js100%100%100%100%
   EntryPlugin.js100%100%100%100%
   Entrypoint.js100%100%100%100%
   EnvironmentNotSupportAsyncWarning.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.89%100%100%98.89%399–403, 542
   ExternalModuleFactoryPlugin.js100%100%100%100%
   ExternalsPlugin.js100%100%100%100%
   FalseIIFEUmdWarning.js100%100%100%100%
   FileSystemInfo.js99.49%100%100%99.49%182, 2213–2214, 2217, 2228, 2239, 2250, 278, 3596, 3611, 3635
   FlagAllModulesAsUsedPlugin.js100%100%100%100%
   FlagDependencyExportsPlugin.js98.74%100%100%98.74%399, 401, 405
   FlagDependencyUsagePlugin.js100%100%100%100%
   FlagEntryExportAsUsedPlugin.js100%100%100%100%
   Generator.js100%100%100%100%
   GraphHelpers.js100%100%100%100%
   HarmonyLinkingError.js100%100%100%100%
   HookWebpackError.js100%100%100%100%
   HotModuleReplacementPlugin.js100%100%100%100%
   HotUpdateChunk.js100%100%100%100%
   IgnoreErrorModuleFactory.js100%100%100%100%
   IgnorePlugin.js100%100%100%100%
   IgnoreWarningsPlugin.js100%100%100%100%
   InitFragment.js100%100%100%100%
   InvalidDependenciesModuleWarning.js100%100%100%100%
   JavascriptMetaInfoPlugin.js100%100%100%100%
   LibManifestPlugin.js97.14%100%100%97.14%117, 120
   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%1304, 1309, 1370, 1384, 1446, 1455
   ModuleBuildError.js100%100%100%100%
   ModuleDependencyError.js100%100%100%100%
   ModuleDependencyWarning.js100%100%100%100%
   ModuleError.js100%100%100%100%
   ModuleFactory.js100%100%100%100%
   ModuleFilenameHelpers.js98.85%100%100%98.85%106, 108
   ModuleGraph.js99.73%100%100%99.73%1004
   ModuleGraphConnection.js100%100%100%100%
   ModuleHashingError.js100%100%100%100%
   ModuleInfoHeaderPlugin.js100%100%100%100%
   ModuleNotFoundError.js100%100%100%100%
   ModuleParseError.js100%100%100%100%
   ModuleProfile.js100%100%100%100%
   ModuleRestoreError.js100%100%100%100%
   ModuleSourceTypeConstants.js100%100%100%100%
   ModuleStoreError.js100%100%100%100%
   ModuleTemplate.js100%100%100%100%
   ModuleTypeConstants.js100%100%100%100%
   ModuleWarning.js100%100%100%100%
   MultiCompiler.js99.69%100%100%99.69%645
   MultiStats.js100%100%100%100%
   MultiWatching.js100%100%100%100%
   NoEmitOnErrorsPlugin.js100%100%100%100%
   NoModeWarning.js100%100%100%100%
   NodeStuffInWebError.js100%100%100%100%
   NodeStuffPlugin.js100%100%100%100%
   NormalModule.js97.67%100%100%97.67%1004, 1038, 1054, 1141, 1783, 1788–1798, 214, 726, 729, 746, 763
   NormalModuleFactory.js99.47%100%100%99.47%1067, 1376, 466, 478
   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.75%100%100%98.75%446–447, 452, 454, 518
   ProvidePlugin.js100%100%100%100%
   RawModule.js100%100%100%100%
   RecordIdsPlugin.js100%100%100%100%
   RequestShortener.js100%100%100%100%
   RequireJsStuffPlugin.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%
   SizeFormatHelpers.js100%100%100%100%
   SourceMapDevToolModuleOptionsPlugin.js100%100%100%100%
   SourceMapDevToolPlugin.js99.16%100%100%99.16%267–268, 610
   Stats.js100%100%100%100%
   Template.js100%100%100%100%
   TemplatedPathPlugin.js98.86%100%100%98.86%134–135
   UnhandledSchemeError.js100%100%100%100%
   UnsupportedFeatureWarning.js100%100%100%100%
   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.js96.97%100%100%96.97%44
   WebpackIsIncludedPlugin.js100%100%100%100%
   WebpackOptionsApply.js100%100%100%100%
   WebpackOptionsDefaulter.js100%100%100%100%
   buildChunkGraph.js99.87%100%100%99.87%326
   cli.js98.71%100%100%98.71%117, 469, 501, 543, 813
   formatLocation.js100%100%100%100%
   index.js100%100%100%100%
   validateSchema.js94.67%100%100%94.67%100, 87, 89, 98
   webpack.js97.22%100%100%97.22%196, 218, 220
lib/asset
   AssetBytesGenerator.js100%100%100%100%
   AssetBytesParser.js100%100%100%100%
   AssetGenerator.js100%100%100%100%
   AssetModulesPlugin.js97.77%100%100%97.77%285, 309, 312, 364, 40
   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
   

@alexander-akait alexander-akait merged commit 8c7700b into main Apr 14, 2026
54 of 57 checks passed
@alexander-akait alexander-akait deleted the css-fix-charset-at-rule branch April 14, 2026 13:47
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.

2 participants