We have a React app with Webpack 5. There are some .scss
files that are importing values from a component library installed in node_modules
using the @value
directive from CSS Modules. Everything was working great until css-loader
version 3, but we upgraded css-loader
to the last version (6.7.1) and now those values aren't compiled in the final code. Before we got the actual value for those variables (a hexadecimal color value) and now we get the name of the variable with some kind of prefix and suffix.
Before we got:
.my-class {
background: #5efa0b;
}
for @value brightGreen: #5efa0b;
in a color.css
file that was imported in .scss
file. And now we get:
.my-class {
background: i__const_brightGreen_135;
}
The .scss
files are like:
@value brightGreen from '~@MyComponentsLibrary/src/Styles/colors.css'
.my-class {
color: brightGreen;
}
and colors.css
is something like:
@value brightGreen: #5efa0b;
@value brightBlue: #4664ec
//more colors
The actual Webpack configuration is this:
const path = require('path');
const webpack = require('webpack');
const packageJson = require('./package.json');
module.exports = {
entry: {
bundle: ['whatwg-fetch', '@babel/polyfill', './src/js/index.js'],
depVersions: './src/depVersions'
},
resolve: {
// allows importing without file extension for these
extensions: ['*', '.js', '.json', '.jsx'],
modules: [path.resolve(__dirname, './src/js'), 'node_modules'],
fallback: {
'os': require.resolve('os-browserify/browser'),
'buffer': require.resolve('buffer')
}
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js',
libraryTarget: 'umd'
},
externals: {
'@MyComponentsLibrary': 'components-library',
'react': 'react',
'react-dom': 'react-dom'
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
include: [path.resolve(__dirname, 'src/')]
},
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
}
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [
'postcss-modules-values'
]
},
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10000
}
},
generator: {
dataUrl: {
mimetype: 'application/font-woff'
}
}
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
type: 'asset'
},
{
test: /\.(png|jpg)$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8192 // inline base64 URLs for <=8k images, direct URLs for the rest
}
}
}
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
'npm_package_name': JSON.stringify(packageJson.name),
'npm_package_version': JSON.stringify(packageJson.version)
}
}),
]
}
And these are the versions of the relevant packages installed.
"my-components-library": "2.2.0",
"css-loader": "6.7.1",
"os-browserify": "^0.3.0",
"sass": "^1.53.0",
"sass-loader": "^13.0.2",
"style-loader": "^3.3.1",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "3.11.3",
"webpack-merge": "^5.8.0"
"bootstrap-sass": "^3.4.3",
"node-sass": "4.14.1",
"postcss": "^8.4.14",
"postcss-loader": "^7.0.1",
"postcss-modules-values": "^4.0.0",
"webworkify-webpack": "^2.1.5",
"whatwg-fetch": "^3.6.2"
I have very little experience with Webpack so maybe (for sure) I'm missing something. I read the documentation for Webpack, css-loader and postcss-modules-values, but I couldn't find an answer. I also tried two things:
~
character from the first line of the .scss
files, which didn't work..scss
file where it is used, it works... If I have a .scss
file like this the value is compiled:@value brightGreen: #5efa0b;
.my-class {
color: brightGreen;
}
but the idea is to be able to use the values from our components library.
I really appreciate any help you can provide. Let me know if you need more information.
The @value
directive is a CSS module feature. I know that css-loader
will by default only apply the CSS module specification to files ending in .module.css
(source). Can you try renaming colors.css
to colors.module.css
or updating css-loader
or postcss-loader
configs to consider all .css
files as modules (this option will decrease performance)?