Bundle Libraries With SCSS and CSS Modules Using Rollup

CSS Modules are a great way to locally scope CSS to a specific component. Unlike with some CSS-in-JS solutions you are writing normal CSS and then import it in your component. For example,

/* Button.css */
.button {
  background: teal;
  color: white;
}
// Button.js
import React from 'react';
import css from './Button.css';

export default ({ children }) => (
  <button className={css.button}>{children}</button>
);

When building your application the generated CSS would look like this:

.Button_button__3_Ozh {
  background: coral;
  color: white;
}

This also works with Sass and SCSS files and there is a lot of documentation on how to set up SCSS and CSS Modules with Webpack. However, recently I wanted to use SCSS and CSS Modules in a library project which is bundled using Rollup.

I knew that people are using this combination of technologies and I even found some sample projects for this technology stack, but at first I couldn’t figure out what they did in their configuration to make it work. The thing that I was missing was that rollup-plugin-postcss also supports Sass and I just need to enable both modules and Sass to make everything work.

Here is my final configuration:

// rollup.config.js
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';

export default {
  input: './src/index.js',

  output: [
    {
      name: 'comlib',
      sourcemap: true,
      file: './dist/index.js',
      format: 'umd',
      globals: { react: 'React' },
    },
  ],

  plugins: [
    peerDepsExternal(),
    postcss({
      extract: false,
      modules: true,
      use: ['sass'],
    }),
    babel({ exclude: 'node_modules/**' }),
    resolve(),
    commonjs(),
  ],

  external: ['react', 'react-dom'],
};

Everything in this configuration is pretty standard, except for the PostCSS configuration:

  • modules: true enables CSS modules for the bundle.
  • use: ['sass'] tells the plugin to enable Sass support. You also need to install node-sass explicitly in the project
  • extract: false keeps the CSS in the JavaScript file. If you want to generate a separate CSS file you can set extract to true and Rollup would build a index.css file which is also put in the projects dist/ directory.

Sources