Reputation: 128
I am trying to implement CSS modules to my project which is using React and Webpack. But, I want to keep using all the global css that I have created.
For example, previously I imported css in React like this
import './styles.scss'
And then, there will be a html element using the class .button
which exists inside ./styles.scss
<button className='button'>Click me</button>
Now since I want to implement CSS modules, I modified the css-loader
config in webpack like this
module: {
rules: [{
test: /\.s?css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
// This is where I added the config for css modules
modules: true,
localIdentName: '[hash:base32:5]-[name]-[local]',
importLoaders: 2,
}
},
{
loader: 'postcss-loader',
options: {
config: {
path: './postcss.config.js',
},
},
},
'sass-loader',
]
}]
}
However, now I cannot use the button
classname when I import like this
import './styles.scss'
Because the classnames in ./styles.scss
are all converted to hash-based classnames like 32osj-home-button
Basically, how do I configure the css-loader to load css normally when I import this way
import './styles.scss'
But use css modules when I import this way?
import styles from './styles.scss'
OR
Is there any configuration available to set css modules to load all css in :global
by default, and only load css in :local
when I specify it?
FYI, I know I can make 2 loader configs to apply css modules for css file named this way
styles.modules.scss
and apply normal css-loader for default named css
styles.scss
But, I prefer not to do so since it will create more files after Webpack bundles them.
Upvotes: 11
Views: 7651
Reputation: 2727
With css modules I use it this way:
import styles from './styles.scss'
<button className={styles.button}>Click me</button>
The imported styles is actual a map with [className] => [hashed_className]
Everything you put in a :global block is not converted to css hashed names
:global {
.button {
color: #FF0000;
}
}
.button {
color: #000000;
}
should output
.button {
color: #FF0000;
}
.32osj-home-button {
color: #000000;
}
Upvotes: 8
Reputation: 1867
This is my setup... I can do what you want to do.
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.scss$/,
loader: ExtractPlugin.extract(['css-loader', 'sass-loader']),
},
{
test: /\.css$/,
exclude: [/\.global\./, /node_modules/],
loader: ExtractPlugin.extract(
{
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: true,
autoprefixer: true,
minimize: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}
]
})
},
{
test: /\.css/,
include: [/\.global\./, /node_modules/],
loader: ExtractPlugin.extract(
{
fallback: 'style-loader',
use: ['css-loader']
})
},
{
test: /\.(woff|woff2|ttf|eot|glyph|\.svg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: 'font/[name].[ext]',
},
},
],
},
{
test: /\.(jpg|jpeg|gif|png|tiff|svg)$/,
exclude: /\.glyph.svg/,
use: [
{
loader: 'url-loader',
options: {
limit: 6000,
name: 'image/[name].[ext]',
},
},
],
},
{
test: /\.(mp3|aac|aiff|wav|flac|m4a|mp4|ogg)$/,
exclude: /\.glyph.svg/,
use: [
{
loader: 'file-loader',
options: { name: 'audio/[name].[ext]' },
},
],
},
Upvotes: 3