react:customize-cra修改webpack配置

谷梁智
2023-12-01

如果想修改create-react-app中的webpack配置,除了使用eject命令暴力破意外,还可以使用第三方库react-app-rewired进行修改。但是这个库只提供了config-overrides.js配置文件,修改起来比较麻烦,下面提供一系列函数来修改config-overrides.js配置文件。

customize-cra利用react-app-rewired的配置文件config-overrides.js,你只要引入改库,就可以重写config-overrides.js里的方法。

文档中的所有方法都由customize-cra导出,原文地址

1.addBabelPlugin(plugin)

添加一个babel插件。无论给plugin 参数传递什么,都会将你传递的参数添加到Babel的plugins数组中。查阅react-app-rewired资料了解更多。

注意:这个方法不会将参数添加到yarn test的Babel配置中。可以查看useBabelRc()了解更多。

2.addBabelPlugins(plugins)

一个简单的帮助函数,可以允许你传递plugin多个参数。使用的使用必须写成...扩展操作符,例如:

module.exports = override(
  disableEsLint(),
  ...addBabelPlugins(
    "polished",
    "emotion",
    "babel-plugin-transform-do-expressions"
  ),
  fixBabelImports("lodash", {
    libraryDirectory: "",
    camel2DashComponentName: false
  }),
  fixBabelImports("react-feather", {
    libraryName: "react-feather",
    libraryDirectory: "dist/icons"
  })
);

3.addBabelPreset(preset)

添加一个babel的预设。无论你给preset参数传递什么,都会将其添加到Babel的preset数组中,查阅react-app-rewired资料了解更多

注意:这个方法不会将参数添加到yarn test的Babel配置中。可以查看useBabelRc()了解更多。

2.addBabelPresets(…presets)

一个简单的帮助函数,可以允许你传递presets多个参数。使用的使用必须写成...扩展操作符,例如:

module.exports = override(
  ...addBabelPresets(
    [
      "@babel/env",
      {
        targets: {
          browsers: ["> 1%", "last 2 versions"]
        },
        modules: "commonjs"
      }
    ],
    "@babel/preset-flow",
    "@babel/preset-react"
  )
);

4.babelInclude

如果需要编译 node_modules文件夹下的一个模块,可以用此方法重写babel loader的include选项,

module.exports = override(
  babelInclude([
    path.resolve("src"), // make sure you link your own source
    path.resolve("node_modules/native-base-shoutem-theme"),
    path.resolve("node_modules/react-navigation"),
    path.resolve("node_modules/react-native-easy-grid")
  ])
);

5.fixBabelImports(libraryName, options)

添加一个 babel-plugin-import plugin. 详情查看.

6.addDecoratorsLegacy()

在传统模式中添加装饰器,请确保已经安装了@babel/plugin-proposal-decorators

7.useBabelRc()

使用.babelrc文件来配置Babel

6.disableEsLint()

Does what it says. You may need this along with addDecoratorsLegacy in order to get decorators and exports to parse together.

如果要使用Eslint的@babel/plugin-proposal-decorators插件,请按照下面的配置卸载.eslintrc文件或package.json文件中。

{
  "extends": "react-app",
  "parserOptions": {
    "ecmaFeatures": {
      "legacyDecorators": true
    }
  }
}

7.useEslintRc(configFile)

激活你的.eslintrc文件,而不使用CRA提供的

configFile是一个可循啊参数,你可以通过它来指定Eslint配置文件的路径。

8.enableEslintTypescript()

更新eslint-loader,可以让.js(x).ts(x)文件展示eslint的提示

9.addWebpackAlias(alias)

向webpack别名(alias)区域添加别名,传递一个对象,并将其合并到项目中

10.addWebpackResolve(resolve)

向webpack的resolve区域添加你传递的resolve,传递一个对象,并将其合并到项目中

11.addWebpackPlugin(plugin)

向webpackplugin数组中添加已提供的plugin,使用new webpack.DefinePlugin({...})方法传递一个定义好的plugin

12.addWebpackExternals(deps)

添加额外external依赖,如果使用CDN整个方法就很有用了

你可以参考react and react-dom 提供的例子 offload

addWebpackExternals({
  react: "React",
  "react-dom": "ReactDom"
});

addWebpackExternals 也可以接收string,function, 或 regex(正则),详情查看the webpack documentation

13.addBundleVisualizer(options, behindFlag = false)

向webpack配置中添加bundle visualizer plugin(一个web生成工具,图形化的工具,用来分析打包后的bundle.js文件)。

使用前要安装webpack-bundle-analyzer,一般情况传入以下配置就可以

{
  "analyzerMode": "static",
  "reportFilename": "report.html"
}

你可以在命令后面添加一个标志--analyze true来隐藏这个插件

addBundleVisualizer({}, true);

14.useBabelRc()

激活.babelrc (或 .babelrc.js)文件,如果你想覆盖CRA的配置就会非常有用,

Causes your .babelrc (or .babelrc.js) file to be used, this is especially useful
if you’d rather override the CRA babel configuration and make sure it is consumed
both by yarn start and yarn test (along with yarn build).

// config-overrides.js
module.exports = override(
  useBabelRc()
);

// .babelrc
{
  "presets": ["babel-preset-react-app"],
  "plugins": ["emotion"]
}
{
  analyzerMode: "static",
  reportFilename: "report.html"
}

这样就可以通过可选参数来覆盖了

15.adjustWorkbox(fn)

调整工具箱配置。传递一个函数让工具箱配置调用,你可以根据需要改变config对象,例子如下:

adjustWorkbox(wb =>
  Object.assign(wb, {
    skipWaiting: true,
    exclude: (wb.exclude || []).concat("index.html")
  })
);

16.addLessLoader(loaderOptions)

首先,要安装lessless-loader

yarn add less
yarn add --dev less-loader

或者:

npm i less
npm i -D less-loader

安装完成后按照下面的方法在override中调用addLessLoader

const { addLessLoader } = require("customize-cra");

module.exports = override(addLessLoader(loaderOptions));

loaderOptions 是可选参数. 如果需要特殊配置就可以用它,例如:

const { addLessLoader } = require("customize-cra");

module.exports = override(
  addLessLoader({
    strictMath: true,
    noIeCompat: true,
    localIdentName: "[local]--[hash:base64:5]" // 如果使用了CSS模块,并且自定义了localIdentName,默认值是'[local]--[hash:base64:5]'
  })
);

查阅Less的文档进行相关配置

一旦使用了 less-loader,就可以通过import.less文件的方式了

.module.less 会使用CSS Modules

如果要使用TypeScript(npm init react-app my-app --typescript),就要编辑react-app-env.d.ts

declare module "*.module.less" {
  const classes: { [key: string]: string };
  export default classes;
}

17.disableChunk

禁止默认的静态片段,将整个build文件构建到一个文件中。查看this thread了解更多

18.Using the plugins

要使用这些插件,请导入override函数,并且调用你想调用的插件。每个调用都会返回一个新函数,override函数就会调用新的config对象,错误值直接忽略,因此要想有条件的使用这些插件,可以按照如下方式:

const {
  override,
  addDecoratorsLegacy,
  disableEsLint,
  addBundleVisualizer,
  addWebpackAlias,
  adjustWorkbox
} = require("customize-cra");
const path = require("path");

module.exports = override(
  addDecoratorsLegacy(),
  disableEsLint(),
  process.env.BUNDLE_VISUALIZE == 1 && addBundleVisualizer(),
  addWebpackAlias({
    ["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
  }),
  adjustWorkbox(wb =>
    Object.assign(wb, {
      skipWaiting: true,
      exclude: (wb.exclude || []).concat("index.html")
    })
  )
);

19.removeModuleScopePlugin()

这个方法会移除CRA的插件来防止从src意外的文件夹导入模块,如果使用不同的文件夹这个方法就非常有用

一个常见的列子:如果你使用了CRA的monorepo设置,你的代码就会在 packages/下而而不是src/目录下
A common use case is if you are using CRA in a monorepo setup, where your packages
are under packages/ rather than src/.

20.MobX 用户

如果想在CRA2中使用MobX,请使用addDecoratorsLegacydisableEsLint.

20. 覆盖 dev server 配置

要覆盖dev server配置,可以使用overrideDevServer对象

const {
  override,
  disableEsLint,
  overrideDevServer,
  watchAll
} = require("customize-cra");

module.exports = {
  webpack: override(
    // usual webpack plugin
    disableEsLint()
  ),
  devServer: overrideDevServer(
    // dev server plugin
    watchAll()
  )
};

21.watchAll()

一旦启用,CRA就会监听项目的所有文件,包括node_modules文件夹里的。

使用它只要在运行时使用yarn start --watch-all命令就可以

watchAll();

22.添加post-css插件

使用addPostcssPlugins可以添加post-css插件

const { override, addPostcssPlugins } = require("customize-cra");

module.exports = override(
  addPostcssPlugins([require("postcss-px2rem")({ remUnit: 37.5 })])
);

23.addTslintLoader(loaderOptions)

需要安装 tslint-loader.

const { addTslintLoader } = require("customize-cra");

module.exports = override(addTslintLoader());

24.addExternalBabelPlugin(plugin)

create-react-app 中存在两种配置babel-loader规则:

  1. addSrc中(默认情况下是src/
  2. external,像node_modules文件夹,你可以使用addExternalBabelPluginexternal中添加插件,同样的,也可以用addBabelPlugin

25.addExternalBabelPlugins(plugins)

A simple helper that calls addExternalBabelPlugin for each plugin passed.

Note: Make sure to use the spread operator if adding multiple plugins.

module.exports = override(
  disableEsLint(),
  ...addExternalBabelPlugins(
    "babel-plugin-transform-do-expressions",
    "@babel/plugin-proposal-object-rest-spread",
  ),
  fixBabelImports("lodash", {
    libraryDirectory: "",
    camel2DashComponentName: false
  }),
  fixBabelImports("react-feather", {
    libraryName: "react-feather",
    libraryDirectory: "dist/icons"
  })
);
 类似资料: