Create react App eject后 webpack 的優化配置


Create react App 是一個官方支持的創建 react 單頁應用程序的方法。它提供了一個零配置的現代構建設置。雖然開箱即用,但是開發中我們還是少不了做一些修改,下面總結了一些常用的配置,本文基於webpack4.44.2進行配置

關於eject

執行npm run eject命令會將react-scripts釋放到本地項目中,可以通過修改對應的文件完成配置。同時會刪除react-scripts依賴包,修改package.json中命令。命令執行完畢以后,我們就會看到本地項目中多出了scripts和config兩個目錄文件。同時,package.json文件命令也被修改了。

此時,如果在執行啟動或者打包命令,就是直接執行的scripts目錄下對應的文件了。我們可以很方便的根據需要修改對應的文件配置即可。
但值得注意的是,npm run eject命令是不可逆的,即執行之后不可恢復,這就造成了如果后續我們想通過腳手架的react-scripts包增加新的特性,比如PWA支持,是不可行的

關閉生產環境 sourcemap

通常在開發的時候,我們會配置開發環境生成 sourcemap 文件,方便調試,但是在生產環境都要關閉,避免代碼泄露和打包多余文件,體積太大。
可以在項目根目錄創建'.env'文件,配置如下內容:

//.env
GENERATE_SOURCEMAP=false

noParse

如果一些第三方模塊沒有AMD/CommonJS規范版本,可以使用 noParse 來標識這個模塊,這樣 webpack 會引入這些模塊,但是不進行轉化和解析,從而提升 webpack 的構建速度,例如:jquery 、lodash (被忽略的庫不能有import、require、define的引入方式),noParse 屬性的值是一個正則表達式或者是一個 function

//webpack.config.js
module.exports = {
    //...
    module: {
        noParse: /jquery|lodash/
    }
}

splitChunks抽取公共代碼

splitChunks可以抽取公共代碼,拆分業務代碼和第三方代碼庫,防止打包文件過大,代碼示例如下:

//webpack.config.js
optimization: {
    //...
    splitChunks: {
        chunks: 'all',
        minSize: 30000,         //字節 引入的文件大於30kb才進行分割
        minChunks: 1,           //模塊至少使用次數
        automaticNameDelimiter: '~', //緩存組和生成文件名稱之間的連接符
        name: true,
        cacheGroups: {
          vender: {
            name: 'vendor',
            test: /[\\/]node_modules[\\/]/,
            chunks: 'all',
            priority: 20          
          },
          react: {
            name: 'react',
            test: (module) => /react|redux/.test(module.context),
            chunks: 'initial',
            priority: 11
          },
          lodash: {
            name: 'lodash',
            test: (module) => /lodash/.test(module.context),
            chunks: 'initial',
            priority: 15 
          },
          antdm: {
            name: 'antd-mobile',
            test: (module) => /antd-mobile/.test(module.context),
            chunks: 'initial',
            priority: 12            
          }
        }
    }
}

thread-loader

webpack4 官方提供了一個thread loader,把這個 loader 放置在其他 loader 之前, 放置在這個 loader 之后的 loader 就會在一個單獨的 worker池里運行,一個worker 就是一個nodeJS 進程,每個單獨進程處理時間上限為600ms,各個進程的數據交換也會限制在這個時間內。
**注意:如果項目小,文件不多,無需開啟多進程打包,打開反而會變慢,因為開啟進程是需要花費時間的

  • 安裝依賴:
cnpm install thread-loader -D
  • webpack配置:
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve("src"),
        use: [
          "thread-loader",
          // your loader (e.g babel-loader)
        ]
      }
    ]
  }
}

HardSourceWebpackPlugin(用於開發環境,可以取代DllPlugin)

HardSourceWebpackPlugin 為模塊提供中間緩存,緩存默認的存放路徑是: node_modules/.cache/hard-source。
配置 hard-source-webpack-plugin,首次構建時間沒有太大變化,但是第二次開始,構建時間大約可以節約 80%。由於生產環境的打包次數有限,所以此插件主要用於開發環境,提升打包速度。與DllPlugin相比配置更加簡單,效率也更高。

  • 安裝依賴:
cnpm install hard-source-webpack-plugin -D
  • webpack 的配置:
//webpack.config.js
var HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.exports = {
    //...
    plugins: [
        //用於開發環境
        isEnvDevelopment &&
        new HardSourceWebpackPlugin()
    ]
}

HardSourceWebpackPlugin文檔
列出了一些你可能會遇到的問題以及如何解決,例如熱更新失效,或者某些配置不生效等。

webpack-bundle-analyzer

借助 webpack-bundle-analyzer 可以查看哪些包的體積較大,

  • 安裝依賴:
cnpm install webpack-bundle-analyzer -D
  • 配置如下:

//webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
    //....
    plugins: [
        //...
        new BundleAnalyzerPlugin(),
    ]
}

npm run build 構建,會默認打開: http://127.0.0.1:8888/,可以看到各個包的體積,進一步使用 splitChunks 進行拆分,打包后對比,優化完成后,上線前最好刪除此插件和配置

webpack自身的優化(已經默認開啟,無需配置)

  • tree-shaking
    如果使用ES6的import 語法,那么在生產環境下(mode:production),會自動移除沒有使用到的代碼。
  • scope hosting 作用域提升
    變量提升,可以減少一些變量聲明。在生產環境下,默認開啟。
  • 縮小文件匹配范圍(include/exclude)
  • 緩存loader的執行結果(cacheDirectory)
  • IgnorePlugin:webpack 的內置插件,作用是忽略第三方包指定目錄
    例如: moment (2.24.0版本) 會將所有本地化內容和核心功能一起打包,我們就可以使用 IgnorePlugin 在打包時忽略本地化內容。
    在使用的時候,如果我們需要指定語言,那么需要我們手動的去引入語言包,例如,引入中文語言包:
    import moment from 'moment';
    import 'moment/locale/zh-cn';// 手動引入
    
  • 多進程壓縮的優化:Webpack 默認使用的是 TerserWebpackPlugin,默認開啟了多進程和緩存,構建時,你的項目中可以看到 terser 的緩存文件 node_modules/.cache/terser-webpack-plugin,沒必要單獨安裝以下插件,webpack-parallel-uglify-plugin,uglifyjs-webpack-plugin 配置 parallel.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM