Skip to content

Commit 1a27b9e

Browse files
fix: contenthash for css generator options
2 parents e716d44 + 97335e1 commit 1a27b9e

File tree

15 files changed

+455
-99
lines changed

15 files changed

+455
-99
lines changed

lib/css/CssExportsGenerator.js

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const { UsageState } = require("../ExportsInfo");
1010
const Generator = require("../Generator");
1111
const RuntimeGlobals = require("../RuntimeGlobals");
1212
const Template = require("../Template");
13-
const { cssExportConvention } = require("../util/conventions");
1413

1514
/** @typedef {import("webpack-sources").Source} Source */
1615
/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
@@ -135,20 +134,18 @@ class CssExportsGenerator extends Generator {
135134
const source = new ConcatSource();
136135
const usedIdentifiers = new Set();
137136
for (const [name, v] of cssExportsData.exports) {
138-
for (let k of cssExportConvention(name, this.convention)) {
139-
let identifier = Template.toIdentifier(k);
140-
let i = 0;
141-
while (usedIdentifiers.has(identifier)) {
142-
identifier = Template.toIdentifier(k + i);
143-
}
144-
usedIdentifiers.add(identifier);
145-
generateContext.concatenationScope.registerExport(k, identifier);
146-
source.add(
147-
`${
148-
generateContext.runtimeTemplate.supportsConst() ? "const" : "var"
149-
} ${identifier} = ${JSON.stringify(v)};\n`
150-
);
137+
let identifier = Template.toIdentifier(name);
138+
let i = 0;
139+
while (usedIdentifiers.has(identifier)) {
140+
identifier = Template.toIdentifier(name + i);
151141
}
142+
usedIdentifiers.add(identifier);
143+
generateContext.concatenationScope.registerExport(name, identifier);
144+
source.add(
145+
`${
146+
generateContext.runtimeTemplate.supportsConst() ? "const" : "var"
147+
} ${identifier} = ${JSON.stringify(v)};\n`
148+
);
152149
}
153150
return source;
154151
} else {
@@ -163,16 +160,14 @@ class CssExportsGenerator extends Generator {
163160
RuntimeGlobals.makeNamespaceObject
164161
);
165162
}
166-
const newExports = [];
167-
for (let [k, v] of cssExportsData.exports) {
168-
for (let name of cssExportConvention(k, this.convention)) {
169-
newExports.push(`\t${JSON.stringify(name)}: ${JSON.stringify(v)}`);
170-
}
163+
const exports = [];
164+
for (let [name, v] of cssExportsData.exports) {
165+
exports.push(`\t${JSON.stringify(name)}: ${JSON.stringify(v)}`);
171166
}
172167
return new RawSource(
173168
`${needNsObj ? `${RuntimeGlobals.makeNamespaceObject}(` : ""}${
174169
module.moduleArgument
175-
}.exports = {\n${newExports.join(",\n")}\n}${needNsObj ? ")" : ""};`
170+
}.exports = {\n${exports.join(",\n")}\n}${needNsObj ? ")" : ""};`
176171
);
177172
}
178173
}
@@ -198,7 +193,9 @@ class CssExportsGenerator extends Generator {
198193
* @param {Hash} hash hash that will be modified
199194
* @param {UpdateHashContext} updateHashContext context for updating hash
200195
*/
201-
updateHash(hash, { module }) {}
196+
updateHash(hash, { module }) {
197+
hash.update(this.esModule.toString());
198+
}
202199
}
203200

204201
module.exports = CssExportsGenerator;

lib/css/CssGenerator.js

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ const { ReplaceSource } = require("webpack-sources");
99
const Generator = require("../Generator");
1010
const InitFragment = require("../InitFragment");
1111
const RuntimeGlobals = require("../RuntimeGlobals");
12-
const { cssExportConvention } = require("../util/conventions");
1312

1413
/** @typedef {import("webpack-sources").Source} Source */
1514
/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
@@ -106,15 +105,6 @@ class CssGenerator extends Generator {
106105
if (module.presentationalDependencies !== undefined)
107106
module.presentationalDependencies.forEach(handleDependency);
108107

109-
if (cssExportsData.exports.size > 0) {
110-
const newExports = new Map();
111-
for (let [name, v] of cssExportsData.exports) {
112-
for (let newName of cssExportConvention(name, this.convention)) {
113-
newExports.set(newName, v);
114-
}
115-
}
116-
cssExportsData.exports = newExports;
117-
}
118108
const data = generateContext.getData();
119109
data.set("css-exports", cssExportsData);
120110

@@ -148,7 +138,9 @@ class CssGenerator extends Generator {
148138
* @param {Hash} hash hash that will be modified
149139
* @param {UpdateHashContext} updateHashContext context for updating hash
150140
*/
151-
updateHash(hash, { module }) {}
141+
updateHash(hash, { module }) {
142+
hash.update(this.esModule.toString());
143+
}
152144
}
153145

154146
module.exports = CssGenerator;

lib/dependencies/CssExportDependency.js

Lines changed: 72 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,23 @@
55

66
"use strict";
77

8+
const { cssExportConvention } = require("../util/conventions");
89
const makeSerializable = require("../util/makeSerializable");
910
const NullDependency = require("./NullDependency");
1011

1112
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
13+
/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */
14+
/** @typedef {import("../CssModule")} CssModule */
1215
/** @typedef {import("../Dependency")} Dependency */
1316
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
17+
/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
1418
/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
1519
/** @typedef {import("../ModuleGraph")} ModuleGraph */
20+
/** @typedef {import("../css/CssExportsGenerator")} CssExportsGenerator */
21+
/** @typedef {import("../css/CssGenerator")} CssGenerator */
1622
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
1723
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
24+
/** @typedef {import("../util/Hash")} Hash */
1825

1926
class CssExportDependency extends NullDependency {
2027
/**
@@ -31,24 +38,60 @@ class CssExportDependency extends NullDependency {
3138
return "css :export";
3239
}
3340

41+
/**
42+
* @param {string} name export name
43+
* @param {CssGeneratorExportsConvention} convention convention of the export name
44+
* @returns {string[]} convention results
45+
*/
46+
getExportsConventionNames(name, convention) {
47+
if (this._conventionNames) {
48+
return this._conventionNames;
49+
}
50+
this._conventionNames = cssExportConvention(name, convention);
51+
return this._conventionNames;
52+
}
53+
3454
/**
3555
* Returns the exported names
3656
* @param {ModuleGraph} moduleGraph module graph
3757
* @returns {ExportsSpec | undefined} export names
3858
*/
3959
getExports(moduleGraph) {
40-
const name = this.name;
60+
const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this));
61+
const convention = /** @type {CssGenerator | CssExportsGenerator} */ (
62+
module.generator
63+
).convention;
64+
const names = this.getExportsConventionNames(this.name, convention);
4165
return {
42-
exports: [
43-
{
44-
name,
45-
canMangle: true
46-
}
47-
],
66+
exports: names.map(name => ({
67+
name,
68+
canMangle: true
69+
})),
4870
dependencies: undefined
4971
};
5072
}
5173

74+
/**
75+
* Update the hash
76+
* @param {Hash} hash hash to be updated
77+
* @param {UpdateHashContext} context context
78+
* @returns {void}
79+
*/
80+
updateHash(hash, { chunkGraph }) {
81+
const module = /** @type {CssModule} */ (
82+
chunkGraph.moduleGraph.getParentModule(this)
83+
);
84+
const generator = /** @type {CssGenerator | CssExportsGenerator} */ (
85+
module.generator
86+
);
87+
const names = this.getExportsConventionNames(
88+
this.name,
89+
generator.convention
90+
);
91+
hash.update(`exportsConvention`);
92+
hash.update(JSON.stringify(names));
93+
}
94+
5295
/**
5396
* @param {ObjectSerializerContext} context context
5497
*/
@@ -79,9 +122,29 @@ CssExportDependency.Template = class CssExportDependencyTemplate extends (
79122
* @param {DependencyTemplateContext} templateContext the context object
80123
* @returns {void}
81124
*/
82-
apply(dependency, source, { cssExportsData }) {
125+
apply(
126+
dependency,
127+
source,
128+
{ cssExportsData, module: m, runtime, moduleGraph }
129+
) {
83130
const dep = /** @type {CssExportDependency} */ (dependency);
84-
cssExportsData.exports.set(dep.name, dep.value);
131+
const module = /** @type {CssModule} */ (m);
132+
const convention = /** @type {CssGenerator | CssExportsGenerator} */ (
133+
module.generator
134+
).convention;
135+
const names = dep.getExportsConventionNames(dep.name, convention);
136+
const usedNames = /** @type {string[]} */ (
137+
names
138+
.map(name =>
139+
moduleGraph.getExportInfo(module, name).getUsedName(name, runtime)
140+
)
141+
.filter(Boolean)
142+
);
143+
if (usedNames.length === 0) return;
144+
145+
for (const used of usedNames) {
146+
cssExportsData.exports.set(used, dep.value);
147+
}
85148
}
86149
};
87150

lib/dependencies/CssLocalIdentifierDependency.js

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
"use strict";
77

8+
const { cssExportConvention } = require("../util/conventions");
89
const createHash = require("../util/createHash");
910
const { makePathsRelative } = require("../util/identifier");
1011
const makeSerializable = require("../util/makeSerializable");
@@ -17,6 +18,7 @@ const NullDependency = require("./NullDependency");
1718
/** @typedef {import("../CssModule")} CssModule */
1819
/** @typedef {import("../Dependency")} Dependency */
1920
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
21+
/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
2022
/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
2123
/** @typedef {import("../ModuleGraph")} ModuleGraph */
2224
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
@@ -25,6 +27,7 @@ const NullDependency = require("./NullDependency");
2527
/** @typedef {import("../css/CssParser").Range} Range */
2628
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
2729
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
30+
/** @typedef {import("../util/Hash")} Hash */
2831

2932
/**
3033
* @param {string} local css local
@@ -88,24 +91,62 @@ class CssLocalIdentifierDependency extends NullDependency {
8891
return "css local identifier";
8992
}
9093

94+
/**
95+
* @param {string} name export name
96+
* @param {CssGeneratorExportsConvention} convention convention of the export name
97+
* @returns {string[]} convention results
98+
*/
99+
getExportsConventionNames(name, convention) {
100+
if (this._conventionNames) {
101+
return this._conventionNames;
102+
}
103+
this._conventionNames = cssExportConvention(this.name, convention);
104+
return this._conventionNames;
105+
}
106+
91107
/**
92108
* Returns the exported names
93109
* @param {ModuleGraph} moduleGraph module graph
94110
* @returns {ExportsSpec | undefined} export names
95111
*/
96112
getExports(moduleGraph) {
97-
const name = this.name;
113+
const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this));
114+
const convention = /** @type {CssGenerator | CssExportsGenerator} */ (
115+
module.generator
116+
).convention;
117+
const names = this.getExportsConventionNames(this.name, convention);
98118
return {
99-
exports: [
100-
{
101-
name,
102-
canMangle: true
103-
}
104-
],
119+
exports: names.map(name => ({
120+
name,
121+
canMangle: true
122+
})),
105123
dependencies: undefined
106124
};
107125
}
108126

127+
/**
128+
* Update the hash
129+
* @param {Hash} hash hash to be updated
130+
* @param {UpdateHashContext} context context
131+
* @returns {void}
132+
*/
133+
updateHash(hash, { chunkGraph }) {
134+
const module = /** @type {CssModule} */ (
135+
chunkGraph.moduleGraph.getParentModule(this)
136+
);
137+
const generator = /** @type {CssGenerator | CssExportsGenerator} */ (
138+
module.generator
139+
);
140+
const names = this.getExportsConventionNames(
141+
this.name,
142+
generator.convention
143+
);
144+
hash.update(`exportsConvention`);
145+
hash.update(JSON.stringify(names));
146+
hash.update(`localIdentName`);
147+
hash.update(generator.localIdentName);
148+
}
149+
109150
/**
110151
* @param {ObjectSerializerContext} context context
111152
*/
@@ -158,7 +199,7 @@ CssLocalIdentifierDependency.Template = class CssLocalIdentifierDependencyTempla
158199
dependency,
159200
source,
160201
{
161-
module,
202+
module: m,
162203
moduleGraph,
163204
chunkGraph,
164205
runtime,
@@ -167,26 +208,32 @@ CssLocalIdentifierDependency.Template = class CssLocalIdentifierDependencyTempla
167208
}
168209
) {
169210
const dep = /** @type {CssLocalIdentifierDependency} */ (dependency);
170-
const used = moduleGraph
171-
.getExportInfo(module, dep.name)
172-
.getUsedName(dep.name, runtime);
173-
174-
if (!used) return;
211+
const module = /** @type {CssModule} */ (m);
212+
const convention = /** @type {CssGenerator | CssExportsGenerator} */ (
213+
module.generator
214+
).convention;
215+
const names = dep.getExportsConventionNames(dep.name, convention);
216+
const usedNames = /** @type {string[]} */ (
217+
names
218+
.map(name =>
219+
moduleGraph.getExportInfo(module, name).getUsedName(name, runtime)
220+
)
221+
.filter(Boolean)
222+
);
223+
if (usedNames.length === 0) return;
175224

225+
// use the first usedName to generate localIdent, it's shorter when mangle exports enabled
176226
const localIdent =
177227
dep.prefix +
178-
getLocalIdent(
179-
used,
180-
/** @type {CssModule} */ (module),
181-
chunkGraph,
182-
runtimeTemplate
183-
);
228+
getLocalIdent(usedNames[0], module, chunkGraph, runtimeTemplate);
184229
source.replace(
185230
dep.range[0],
186231
dep.range[1] - 1,
187232
escapeCssIdentifier(localIdent, dep.prefix)
188233
);
189-
if (used) cssExportsData.exports.set(used, localIdent);
234+
for (const used of usedNames) {
235+
cssExportsData.exports.set(used, localIdent);
236+
}
190237
}
191238
};
192239

lib/util/conventions.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
/**
1111
* @param {string} input input
1212
* @param {CssGeneratorExportsConvention | undefined} convention convention
13-
* @returns {Set<string>} results
13+
* @returns {string[]} results
1414
*/
1515
exports.cssExportConvention = (input, convention) => {
1616
const set = new Set();
@@ -42,7 +42,7 @@ exports.cssExportConvention = (input, convention) => {
4242
}
4343
}
4444
}
45-
return set;
45+
return Array.from(set);
4646
};
4747

4848
// Copy from css-loader

0 commit comments

Comments
 (0)