CSS Modules in React — Starter Kit

Traditionally we kept our client side code in three separate groups (html, css, js). When SPA (single page applications) got famous, it was not fun to restrict a big app in just 3 groups. We should be able to split them into many more groups, and then came the cross cutting solution (in the real sense). And the answer was Modular CSS.

Not only CSS, but also HTML and JS are made modular. So all three are bundled into one unit and that is what is famously known as Components.

The first lesson while learning ReactJS is, ‘everything is a component’. The best part about components is, they work independently and they are composable. We can reuse components across multiple projects effortlessly.

React brings in a lot of interesting concepts which will live through the next decade or two. Having said that, it will take some time for these topics to sink in for a new developer. Apart from learning, setting up the project itself is considered as a difficult process by beginners.

create-react-app is a great tool to get started with a React project, but it doesn’t support Modular CSS out of the box. So the solution is to build the setup from scratch. Though there are lot of good tutorials available, a new developer will miss a point or two and fail to complete the setup. And some of the tutorials are outdated.

Starter Kit

I created a simple starter kit with minimum setup, mainly covering support for css modules. Do clone the repository and go through the files. I have not included some of the popular dependencies like react-props, jest etc in order to keep it simple. You can use it as a starter for a project or just as a learning resource.

I would like to go through, just a few of the webpack settings. For handling css, we need to add two loaders:

1. css-loader: which only loads the css from the file system

2. style-loader: which actualy adds the loaded css to the page.

// from webpack.config.dev.js
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]_[local]__[hash:base64:5]'
}
}
   ]
}

We can guess that css-loader should be applied before the style-loader. Webpack loaders takes an optional configuration object (options). So, for the ‘css-loader’ we are setting the Boolean property ‘module’ to ‘true’. We are also setting the property ‘localIdentName’ with a trickier name. This serves the purpose of generating random class names, so that there wont be any clashes with the class names coming from some other modules/components.

I am also using a couple of webpack plugins, and let me add a quick note about them.

HTMLWebpackPlugin

We know that, in React we handle even css and html inside javascript, and the entry point for our project is mostly ‘index.js’. But when it comes to running it on browser, we need to wrap our javascript in a html page. And this plugin solves that purpose. We provide the location for the ‘html template’ to be used, in webpack.

ExtractTextPlugin

By default, the css would be bundled with the javascript. In case if we want to have the css in a separate file (say style.css) we should use this plugin. We are using it only in production and not in development environment, because it doesn’t work along with ‘Hot Module Replacement’.

Please do let me know if you have any question.