creat-react-app的webpack配置几种覆盖方法

838 阅读2分钟

Create React App已经封装了webpack 配置,如果想对 webpack 配置做一些修改,这个时候应该怎么办呢?CRA提供了以下几种方式来修改 webpack 的配置:

  • eject 命令
  • 替换 react-scripts 包
  • 使用 react-app-rewired
  • scripts 包 + override 组合
  • customize-cra 【推荐】

eject 命令

在creat-react-app创建完项目,我们要修改webpack配置的话,需要先执行npm run eject ,这时就会在项目内生成config和scripts文件夹,包含webpack配置和执行脚本

config
  jest
  env.js
  getHttpsConfig.js
  modules.js
  paths.js
  pnpTs.js
  webpack.config.js
  webpackDevServer.config.js
scripts
  build.js
  start.js
  test.js

如果使用了eject命令,虽然扩展了 webpack 配置,但是再也享受不到 CRA 升级带来的好处了。因为react-scripts已经是以文件的形式存在于你的项目,而不是以包的形式,所以无法对其升级。

使用 react-app-rewired

react-app-rewired 是 react 社区开源的一个修改 CRA 配置的工具,这种方式让开发者既不用eject项目也不用自己创建 scripts 包就可以拓展webpack。

如何使用

1.在 CRA 创建的项目中安装react-app-rewired

npm install react-app-rewired --save-dev

2.在项目根目录下创建config-overrides.js 文件(支持自定义文件路径)

/* config-overrides.js */

module.exports = function override(config, env) {
  // 参数中的 config 就是默认的 webpack config
  
  // 对 config 进行任意修改
  config.mode = 'development';
  
  // 一定要把新的 config 返回
  return config;
}

config-overriders.js 导出的是一个函数,这个函数的签名是 const override = (oldWebpackConfig, env) => newWebpackConfig

3.修改 scripts 命令:

/* package.json */

"scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test",
+   "test": "react-app-rewired test",
    "eject": "react-scripts eject"
}

自定义 config-overrides.js 文件路径

通过package.json 的config-overrides-path设置自定义路径:

/* package.json */
{
  ...
  "config-overrides-path": "src/app", // src/app/config-overrides.js
  ...
}

config-overrides.js 文件

默认情况下,config-overrides.js文件导出一个函数,这个函数的签名是 const override = (oldWebpackConfig, env) => newWebpackConfig(oldWepbackConfig 和 newWebpackConfig 实际指向同一个对象,因为直接在原来的 webpack config 对象上进行修改)。

也可以改为此文件导出一个对象,该对象最多包含三个字段,每个字段都是一个函数。

module.exports = {
  // The Webpack config
  webpack: function(config, env) {
    // ...add your webpack config
    return config;
  },
  // The Jest config
  jest: function(config) {
    // ...add your jest config customisation...
    return config;
  },
  // create a webpack dev server
  devServer: function(configFunction) {
    return function(proxy, allowedHost) {
      const config = configFunction(proxy, allowedHost);
      const fs = require('fs');
      config.https = {
        key: fs.readFileSync(process.env.REACT_HTTPS_KEY, 'utf8'),
        cert: fs.readFileSync(process.env.REACT_HTTPS_CERT, 'utf8'),
        ca: fs.readFileSync(process.env.REACT_HTTPS_CA, 'utf8'),
        passphrase: process.env.REACT_HTTPS_PASS
      };
      return config;
    };
  },
  paths: function(paths, env) {
    // ...add your paths config
    return paths;
  },
}

实现原理

编译时,react-app-rewired 会先取到 create-react-app 生成的默认的 webpack config,然后调用 override(config) 方法,对 config 进行修改,得到新的 webpack config。webpack 最终会使用这个新的 config 进行打包。

流程大致如下:

const overrides = require('../config-overrides');
const webpackConfigPath = paths.scriptVersion + "/config/webpack.config.prod";

// load original config
const webpackConfig = require(webpackConfigPath);

// override config in memory
require.cache[require.resolve(webpackConfigPath)].exports =
  overrides.webpack(webpackConfig, process.env.NODE_ENV);

// run original script
require(paths.scriptVersion + '/scripts/build');

引用地址segmentfault.com/a/119000003…