Adriel
Adriel

Reputation: 128

How to let CSS Modules import files globally by default?

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

Answers (2)

Stefan van de Vooren
Stefan van de Vooren

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

Gavin Thomas
Gavin Thomas

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

Related Questions