add uniqueName for css module classes

This commit is contained in:
Tobias Koppers 2021-12-15 16:46:13 +01:00
parent 631ec6665e
commit bdd5d3d9d3
5 changed files with 57 additions and 21 deletions

View File

@ -103,7 +103,7 @@ class CssLoadingRuntimeModule extends RuntimeModule {
const code = Template.asString([ const code = Template.asString([
"link = document.createElement('link');", "link = document.createElement('link');",
uniqueName uniqueName
? 'link.setAttribute("data-webpack", dataWebpackPrefix + key);' ? 'link.setAttribute("data-webpack", uniqueName + ":" + key);'
: "", : "",
"link.setAttribute(loadingAttribute, 1);", "link.setAttribute(loadingAttribute, 1);",
'link.rel = "stylesheet";', 'link.rel = "stylesheet";',
@ -133,10 +133,24 @@ class CssLoadingRuntimeModule extends RuntimeModule {
id => `${JSON.stringify(id)}:0` id => `${JSON.stringify(id)}:0`
).join(",")}};`, ).join(",")}};`,
"", "",
uniqueName
? `var uniqueName = ${JSON.stringify(
runtimeTemplate.outputOptions.uniqueName
)};`
: "// data-webpack is not used as build has no uniqueName",
`var loadCssChunkData = ${runtimeTemplate.basicFunction("chunkId, link", [ `var loadCssChunkData = ${runtimeTemplate.basicFunction("chunkId, link", [
'var data, token = "", token2, exports = {}, exportsWithId = [], i = 0, cc = 1;', 'var data, token = "", token2, exports = {}, exportsWithId = [], i = 0, cc = 1;',
"try { if(!link) link = loadStylesheet(chunkId); data = link.sheet.cssRules; data = data[data.length - 1].style; } catch(e) { data = getComputedStyle(document.head); }", "try { if(!link) link = loadStylesheet(chunkId); data = link.sheet.cssRules; data = data[data.length - 1].style; } catch(e) { data = getComputedStyle(document.head); }",
'data = data.getPropertyValue("--webpack-" + chunkId);', `data = data.getPropertyValue(${
uniqueName
? runtimeTemplate.concatenation(
"--webpack-",
{ expr: "uniqueName" },
"-",
{ expr: "chunkId" }
)
: runtimeTemplate.concatenation("--webpack-", { expr: "chunkId" })
});`,
"if(!data) return;", "if(!data) return;",
"for(; cc; i++) {", "for(; cc; i++) {",
Template.indent([ Template.indent([
@ -147,11 +161,23 @@ class CssLoadingRuntimeModule extends RuntimeModule {
)}) { exports[token2.replace(/^_/, "")] = token.replace(/^_/, ""); token = ""; }`, )}) { exports[token2.replace(/^_/, "")] = token.replace(/^_/, ""); token = ""; }`,
`else if(cc == ${cc( `else if(cc == ${cc(
"/" "/"
)}) { token = token.replace(/^_/, ""); exports[token] = token + "_"; exportsWithId.push(token); token = ""; }`, )}) { token = token.replace(/^_/, ""); exports[token] = token; exportsWithId.push(token); token = ""; }`,
`else if(!cc || cc == ${cc( `else if(!cc || cc == ${cc(
"," ","
)}) { token = token.replace(/^_/, ""); exportsWithId.forEach(${runtimeTemplate.expressionFunction( )}) { token = token.replace(/^_/, ""); exportsWithId.forEach(${runtimeTemplate.expressionFunction(
"exports[x] += token", `exports[x] = ${
uniqueName
? runtimeTemplate.concatenation(
{ expr: "uniqueName" },
"-",
{ expr: "token" },
"-",
{ expr: "exports[x]" }
)
: runtimeTemplate.concatenation({ expr: "token" }, "-", {
expr: "exports[x]"
})
}`,
"x" "x"
)}); ${RuntimeGlobals.makeNamespaceObject}(exports); ${ )}); ${RuntimeGlobals.makeNamespaceObject}(exports); ${
RuntimeGlobals.moduleFactories RuntimeGlobals.moduleFactories
@ -166,9 +192,6 @@ class CssLoadingRuntimeModule extends RuntimeModule {
"installedChunks[chunkId] = 0;" "installedChunks[chunkId] = 0;"
])}`, ])}`,
'var loadingAttribute = "data-webpack-loading";', 'var loadingAttribute = "data-webpack-loading";',
uniqueName
? `var dataWebpackPrefix = ${JSON.stringify(uniqueName + ":")};`
: "// data-webpack is not used as build has no uniqueName",
`var loadStylesheet = ${runtimeTemplate.basicFunction( `var loadStylesheet = ${runtimeTemplate.basicFunction(
"chunkId, url, done" + (withHmr ? ", hmr" : ""), "chunkId, url, done" + (withHmr ? ", hmr" : ""),
[ [
@ -180,7 +203,7 @@ class CssLoadingRuntimeModule extends RuntimeModule {
"var l = links[i];", "var l = links[i];",
`if(l.getAttribute("href") == url${ `if(l.getAttribute("href") == url${
uniqueName uniqueName
? ' || l.getAttribute("data-webpack") == dataWebpackPrefix + key' ? ' || l.getAttribute("data-webpack") == uniqueName + ":" + key'
: "" : ""
}) { link = l; break; }` }) { link = l; break; }`
]), ]),

View File

@ -180,7 +180,8 @@ class CssModulesPlugin {
this.renderChunk({ this.renderChunk({
chunk, chunk,
chunkGraph, chunkGraph,
codeGenerationResults codeGenerationResults,
uniqueName: compilation.outputOptions.uniqueName
}), }),
filenameTemplate: CssModulesPlugin.getChunkFilenameTemplate( filenameTemplate: CssModulesPlugin.getChunkFilenameTemplate(
chunk, chunk,
@ -240,7 +241,7 @@ class CssModulesPlugin {
return [...(cssImports || []), ...(cssContent || [])]; return [...(cssImports || []), ...(cssContent || [])];
} }
renderChunk({ chunk, chunkGraph, codeGenerationResults }) { renderChunk({ uniqueName, chunk, chunkGraph, codeGenerationResults }) {
const modules = this.getOrderedChunkCssModules(chunk, chunkGraph); const modules = this.getOrderedChunkCssModules(chunk, chunkGraph);
const source = new ConcatSource(); const source = new ConcatSource();
const metaData = []; const metaData = [];
@ -262,7 +263,7 @@ class CssModulesPlugin {
`${ `${
exports exports
? Array.from(exports, ([n, v]) => ? Array.from(exports, ([n, v]) =>
v === `${n}_${moduleId}` v === `${uniqueName ? uniqueName + "-" : ""}${moduleId}-${n}`
? `${escapeCss(n)}/` ? `${escapeCss(n)}/`
: `${escapeCss(n)}(${escapeCss(v)})` : `${escapeCss(n)}(${escapeCss(v)})`
).join("") ).join("")
@ -275,7 +276,10 @@ class CssModulesPlugin {
} }
} }
source.add( source.add(
`head{--webpack-${escapeCss(chunk.id, true)}:${metaData.join(",")};}` `head{--webpack-${escapeCss(
(uniqueName ? uniqueName + "-" : "") + chunk.id,
true
)}:${metaData.join(",")};}`
); );
return source; return source;
} }

View File

@ -83,14 +83,20 @@ CssLocalIdentifierDependency.Template = class CssLocalIdentifierDependencyTempla
apply( apply(
dependency, dependency,
source, source,
{ module, moduleGraph, chunkGraph, runtime, cssExports } { module, moduleGraph, chunkGraph, runtime, runtimeTemplate, cssExports }
) { ) {
const dep = /** @type {CssLocalIdentifierDependency} */ (dependency); const dep = /** @type {CssLocalIdentifierDependency} */ (dependency);
const used = moduleGraph const used = moduleGraph
.getExportInfo(module, dep.name) .getExportInfo(module, dep.name)
.getUsedName(dep.name, runtime); .getUsedName(dep.name, runtime);
const moduleId = chunkGraph.getModuleId(module); const moduleId = chunkGraph.getModuleId(module);
const identifier = (used || "_") + "_" + moduleId; const identifier =
(runtimeTemplate.outputOptions.uniqueName
? runtimeTemplate.outputOptions.uniqueName + "-"
: "") +
moduleId +
"-" +
(used || "");
source.replace( source.replace(
dep.range[0], dep.range[0],
dep.range[1] - 1, dep.range[1] - 1,

View File

@ -8,16 +8,16 @@ it("should allow to create css modules", done => {
try { try {
expect(x).toEqual({ expect(x).toEqual({
global: undefined, global: undefined,
class: prod ? "S_491" : "class_./style.module.css", class: prod ? "my-app-491-S" : "./style.module.css-class",
local: prod local: prod
? "Zw_491 yl_491 J__491 gc_491" ? "my-app-491-Zw my-app-491-yl my-app-491-J_ my-app-491-gc"
: "local1_./style.module.css local2_./style.module.css local3_./style.module.css local4_./style.module.css", : "./style.module.css-local1 ./style.module.css-local2 ./style.module.css-local3 ./style.module.css-local4",
local2: prod local2: prod
? "Xg_491 AY_491" ? "my-app-491-Xg my-app-491-AY"
: "local5_./style.module.css local6_./style.module.css", : "./style.module.css-local5 ./style.module.css-local6",
nested: prod nested: prod
? "RX_491 undefined X2_491" ? "my-app-491-RX undefined my-app-491-X2"
: "nested1_./style.module.css undefined nested3_./style.module.css" : "./style.module.css-nested1 undefined ./style.module.css-nested3"
}); });
} catch (e) { } catch (e) {
return done(e); return done(e);

View File

@ -10,6 +10,9 @@ module.exports = [
{ {
target: "web", target: "web",
mode: "production", mode: "production",
output: {
uniqueName: "my-app"
},
experiments: { experiments: {
css: true css: true
} }