I am trying CSS Modules for the first time with React and Webpack and I came across at least three ways to achieve it:
- css-loader
- react-css-modules
- babel-plugin-react-css-modules
I went with babel-plugin-react-css-modules
in order to balance code simplicity and performance and everything seems to be working fine except for one thing: my 3rd party libraries (Bootstrap and Font Awesome) are also included in CSS Modules transformation.
<NavLink to="/about" styleName="navigation-button"></NavLink>
The above assigns a properly transformed className
to the NavLink
. However, a span
inside needs to refer to global styles in order to render an icon.
<span className="fa fa-info" />
The above span is not assigned a transformed className
which is expected, but my bundled stylesheet does not have these CSS classes as they are being transformed into something else, to simulate local scope.
Below is the content in my .babelrc
file to activate babel-plugin-react-css-modules
:
{
"presets": ["env", "react"],
"plugins": [
["react-css-modules", {
"generateScopedName": "[name]__[local]___[hash:base64:5]",
"filetypes": {
".less": {
"syntax": "postcss-less"
}
}
}]
]
}
In my Webpack configuration, below is the section to configure css-loader
for transforms:
{
test: /\.(less|css)$/,
exclude: /node_modules/,
use: extractCSS.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
minimize: true,
modules: true,
sourceMap: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
},
{
loader: 'less-loader'
}
]
})
}
As far as I have read, the above rule should exclude the library stylesheets and I also tried adding another rule specifically for the excluded stylesheets, however that did not seem to work, as I guess as those stylesheets were still transformed with the original rule.
In order to import CSS from the two libraries, I have the below two lines in my parent stylesheet that declares some global styles:
@import '../../../node_modules/bootstrap/dist/css/bootstrap.min.css';
@import '../../../node_modules/font-awesome/css/font-awesome.min.css';
Updated solution from playing771