Repository navigation
Description
Have you used AI?
No
Which part of webpack is affected?
config (options, defaults, validation), css, html
Bug Description
RuleSetCompiler.hasRuleForResource returns false when a rule uses a path-scoped RegExp with grouped or alternate extensions (e.g., test: /[\\/]src[\\/].*\.(css|scss)$/, test: /\/components\/.*\.(ts|tsx)$/, or test: /\/templates\/.*\.(html|htm)$/).
Because hasRuleForResource fails to detect that the user has configured loaders for .css, .html, or .ts, the experiments.css, experiments.html, and experiments.typescript defaults do not resolve to false. Instead, they stay "auto" (or resolve to true for experiments.typescript on Node >= 22.6), allowing built-in experimental processing (like native TypeScript type-stripping via stripTypeScriptTypes or CSS/HTML module handling) to activate alongside or conflict with the user's explicit loaders.
Link to Minimal Reproduction and steps to reproduce
const webpack = require("webpack");
const RuleSetCompiler = require("webpack/lib/rules/RuleSetCompiler");
// User configures a path-scoped rule with grouped extensions:
const rules = [
{
test: /[\/]src[\/].*.(css|scss)$/,
use: ["style-loader", "css-loader"]
}
];
// 1. Direct check on hasRuleForResource:
console.log("hasRuleForResource('/file.css'):", RuleSetCompiler.hasRuleForResource(rules, "/file.css"));
// Expected: true
// Actual: false
// 2. Options resolution check:
const compiler = webpack({
mode: "development",
entry: "./src/index.js",
module: { rules }
});
console.log("Resolved experiments.css:", compiler.options.experiments.css);
// Expected: false (disabled because user handles css)
// Actual: "auto"
Expected Behavior
RuleSetCompiler.hasRuleForResource(rules, "/file.css") should return true when a rule's test regexp targets .css files even if the regexp uses alternation groups (such as \.(css|scss) or \.(?:css|module\.css)).
Consequently, experiments.css should resolve to false in applyExperimentsDefaults when the user has provided loaders for these files.
Actual Behavior
RuleSetCompiler.hasRuleForResource(rules, "/file.css") returns false. experiments.css remains "auto".
Environment
System:
OS: Windows 11 10.0.26200
CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12700H
Memory: 5.09 GB / 23.63 GB
Binaries:
Node: 24.7.0
npm: 11.5.1
Browsers:
Chrome: 152.0.7977.65
Edge: Chromium (152.0.4191.53)
Packages:
webpack: 5.x (main)
webpack-cli: 7.2.2
css-loader: 7.1.4
html-loader: 5.1.0
ts-loader: 9.6.2Is this a regression?
None
Last Working Version
No response
Additional Context
The issue is in lib/rules/RuleSetCompiler.js:
- For
/file.css,extProbeis"\\.css". matchRuleSetCondition(condition, "/file.css")fails against/file.cssbecause the dummy path lacks the path prefix (e.g.src/).conditionReferencesExtensionperformscondition.source.includes("\\.css"), which is a literal substring search. For regexes with grouped extensions like"/[\\\\/]src[\\\\/].*\\.(css|scss)$/"or"/src\\/.*\\.(?:ts|tsx)$/",condition.sourcecontains(css|scss)rather than literal\\.css, returningfalse.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Effort
Activity