loading...

Configuring both CSS Modules and global CSS for ReactJS in Webpack

codeprototype profile image Kevin Le ・2 min read

I prefer to keep all common CSS style rules in a global CSS style, called app.css for example. For style rules that only pertain to a particular component, then I'd like to keep in a separate CSS module. However, I want to be able to use the same className everywhere. For example, I might have a .logo class that are used everywhere, but my Header component needs a different logo. In this case, I might want to use both global CSS and CSS modules. This is a simple concept but the tricky part is in the details which is the Webpack configuration webpack.config.js.

The .logo class is defined in the global app.css as follow:

1. CSS module naming requirement

For the Header component, Webpack dictates that the CSS module has to be named according to the pattern something.module.css. So in this example, I will name it header.module.css.

2. Name mangling

The .logo is defined in the header.module.css as follow:

To differentiate the two .logo classNames, Webpack does the heavy lifting. It mangles the className .logo in header.module.css. If we look at the page source, we will see something like _app_header_module_css__WEBPACK_IMPORTED_MODULE_2___default.a.logo as opposed to simply logo in app.css.

3. webpack.config.js

We don't care about the above heavy lifting that Webpack does, but we have to abide by its requirement. We will need to configure 2 different rules: one for the global CSS and another for CSS module.

The first rule is for CSS module and second is for global CSS. You can easily tell by looking at the include key in each rule.

4. Outdated information

You might have seen some older posts which showed outdated information:

For example,

test: /\.css$/,
  loader: 'style!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'

or

{
    test: /\.(css|scss)$/,
    use: [
      'style-loader',
      {
        loader: 'css-loader',
        options: {
          modules: true,
          importLoaders: 1,
          localIdentName: '[name]__[local]__[hash:base64:5]'
        }
      }
    ],
    include: /\.module\.css$/
},

These will break the Webpack compiling npm run webpack. Don't use them.

4. Consume CSS style rules in ReactJS

Write the code for ReactJS is the easiest part:

//from global CSS
import './app.css'

return (
   <div>
      <div className='logo' />
   </div>
)
//from CSS Module
import styles from "./header.module.css"

return (
   <div>
      <div className={styles.logo} />
   </div>
)

Discussion

pic
Editor guide