css-modules-modify-specificity-loader
This webpack loader modifies css modules output to bump specificity of composed css classes when using css modules. It is useful when using dynamic css chunks generated by mini-css-extract-plugin when the order of classes can be random and so the applied styles.
npm i @react-app/css-modules-modify-specificity-loader
Let's have these source files:
-
a.module.css
.test { background-color: red; }
-
b.module.css
.test2 { composes: test from "./a.module.css"; background-color: blue; }
-
c.module.css
.test3 { composes: test2 from "./b.module.css"; background-color: green; }
The output of these files would be:
-
a.module.css
.test { background-color: red; }
-
b.module.css
.test { background-color: red; } .test2 { background-color: blue; }
-
c.module.css
.test { background-color: red; } .test2 { background-color: blue; } .test3 { background-color: green; }
Now let's consider that our code dynamically imports chunk with output of a.module.css and c.module.css and than later imports chunk with b.module.css output. The current applied css would be:
.test {
background-color: red;
}
.test {
background-color: red;
}
.test2 {
background-color: blue;
}
.test3 {
background-color: green;
}
.test {
background-color: red;
}
.test2 {
background-color: blue;
}
When considering element using classnames from c.module.css,
<div class="test_localname test2_localname test3_localname" />
the applied background color of the element would be blue instad of green.
This plugin changes the output of files to this:
-
a.module.css
.test { background-color: red; }
-
b.module.css
.test { background-color: red; } .test2.test2 { background-color: blue; }
-
c.module.css
.test { background-color: red; } .test2.test2 { background-color: blue; } .test3.test3.test3 { background-color: green; }
Which in our example the current applied css would be:
.test {
background-color: red;
}
.test {
background-color: red;
}
.test2.test2 {
background-color: blue;
}
.test3.test3.test3 {
background-color: green;
}
.test {
background-color: red;
}
.test2.test2 {
background-color: blue;
}
This way the element from example above will always have green background color no mather what.
You can also apply this technique with global styles. Example with bootstrap:
Instead of:
<div className={styles.test + ' alert-light'} />
Use:
.test {
composes: alert-light from global;
}
in your css module file and then:
<div className={styles.test} />
To use this loader add it to chain after css-loader.
In development:
{
test: /\.module\.css$/,
use: [
'style-loader',
'css-modules-modify-specificity-loader',
{
loader: 'css-loader',
options: {
modules: true,
}
},
],
}
In production:
{
test: /\.module\.css$/,
use: [
MiniCssExtractPlugin.loader
'css-modules-modify-specificity-loader',
{
loader: 'css-loader',
options: {
modules: true,
}
},
],
}