Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 689
Adriel Avatar asked Dec 19 '17 04:12

Adriel


People also ask

Are CSS modules global?

According to the official CSS Module GitHub repository, a CSS Module is a CSS file in which all class names and animation names are scoped locally by default. By contrast, in a typical CSS file, all CSS selectors live in the global scope.

How do I import a CSS module?

To import a CSS Module into the corresponding component, import the css modules stylesheet as styles or [name]Styles : In JSX, use the defined CSS class as a className prop like so: From here, you can add as many other CSS modules you'd like, just remember to import each as a different name.

How do you make a global CSS react?

To apply global CSS styles in a React app, write your css in a file with a . css extension and import it in your index. js file. Global CSS should be imported in index.

How do I use CSS modules with Webpacks?

In the following code block, css-loader and style-loader are used together. Similar to babel-loader , we can load CSS files to style our pages like so: module: { rules: [ { test: /\\. js$/, loader: "babel-loader", exclude: "/node_modules/", }, // CSS rules { test: /\\.


2 Answers

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;
}
like image 103
Stefan van de Vooren Avatar answered Nov 15 '22 22:11

Stefan van de Vooren


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]' },
                },
            ],
        },
like image 26
Gavin Thomas Avatar answered Nov 15 '22 22:11

Gavin Thomas