React:怎么配置使用less?

React怎么配置使用less

React暴露配置

yarn eject

安装less模块(注意less-loader的版本)

yarn add less less-loader@6.2.0 -D

配置webpack.config.js

添加lessRegex变量

const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const lessRegex = /\.(less)$/;  // 新增
const lessModuleRegex = /\.module\.(less)$/;  // 新增

修改getStyleLoaders方法,该方法无法配置loaderpreProcessoroptions参数,所以该方法优化后如下:

    // 新增一个preProcessorOption参数
    const getStyleLoaders = (cssOptions, preProcessor, preProcessorOption) => {  
        const loaders = [
            isEnvDevelopment && require.resolve('style-loader'),
            isEnvProduction && {
                loader: MiniCssExtractPlugin.loader,
                options: paths.publicUrlOrPath.startsWith('.')
                    ? {publicPath: '../../'}
                    : {},
            },
            {
                loader: require.resolve('css-loader'),
                options: cssOptions,
            },
            {
                loader: require.resolve('postcss-loader'),
                options: {
                    ident: 'postcss',
                    plugins: () => [
                        require('postcss-flexbugs-fixes'),
                        require('postcss-preset-env')({
                            autoprefixer: {
                                flexbox: 'no-2009',
                            },
                            stage: 3,
                        }),
                        postcssNormalize(),
                    ],
                    sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
                },
            },
        ].filter(Boolean);
        if (preProcessor) {
            loaders.push(
                {
                    loader: require.resolve('resolve-url-loader'),
                    options: {
                        sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
                        root: paths.appSrc,
                    },
                },
                {
                    loader: require.resolve(preProcessor),
                    // 当preProcessorOption为undefined,则保持原逻辑
                    // 当preProcessorOption不为空,则把preProcessorOption设置到options中
                    options: preProcessorOption === undefined ? {sourceMap: true,} : {
                        sourceMap: true,
                        ...preProcessorOption,
                    },
                }
            );
        }
        return loaders;
    };

新增rule,可以复制sassRegex的配置进行修改,修改后如下:

           {
                            test: lessRegex,
                            exclude: lessModuleRegex,
                            use: getStyleLoaders(
                                {
                                    importLoaders: 3,
                                    sourceMap: isEnvProduction
                                        ? shouldUseSourceMap
                                        : isEnvDevelopment,
                                },
                                'less-loader',
                                {
                                    lessOptions: {
                                        javascriptEnabled: true,
                                        modifyVars: { '@primary-color': '#1DA57A' },
                                    }
                                }
                            ),
                            // 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: lessModuleRegex,
                            use: getStyleLoaders(
                                {
                                    importLoaders: 3,
                                    sourceMap: isEnvProduction
                                        ? shouldUseSourceMap
                                        : isEnvDevelopment,
                                    // modules: true,
                                    // getLocalIdent: getCSSModuleLocalIdent,
                                    modules: {
                                        getLocalIdent: getCSSModuleLocalIdent,
                                    },
                                },
                                'less-loader',
                                {
                                    lessOptions: {
                                        javascriptEnabled: true,
                                        modifyVars: { '@primary-color': '#1DA57A' },
                                    }
                                }
                            ),
                        },

使用

由webpack配置文件得知,以less为后缀的样式,使用方式如下:

// index.less
.demo {
  color: orange;
}

// App.tsx
import "./styles/index.less"; 
<p className={"demo"}>这是橙色的文字</p>

以module.less为后缀的样式,使用方式如下:

// index.module.less
.demo {
  color: orange;
}

// App.tsx
import styles from "./styles/index.module.less";
<p className={styles.demo}>这是橙色的文字</p>

// 需要在react-app-env.d.ts新增以下内容,否则在App.tsx导入时会编译失败
declare module '*.module.less' {
  const classes: {[key: string]: string};
  export default classes;
}