create-react-app之使用 @craco/craco 和 craco-less 支持 css modules

4,271 阅读2分钟

通过 CRA 创建的项目,如果要支持 less 需要修改编译配置。

修改编译配置,可以通过 npm run eject 弹出配置后修改,但是 eject 是不可逆的,弹出配置后将不会跟随官方升级项目的 react-script 版本。

如果不想通过 eject 重写配置,也可以通过以下几种方式:

  1. 通过 CRA 官方支持的 --scripts-version 参数,创建项目时使用自己重写过的 react-scripts 包。官方介绍
  2. 使用 react-app-rewired + customize-cra 组合覆盖配置
  3. 使用 craco 覆盖配置

本文将通过 craco 来完成 less 的配置

配置craco

  1. 安装 @craco/craco
    npm i @craco/craco -D
  1. 修改 package.json 中的 script 标签
    "scripts": {
        "start": "craco start",
        "build": "craco build",
        "test": "craco test",
    }
  1. 在项目根目录中创建 craco.config.js
/* craco.config.js */
    module.exports = function () {
      ...
    };

craco 的基础配置已经完成,craco.config.js 配置文件结构,可以在 craco 官方的文档中详细查询:Configuration Overview

启用sass

CRA脚手架中添加了 sass-loader 的支持,如果要启用sass的话,只需安装 node-sass 即可。

  1. 安装 node-sass
    npm install node-sass --save 
  1. 将 src/App.css 重命名为 src/App.scss
  2. 如果需要启用CSS Modules,将 CSS 文件扩展名更改为[name].module.scss 或 [name].module.sass
  • CRA脚手架使用 [name].module.css 文件命名约定支持 CSS Modules 和常规 CSS 。
  • CSS Modules 允许通过自动创建 [filename]_[classname]__[hash] 格式的唯一 classname 来确定 CSS 的作用域

启用less

CRA脚手架默认不支持 less,所以需要通过拓展来实现

  1. 安装相关 loader
    /* 安装craco-less,支持覆些webpack loader */
    npn i craco-less -S
    
    /* 同时需要安装less 和 less-loader */
    npm install --save-dev less-loader less
  1. craco.config.js 中补充相关配置:
    const CracoLessPlugin = require('craco-less');
    const { loaderByName } = require('@craco/craco');

    module.exports = function (webpackEnv) {
      const lessModuleRegex = /\.module\.less$/;

      return {
        plugins: [
          {
            plugin: CracoLessPlugin,
            options: {
              // less loader option
              lessLoaderOptions: {
                lessOptions: {
                /*
                    如果项目中有使用TDesign或AntDesign组件库需要自定义主题,可以在modifyVars中添加对应less变量
                */
                  modifyVars: {
                      @primary-color: '#2378ff'
                  },
                  javascriptEnabled: true,
                },
              },
              modifyLessRule(lessRule) {
                lessRule.exclude = lessModuleRegex;
                return lessRule;
              },
              modifyLessModuleRule(lessModuleRule) {
                // configure the file suffix
                lessModuleRule.test = lessModuleRegex;

                // configure the generated local ident name
                const cssLoader = lessModuleRule.use.find(loaderByName('css-loader'));
                cssLoader.options.modules = {
                /* 
                    注意这里的命名规则:
                    - CRA脚手架创建的项目是可以直接使用css modules的,css文件的命名规则默认是[local]_[hash:base64:5]
                    - 这里使用css modules的命名规则
                */
                
                  localIdentName: '[local]_[hash:base64:5]',
                };

                return lessModuleRule;
              },
            },
          },
        ],
      };
    };

3.将CSS文件扩展名改为 [name].less[name].module.less(启用 CSS Modules