Skip to content

Commit ecb436b

Browse files
authored
fix: use compiler context for CSS modules hash to avoid collisions (#20799)
* test: add test case reproducing CSS modules hash collision across directories Files with the same name in different directories (e.g. f1/style.module.css and f2/style.module.css) generate identical hashed class names, causing style collisions. Ref: #20795 * fix: use compiler context for CSS modules hash to avoid collisions Use compiler.context instead of module.context as the base path when computing relativeResourcePath for CSS module local ident hashing. Previously, files with the same name in different directories would produce identical relative paths (both "./style.module.css"), leading to hash collisions. Fixes #20795 * chore: add changeset for CSS modules hash collision fix
1 parent c0e8cf4 commit ecb436b

6 files changed

Lines changed: 36 additions & 1 deletion

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"webpack": patch
3+
---
4+
5+
Use compiler context instead of module context for CSS modules local ident hashing to avoid hash collisions when files with the same name exist in different directories.

lib/dependencies/CssIcssExportDependency.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => {
5555
(generator.options.localIdentName);
5656
const relativeResourcePath = makePathsRelative(
5757
/** @type {string} */
58-
(module.context),
58+
(runtimeTemplate.compilation.compiler.context),
5959
/** @type {string} */
6060
(module.getResource()),
6161
runtimeTemplate.compilation.compiler.root
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.xxx {
2+
background: green;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.xxx {
2+
background: red;
3+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import * as f1 from "./f1/style.module.css";
2+
import * as f2 from "./f2/style.module.css";
3+
4+
it("should generate unique hashed class names for same-named classes in different directories", () => {
5+
expect(f1.xxx).toBeDefined();
6+
expect(f2.xxx).toBeDefined();
7+
expect(f1.xxx).not.toBe(f2.xxx);
8+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"use strict";
2+
3+
/** @type {import("../../../../").Configuration} */
4+
module.exports = {
5+
experiments: {
6+
css: true
7+
},
8+
module: {
9+
rules: [
10+
{
11+
test: /\.module\.css$/i,
12+
type: "css/module"
13+
}
14+
]
15+
}
16+
};

0 commit comments

Comments
 (0)