2021.12.05 Progress a little every day: Configure less-loader and css-modules in react

Dead work

The latest version of react scaffolding is already installed by default

Exposing webpack configuration

The webpack configuration for react is hidden by default and encapsulated in the react scaffold package.

To add your own configuration, you need to expose the webpack file.

npm run eject

The default configuration file is displayed:

There is a webpack.config.js file in it, which is where we want to write our own configuration.

Version description

React: ^17.0.2

webpack: 4.44.2

If the versions are different, inconsistent configuration methods may occur.

If you expose two webpack files, webpack.config.dev.js and webpack.config.prod.js, which are older scaffolding versions, you probably need to configure css-modules this way:

https://blog.csdn.net/tuzi007a/article/details/121617342?spm=1001.2014.3001.5501

Configure less-loader

Install less and less-loader

npm install less --save

npm install less-loader@5.0.0 --save

Note:

When less-loader does not select a version, the 10.x version is installed by default.

This version does not support the less Options method and errors will occur:

./src/index.less (./node_modules/css-loader/dist/cjs.js??ref--5-oneOf-8-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--5-oss) TypeError: this.getOptions is not a function

So when installing less-loader, you should choose the appropriate version.

I tested 10.0.0-6.0.0 which are not supported. Version 5.0.0 was tested and supported.

Configuration Method

The following are manipulated in the webpack.config.js file.

So all the things mentioned below are found and modified in this file.

  • 1, Configure less rules and module rules

Find the following statement:

const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;

Copy it and put it after this statement.

And replace css with less:

That is, the less statement is as follows, which can be directly copied and added:

const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
  • 2, Configure less option

Find the following statement:

 const getStyleLoaders = (cssOptions, preProcessor) => {
    const loaders = [...

Add less Options after cssOptions

The statement becomes like this:

 const getStyleLoaders = (cssOptions, lessOptions, preProcessor) => {
    const loaders = [...

At the same time, find the statement next to:

{
   loader: require.resolve('css-loader'),
   options: cssOptions,
},

And add the following sentence to the bottom of the previous one.

{
   loader: require.resolve('less-loader'),
   options: lessOptions,
},

The results are as follows:

  • 3. Configuration extension method

Find this code:

{
    test: sassRegex,
    exclude: sassModuleRegex,
    use: getStyleLoaders(
    {
        importLoaders: 3,
        sourceMap: isEnvProduction
        ? shouldUseSourceMap
        : isEnvDevelopment,
    },
    'sass-loader'
    ),
    // Don't consider CSS imports dead code even if the
    // containing package claims to have no side effects.
    // Remove this when webpack adds a warning or an error for this.
    // See https://github.com/webpack/webpack/issues/6571
    sideEffects: true,
},
// Adds support for CSS Modules, but using SASS
// using the extension .module.scss or .module.sass
{
    test: sassModuleRegex,
    use: getStyleLoaders(
    {
        importLoaders: 3,
        sourceMap: isEnvProduction
        ? shouldUseSourceMap
        : isEnvDevelopment,
        modules: {
        getLocalIdent: getCSSModuleLocalIdent,
        },
    },
    'sass-loader'
    ),
},

Copy the code above, change the sass to less, and add the modified code below.

The modified code is as follows:

{
    test: lessRegex,
    exclude: lessModuleRegex,
    use: getStyleLoaders(
        {
        importLoaders: 3,
        sourceMap: isEnvProduction
            ? shouldUseSourceMap
            : isEnvDevelopment,
        },
        'less-loader'
    ),
    sideEffects: true,
    },
    {
    test: lessModuleRegex,
    use: getStyleLoaders(
        {
        importLoaders: 3,
        sourceMap: isEnvProduction
            ? shouldUseSourceMap
            : isEnvDevelopment,
        modules: {
            getLocalIdent: getCSSModuleLocalIdent,
        },
        },
        'less-loader'
    ),
},

At this point, less, less-loader configuration is complete. After configuration is complete, the project needs to be restarted.

Case Testing

Write an example with less syntax to test if the less configuration is available.

/src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.less';

function App() {
    return (
        <div>
            <h3 className="color1">hello react!</h3>
        </div>
    )
}

ReactDOM.render(
    <div>
        <App />
    </div>,
    document.querySelector('#root')
)

/src/index.less

@def: pink;

.color1 {
    color: @def;
}

Restart project, npm start

If the font color on the page is pink, the configuration is correct.

The simplest modularization

The easiest way is to leave nothing changed. This is supported by default in Scaffold version 2.0 and does not require any configuration, so there is no need to expose webpack files.

Simply change the file name of the css/less file to modularize the style.

The reason is that in the default configuration of react, modular settings have been turned on, but only file names are required and need to be written as xx.module.css or xx.module.less.

Write a case to test, and use the example above. Then we make the following changes:

  • 1, Change the style file name: index.less --> index.module.less
  • 2. Change the import method: import'. /index.module.less'; --> Import styles from'. /index.module.less';
  • 3. Change the way class names are written within tags: <h3 className="color1">hello react!</ H3> --> <h3 className={styles.color1}>hello react!</ H3>

At this point, restart the project. npm start

As you can see, the font on the page is still pink.

Moreover, the emphasis is on:

Open the console and you can see that the class name here has changed. Has become a file name_ Class Name_u Format of hash value (top 5 digits intercepted).

That is, at this point, the style has been modularized.

However, in order to get used to the style file name, how can you not only change the style file name, but also modularize the style? At this point, we think of the value of the auto option above.

Configure css-loader to implement css-modules

css-modules are not separate libraries or plug-ins, but an optional option in css-loader that can be activated to modularize styles without changing the original file name.

Now that we need to configure it ourselves, we need to turn it on.

Find these codes, css less sass has one, should be a total of three such codes:

test: --ssRegex,
exclude: --ssModuleRegex,
use: getStyleLoaders({
importLoaders: --,
sourceMap: isEnvProduction
    ? shouldUseSourceMap
    : isEnvDevelopment,
}),

Make the following changes here:

test: --ssRegex,
exclude: --ssModuleRegex,
use: getStyleLoaders({
importLoaders: --,
modules: true, // Add this line of code
sourceMap: isEnvProduction
    ? shouldUseSourceMap
    : isEnvDevelopment,
}),

modules: true, which means to turn on the css-modules function. There is no need to name the file.modules.xx.

Of course, in order for the class name to conform to the rules, we need to make other changes by changing the above code to the following form:

test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
modules: {
    mode: "local",
    localIdentName: "[path][name]__[local]--[hash:base64:5]",
},
sourceMap: isEnvProduction
    ? shouldUseSourceMap
    : isEnvDevelopment,
}),

localIdentName This represents the compiled class name rule.

path:File path

Name:File name

local:Class name

hash:base64:5 takes the first five digits of the base64 string

Write a case to test it:

We still use the above cases.

This time, just remove the module from the file name.

index.module.less --> index.less

After modification, restart the project:


You can see that the page font color is pink.

Open the console and you can also see the new class name:


At this point, our css-modules configuration has also been completed.

Reference material

  • Old version webpack configuration document https://github.com/css-modules/webpack-demo
  • Official description of css-loader https://github.com/webpack-contrib/css-loader
  • Official less-loader document https://webpack.docschina.org/loaders/less-loader/

Tags: less React Webpack css

Posted on Sun, 05 Dec 2021 20:27:19 -0500 by tmayder