crate-react-app是我们非常常用的初始化项目点的工具,在默认情况下,刚创建的好的项目是没有暴露出配置的,如果需要暴露则需要运行对应的命令:
yarn/npm run eject
但是既然官方不推荐我们来暴露这些配置,那么有没有办法不暴露配置就能实现我们的一些常用配置呢?
答案是肯定的:
有多种方式可以实现,我这里具体讲讲我探究出来的方案:
基于customize-cra 来配置less .
customize-cra的可配置项
首先按照基本的套路来,先安装对应的库
yarn add customize-cra react-app-rewired --save-dev
// 或者
npm install customize-cra react-app-rewired --save-dev
接着我们在根目录下创建一个文件名为 config-overrrides的文件,输入如下代码:
const {
override,
} = require('customize-cra');
module.exports = override(
// 这里我们将实现对默认设置的覆盖条件
)
紧接着,我们来修改package.json里的scrip 命令:
// 修改前
"start": "react-scripts start",
"build": "react-scripts build",
"eject": "react-scripts eject"
// 修改后
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"eject": "react-scripts eject"
这里我们暂且保留 eject ,也许你不想配置了的时候还能继续使用,或者碰到其他解决不了的问题了想来暴露配置,这里预览。
less 是我们常用的css 预处理工具,能够提供给我们样式嵌套等丰富的功能,所以我们这里使用less.
还是老套路,先安装对应的库:
yarn add less less-loader --save-dev
或者
npm install less less-loader --save-dev
接着在config-overrides文件中增加less文件配置:
const {
override,
addLessLoader,
} = require('customize-cra');
module.exports = override(
addLessLoader({
lessOptions: {
javascriptEnabled: true,
modifyVars: { '@primary-color': '#1DA57A' },
},
sourceMap:true,
}),
)
这里我们有一点需要特别注意的:
less-loader的版本问题
如果你是5.0.0的版本这里的配置应该是这个样子的:
const {
override,
addLessLoader,
} = require('customize-cra');
module.exports = override(
addLessLoader({
javascriptEnabled: true,
modifyVars: { '@primary-color': '#1DA57A' },
sourceMap:true,
}),
)
即没有lessOptions这一层;
这里我们的less 就配好了,可以将样式文件名称改为.less,然后代码中引入并使用:
如果我们仅仅只是想使用less 并且用到css module,可以用一下方式:
less-loader :版本为5.0.0
const {
override,
addLessLoader,
} = require('customize-cra');
module.exports = override(
addLessLoader({
javascriptEnabled: true,
modifyVars: { '@primary-color': '#1DA57A' },
sourceMap:true,
cssLoaderOptions: {
modules: true,
},
}),
)
此方案有一个缺点,就是生成的类名完全是hash模式,不方便后期调试。
less-loader :版本为6及以上
const {
override,
addLessLoader,
adjustStyleLoaders,
} = require('customize-cra');
module.exports = override(
addLessLoader({
javascriptEnabled: true,
modifyVars: { '@primary-color': '#1DA57A' },
sourceMap:true,
}),
adjustStyleLoaders(({ use: [ , css] }) => {
css.options.sourceMap = true;
css.options.modules = {
// 配置默认的样式名称规则
localIdentName:'[name]__[local]--[hash:base64:5]',
}
})
)
产生原因:antd 默认是采用less 来渲染样式的,如果我们页面里采用css modules, 就会将antd的less文件也给编译一遍,导致样式渲染异常,所以我吗要排除掉对antd的影响。
less-loader版本 6及以上,最终的配置如下:
const {
override,
fixBabelImports,
addLessLoader,
adjustStyleLoaders,
} = require('customize-cra');
module.exports = override(
// 针对antd 实现按需打包:根据import来打包 (使用babel-plugin-import)
fixBabelImports('import', {
libraryName: 'antd',
libraryDirectory: 'es',
style: true, //自动打包相关的样式 默认为 style:'css'
}),
// 使用less-loader对源码重的less的变量进行重新制定,设置antd自定义主题
addLessLoader({
lessOptions: {
javascriptEnabled: true,
modifyVars: { '@primary-color': '#1DA57A' },
},
sourceMap:true,
}),
adjustStyleLoaders(({ use: [ , css] }) => {
css.options.sourceMap = true;
css.options.modules = {
// 配置默认的样式名称规则
localIdentName:'[name]__[local]--[hash:base64:5]',
getLocalIdent:(loaderContext, localIdentName, localName, options) => {
// 处理antd 的样式
if (loaderContext.resourcePath.includes('node_modules')) {
return localName;
}
}
}
})
)
index.js
import React from "react";
import {
Button
} from "antd";
import * as styles from "./style.less";
console.log(styles);
class Deom extends React.Component {
render() {
return <div className={styles.bbb}>
<Button type="primary">antd button</Button>
<div className={styles.test}>测试文字</div>
</div>
}
};
export default Deom;
style.less
.bbb {
background: pink;
.test {
color: red;
}
}
参考文章:
lessOptions 参数
lessLoader 版本的区别
getLocalIdent函数的灵感来源