Obfuscate css className in a React App, scaffolded using create-react-app

Shouvik Bhuiyan
2 min readAug 22, 2020

--

Obfuscating class names can reduce the bundle size and improve overall page load performance. Also it make the code less readable for the end user in production.

To achieve this we are using CRA to scaffold a react app. Once after installation is complete then run npm run eject This will expose all the configuration files for us and we can further modify the build/webpack configurations as per our need.

We also need to install one npm module classnames, not this only makes life easier to load classes conditionally, it also has may more features to overcome the css nightmares. Please visit their documentation to read more about this library and use it as per your use case. However, in this article we will keep it simple and load a hardcoded class name.

Once classnames module is installed, we create a simple component using this.

import React from 'react';import classNames from 'classnames/bind';import styles from './heroComponent.css';const cx = classNames.bind(styles);
const Hero = (props) => {return ( <div className={cx('hero')}> <p>Hero Component</p> </div> );}export default Hero;

Note that we are passing a static class name using the classnames module. This class is defined in the css folder. However, this code alone won’t obfuscate the class names. This is where css-loader comes into picture.

Remember we did npm run eject at the start of this article, now we use its benefits. All the configuration files are stored under <Root>/config folder. Inside that folder there will be a webpack.config.js

Inside modules object of that file there will be a regex to check for all the css files. Something like this /\.css$/ At the time of writing this article CRA was storing this value inside cssRegex variable. Also, there is one variable named isEndDevelopment which if true indicates that code is being for dev environment.

Inside modules there is css-loader, which is getting called using a function named getStyleLoaders , we pass the following config to that function.

localIdentName: isEnvProduction ? '[sha1:hash:hex:4]' : '[path][name]__[local]'

Basically this says that if in production env then obfuscate the name to 4 characters and if in dev env, the class name is displayed in a more readable format.

After the changes my overall object for css-loader inside modules object looks like below.

{test: cssRegex,exclude: cssModuleRegex,use: getStyleLoaders({importLoaders: 1,modules: {localIdentName: isEnvProduction ? '[sha1:hash:hex:4]' : '[path][name]__[local]'},sourceMap: isEnvProduction && shouldUseSourceMap,sideEffects: true,}

The same thing can be achieved for sass, postcss etc. Thanks for reading, happy learning !

--

--

Shouvik Bhuiyan
Shouvik Bhuiyan

No responses yet