Skip to content

Commit 13c679a

Browse files
authored
fix(css): skip JS module generation for unused CSS exports (#20337)
1 parent b2ad09d commit 13c679a

File tree

8 files changed

+62
-9
lines changed

8 files changed

+62
-9
lines changed

.changeset/unused-css-export.md

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+
Avoid generating JavaScript modules for CSS exports that are not used, reducing unnecessary output and bundle size.

lib/css/CssGenerator.js

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const {
1919
const RuntimeGlobals = require("../RuntimeGlobals");
2020
const Template = require("../Template");
2121
const CssImportDependency = require("../dependencies/CssImportDependency");
22+
const EntryDependency = require("../dependencies/EntryDependency");
2223
const { getUndoPath } = require("../util/identifier");
2324
const memoize = require("../util/memoize");
2425

@@ -467,22 +468,45 @@ class CssGenerator extends Generator {
467468
* @returns {SourceTypes} available types (do not mutate)
468469
*/
469470
getTypes(module) {
470-
if (this._generatesJsOnly(module)) {
471-
return JAVASCRIPT_TYPES;
472-
}
473-
/** @type {Set<string>} */
471+
const exportType = /** @type {BuildMeta} */ (module.buildMeta).exportType;
474472
const sourceTypes = new Set();
475473
const connections = this._moduleGraph.getIncomingConnections(module);
474+
475+
let isEntryModule = false;
476476
for (const connection of connections) {
477-
if (connection.dependency instanceof CssImportDependency) {
477+
if (connection.dependency instanceof EntryDependency) {
478+
isEntryModule = true;
479+
}
480+
if (
481+
exportType === "link" &&
482+
connection.dependency instanceof CssImportDependency
483+
) {
478484
continue;
479485
}
480486
if (!connection.originModule) {
481487
continue;
482488
}
483489
if (connection.originModule.type.split("/")[0] !== CSS_TYPE) {
484490
sourceTypes.add(JAVASCRIPT_TYPE);
491+
} else {
492+
const originModule = /** @type {CssModule} */ connection.originModule;
493+
const originExportType = /** @type {BuildMeta} */ (
494+
originModule.buildMeta
495+
).exportType;
496+
if (
497+
/** @type {boolean} */ (
498+
originExportType && originExportType !== "link"
499+
)
500+
) {
501+
sourceTypes.add(JAVASCRIPT_TYPE);
502+
}
503+
}
504+
}
505+
if (this._generatesJsOnly(module)) {
506+
if (sourceTypes.has(JAVASCRIPT_TYPE) || isEntryModule) {
507+
return JAVASCRIPT_TYPES;
485508
}
509+
return new Set();
486510
}
487511
if (sourceTypes.has(JAVASCRIPT_TYPE)) {
488512
return JAVASCRIPT_AND_CSS_TYPES;

test/__snapshots__/ConfigCacheTestCases.basictest.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2882,7 +2882,7 @@ exports[`ConfigCacheTestCases css css-modules exported tests should allow to cre
28822882
Object {
28832883
"UsedClassName": "my-app-identifiers_module_css-UsedClassName",
28842884
"VARS": "--my-app-style_module_css-LOCAL-COLOR my-app-style_module_css-VARS undefined my-app-style_module_css-globalVarsUpperCase",
2885-
"__webpack_modules__": 12,
2885+
"__webpack_modules__": 6,
28862886
"animation": "my-app-style_module_css-animation",
28872887
"animationName": "my-app-style_module_css-animationName",
28882888
"class": "my-app-style_module_css-class",
@@ -11015,7 +11015,7 @@ exports[`ConfigCacheTestCases css css-modules exported tests should allow to cre
1101511015
Object {
1101611016
"UsedClassName": "FPwoX1",
1101711017
"VARS": "---YmVq7 gAOQgg undefined g45L8B",
11018-
"__webpack_modules__": 9,
11018+
"__webpack_modules__": 3,
1101911019
"animation": "_1CLYv0",
1102011020
"animationName": "AndP3O",
1102111021
"class": "Q0FGvN",

test/__snapshots__/ConfigTestCases.basictest.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2882,7 +2882,7 @@ exports[`ConfigTestCases css css-modules exported tests should allow to create c
28822882
Object {
28832883
"UsedClassName": "my-app-identifiers_module_css-UsedClassName",
28842884
"VARS": "--my-app-style_module_css-LOCAL-COLOR my-app-style_module_css-VARS undefined my-app-style_module_css-globalVarsUpperCase",
2885-
"__webpack_modules__": 12,
2885+
"__webpack_modules__": 6,
28862886
"animation": "my-app-style_module_css-animation",
28872887
"animationName": "my-app-style_module_css-animationName",
28882888
"class": "my-app-style_module_css-class",
@@ -11015,7 +11015,7 @@ exports[`ConfigTestCases css css-modules exported tests should allow to create c
1101511015
Object {
1101611016
"UsedClassName": "FPwoX1",
1101711017
"VARS": "---YmVq7 gAOQgg undefined g45L8B",
11018-
"__webpack_modules__": 9,
11018+
"__webpack_modules__": 3,
1101911019
"animation": "_1CLYv0",
1102011020
"animationName": "AndP3O",
1102111021
"class": "Q0FGvN",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.e {
2+
background-color: red;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.i {
2+
composes: e from "./e.modules.css";
3+
}

test/configCases/css/node/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { i } from "./i.modules.css"
2+
3+
it("should work", () => {
4+
expect(typeof i).toBe("string")
5+
expect(__webpack_modules__["./i.modules.css"]).toBeDefined();
6+
expect(__webpack_modules__["./e.modules.css"]).toBeUndefined();
7+
})
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"use strict";
2+
3+
/** @type {import("../../../../").Configuration} */
4+
module.exports = {
5+
target: "node",
6+
mode: "development",
7+
devtool: false,
8+
experiments: {
9+
css: true
10+
}
11+
};

0 commit comments

Comments
 (0)