react專案配置(less配置,別名配置,antd配置,跨域代理,壓縮資源配置等)

在react腳手架中修改配置有兩種方式

  1. 使用npm eject 命令 將配置跳出來(不推薦,不優雅)
  2. 使用customize-cra 來新增一個config-overrides.js檔案 來進行專案配置

接下來,主要使用第二種方式把一些專案開發中常見配置給紀錄一下

首先 先安裝 必要的兩個依賴

1
yarn add custom-cra react-app-rewired  -dev

然後,修改package.json的配置

1
2
3
4
5
6
"scripts": {<!-- -->
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  },

然後在專案根目錄新建config-overrides.js檔案,以下是我專案實作中使用的一些配置,使用的一些依賴這裡就不列了,自己去安裝吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
const path = require('path')
const fs = require('fs')
const webpack = require('webpack')
const CompressionWebpackPlugin = require('compression-webpack-plugin') // 壓縮gzip檔案外掛
const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin') // 使用day.js代替moment.js,減少程式碼包體積
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin') // 採用快取提升打包速度
const ProgressBarPlugin = require('progress-bar-webpack-plugin') // 開啟打包和開發進度條
const {<!-- --> LifeCycleWebpackPlugin } = require('lifecycle-webpack-plugin') // webpack生命週期
const CleanWebpackPlugin = require('clean-webpack-plugin') // 清除上次打包的資料夾
const {<!-- --> BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') // 檢視打包後各依賴體積
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin') // 檢視打包過程中的時間花費
const smp = new SpeedMeasurePlugin()
const rewireReactHotLoader = require('react-app-rewire-hot-loader')

const {<!-- -->
  override,
  fixBabelImports,
  addLessLoader,
  addWebpackAlias,
  overrideDevServer,
  addWebpackPlugin
} = require('customize-cra')
const isProduction = process.env.NODE_ENV === 'production'
let analyzer_type = process.env.ANALYZER_ENV
// 熱跟新
const hotLoader = () => (config, env) => {<!-- -->
  config = rewireReactHotLoader(config, env)
  return config
}
const config = {<!-- -->
  webpack: override(
    // 新增解析less配置
    addLessLoader({<!-- -->
      modifyVars: {<!-- --> '@primary-color': '#3377FF' }, // 配置antd主題顏色
      javascriptEnabled: true
    }),
    // 開啟熱更新
    hotLoader(),
    // 配置按需引入,antd4版本js模組自動tree-shaking,但是css沒有
    fixBabelImports('import', {<!-- -->
      libraryName: 'antd',
      style: true
    }),
    // 別明配置
    addWebpackAlias({<!-- -->
      '@': path.resolve(__dirname, './src'),
      'react-dom': '@hot-loader/react-dom'
    }),
    addWebpackPlugin(
      // 配置環境變數
      new webpack.DefinePlugin({<!-- -->
        'process.env.BASE_ENV': JSON.stringify(process.env.BASE_ENV)
      })
    ),
    // 使用day.js代替moment.js,減少程式碼包體積
    // addWebpackPlugin(new AntdDayjsWebpackPlugin()),
    addWebpackPlugin(
      // 新增打包進度條
      new ProgressBarPlugin()
    ),
    analyzer_type &&
      addWebpackPlugin(
        new BundleAnalyzerPlugin({<!-- -->
          analyzerPort: 8889, // 指定埠號
          openAnalyzer: true
        })
      ),
    isProduction &&
      addWebpackPlugin(
        new CompressionWebpackPlugin({<!-- -->
          filename: '[path].gz[query]',
          algorithm: 'gzip',
          test: /.(js|css)$/,
          cache: true,
          threshold: 10240, //衹有大小大於該值的資源會被處理。預設值是 10k
          minRatio: 0.8 //衹有壓縮率小於這個值的資源才會被處理,預設值是 0.8
        })
      ),
    // 開啟快取壓縮
    // isProduction && addWebpackPlugin(new HardSourceWebpackPlugin()),
    // 每次打包都清空dist檔案
    isProduction && addWebpackPlugin(new CleanWebpackPlugin([path.resolve(__dirname, 'dist')])),
    // 打包完成後更改build名稱為dist
    isProduction &&
      addWebpackPlugin(
        // webpack生命週期
        new LifeCycleWebpackPlugin({<!-- -->
          done: (compiler) => {<!-- -->
            setTimeout(() => {<!-- -->
              fs.renameSync(path.resolve(__dirname, 'build'), path.resolve(__dirname, 'dist'))
            }, 100)
          }
        })
      ),
    // 可以在此處修改webpack配置
    (config) => {<!-- -->
      if (config.mode === 'production') {<!-- -->
        config.devtool = false // 取消js map檔案
        config.optimization.minimizer[1].options.cssProcessorOptions.map = false // 取消css map檔案
        config.optimization.minimizer[0].options.terserOptions.compress.drop_console =
          process.env.BASE_ENV === 'production' //生產環境去除console
        config.optimization.splitChunks = {<!-- -->
          cacheGroups: {<!-- -->
            // vendor: {<!-- -->
            //   test: /node_modules/,
            //   name: 'vendors',
            //   minChunks: 2,
            //   chunks: 'all',
            //   minSize: 0,
            //   priority: 1
            // },
            common: {<!-- -->
              name: 'commons',
              minChunks: 2,
              chunks: 'all',
              minSize: 0
              // priority: 0
            }
          }
        }
      }
      // 是否新增分析打包時間
      return analyzer_type ? smp.wrap(config) : config
    }
  ),
  // 開發環境配置
  devServer: overrideDevServer((config) => {<!-- -->
    config.proxy = {<!-- -->
      '/api': {<!-- -->
        target: '*********',
        changeOrigin: true,
        secure: false,
        pathRewrite: {<!-- -->
          '^/api': ''
        }
      }
    }
    return config
  })
}

module.exports = config