用 create-react-app 创建的项目,如果想要修改配置,一般有下面几种方法:
我的项目里使用了 craco 这个方案,原因是比较好维护后续更新。
项目里引用了一些 less 库,其中使用了字体文件,形式如下
@font-face {font-family: 'iconfont';src: url('//example.com/iconfont.eot');src: url('//example.com/iconfont.eot?#iefix') format('embedded-opentype'),url('//example.com/iconfont.woff') format('woff'),url('//example.com/iconfont.ttf') format('truetype'),url('//example.com/iconfont.svg#iconfont') format('svg');}.iconfont {font-family: 'iconfont'!important;}
这个在普通网页下没什么问题,但是放到 Electron 这样的环境下,就会出现问题。
浏览器会认为网址是 file://example.com/iconfont.woff
,这显然是找不到的。
一是直接修改库,这显然不是很好搞;二是通过 postcss 插件,重写 //example.com
为 http://example.com
,这种更直接点。
craco 通过 craco-less 插件来支持 less 模块导入。
它的原理是给 webpack 增加一个 rule ,当碰到 \.less
或者 \.module\.less
文件的时候,依次使用下面这些 loader 导入文件:
这里可以发现其实已经使用了 postcss ,只要我们覆盖里面的选项即可满足需求。但是一看文档,根本啥都没写,无奈只能去翻下代码。
/* else */if (rule.loader.includes(`${pathSep}postcss-loader${pathSep}`)) {lessRule.use.push({loader: rule.loader,options: {...rule.options,...(pluginOptions.postcssLoaderOptions || {})}});}
可以看到有个 postcssLoaderOptions 可以用来覆盖 postcss-loader 选项。那么 create-react-app 里面默认的选项都是些什么呢?
查阅下 react-scripts/config/webpack.config.js
,可以找到如下配置
{// Options for PostCSS as we reference these options twice// Adds vendor prefixing based on your specified browser support in// package.jsonloader: require.resolve('postcss-loader'),options: {// Necessary for external CSS imports to work// https://github.com/facebook/create-react-app/issues/2677ident: '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,},},
也就是说只要把 plugins 替换成我们自己的选项即可
参考一些 postcss 插件教程,最后搞了个插件
// custom-url-postcss-plugin.jsconst postcss = require('postcss');module.exports = postcss.plugin('postcss-focus', function () {return function (css) {css.walkDecls(decl => {if (decl.prop === 'src' && /^url\('\/\/baidu.com/.test(decl.value)) {decl.value = decl.value.replace(/^url\('\/\/baidu.com/, `url('https://google.com`);}});};});
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')]}}}]};
看来要多看看这些脚手架的源码,因为当你要修改一下其中的配置,都不知道从哪个环节下手......