前言
用 create-react-app 创建的项目,如果想要修改配置,一般有下面几种方法:
- 通过官方提供的环境变量或者修改 package.json 中的参数
- eject 弹出配置
- 通过 craco 这样的库
我的项目里使用了 craco 这个方案,原因是比较好维护后续更新。
需求
项目里引用了一些 less 库,其中使用了字体文件,形式如下
这个在普通网页下没什么问题,但是放到 Electron 这样的环境下,就会出现问题。
浏览器会认为网址是 file://example.com/iconfont.woff
,这显然是找不到的。
解决方法
一是直接修改库,这显然不是很好搞;二是通过 postcss 插件,重写 //example.com
为 http://example.com
,这种更直接点。
craco-less
craco 通过 craco-less 插件来支持 less 模块导入。
它的原理是给 webpack 增加一个 rule ,当碰到 \.less
或者 \.module\.less
文件的时候,依次使用下面这些 loader 导入文件:
- style-loader / mini-css-extract-loader
- css-loader
- postcss-loader
- resolve-url-loader
- less-loader
这里可以发现其实已经使用了 postcss ,只要我们覆盖里面的选项即可满足需求。但是一看文档,根本啥都没写,无奈只能去翻下代码。
可以看到有个 postcssLoaderOptions 可以用来覆盖 postcss-loader 选项。那么 create-react-app 里面默认的选项都是些什么呢?
查阅下 react-scripts/config/webpack.config.js
,可以找到如下配置
也就是说只要把 plugins 替换成我们自己的选项即可
postcss 插件
参考一些 postcss 插件教程,最后搞了个插件
覆盖 craco-less 配置
感悟
看来要多看看这些脚手架的源码,因为当你要修改一下其中的配置,都不知道从哪个环节下手......
{
// Options for PostCSS as we reference these options twice
// Adds vendor prefixing based on your specified browser support in
// package.json
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebook/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
postcssNormalize(),
],
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
},
},
module.exports = {
plugins: [
//...
{
plugin: LessPlugin,
options: {
postcssLoaderOptions: {
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
}),
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
require('postcss-normalize'),
require('./custom-url-postcss-plugin')
]
}
}
}
]
};