步骤二:重写Webpack【React项目创建】

1,152 阅读2分钟

因为create-react-app创建的项目,在实际开发中,可能需要按照项目需求进行一些优化,所以往往修改进行webpack重写

方案选择

  1. npm run eject 新建完项目后,可以通过执行上面暴露出隐藏的配置文件。这也是我不希望看到的

  2. react-app-rewiredcustomize-cra 可以利用react-app-rewired进行修改和重写,同时customize-cra提供了现有的技术方案,还是比较方便的

实现什么?

在后期的项目打包过程中,我想要实现

  • 开发时候的热更新HMR
  • 开发时候的sourcemap
  • 可以使用less的样式预处理
  • 开发时候的别名
  • 代码分片
  • 打包文件分析工具 等等等等,

以上只是初期希望实现的,也是此刻想到的,后面肯定会再优化,可以从源码中查看具体的配置

实现步骤

因为npm run eject不可逆,同时不想暴露太多不需要涉及到的配置,所以这里使用方案2:react-app-rewiredcustomize-cra对config进行重写

安装所需包

安装react-app-rewiredcustomize-cra

npm i react-app-rewired customize-cra -D

修改配置

config-override.js

创建config-override.js文件,并根据想要实现的内容加入了以下配置

// 部分,其他的配置查看详细的源代码
const path = require('path');
const rewireReactHotLoader = require('react-app-rewire-hot-loader');
const { override, addLessLoader, addWebpackPlugin, fixBabelImports, addWebpackAlias, setWebpackOptimizationSplitChunks } = require('customize-cra');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

const isProduction = process.env.NODE_ENV === 'production';
// 根据环境修改webpack配置,这里只修改了source-map
const replaceConfig = () => config => {
  if (isProduction) {
    config.devtool = false;
   } else{
    config.devtool = 'eval-source-map';
  }
  return config;
}
// 热更新,项目代码中需要结合修改
const hotLoader = () => config => {
  config = rewireReactHotLoader(config, process.env.NODE_ENV)
  return config;
}
module.exports = {
  webpack: override(
    addLessLoader(), // 支持less,如果配置antd主题,参考:https://ant.design/docs/react/use-with-create-react-app-cn#高级配置
    isProduction && fixBabelImports('import', {
      libraryName: 'antd',
      libraryDirectory: 'es',
      style: 'css',
    }),
    // 默认路径设置
    addWebpackAlias({
      '@': path.resolve(__dirname, 'src'),
    }),
    hotLoader(),
    replaceConfig(),
    // 代码分片
    isProduction && setWebpackOptimizationSplitChunks({
      cacheGroups: {
        echarts: {
          test: /[\\/]node_modules[\\/](echarts)/,
          name: 'echarts',
          chunks: 'all',
        },
      },
    }),
    // 打包分析
    isProduction && addWebpackPlugin(new BundleAnalyzerPlugin()),
  )
}
package.json

修改package.json文件的scripts指令

{
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test"
  }
}
tsconfig.json

修改tsconfig.json文件。目的是配合上面的addWebpackAlias,否则再项目中直接import("@/components")会报错

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@/*": [
            "src/*"
          ]
        }
    }
}

传送门

  • webpack-bundle-analyzer:打包分析
  • less-loader:支持less样式
  • babel-plugin-import
  • @babel/plugin-proposal-decorators:支持es7的装饰器
  • react-hot-loader