您好,登錄后才能下訂單哦!
小編給大家分享一下webpack4之splitchunksPlugin代碼包分拆的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
項目框架
項目有home和topic兩個入口文件,主要包括:
react、mobx、antd作為項目的基本框架,
echarts和d3(畫圖)是項目中部分頁面用到比較大的組件庫
src下的工作的組件和代碼
其他的非公共代碼。
兩個入口文件都用react-loadable做了異步加載
import Loadable from 'react-loadable'; ... const LoadableLogin = Loadable({ loader: () => import('../../common/components/login'), loading: Loading, }); ...
webpack部分配置相關如下:
module.exports = { ... mode: 'production', entry: { // 多入口 home: './src/home', topic: './src/topic', }, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath, }, plugins: [ new HtmlWebpackPlugin({ // home頁面 filename: 'home.html', template: './template.html', }), new HtmlWebpackPlugin({ // topic頁面 filename: 'topic.html', template: './template.html', inject: true, }), ], ... }
splitChunks
chunks:
all: 不管文件是動態還是非動態載入,統一將文件分離。當頁面首次載入會引入所有的包
async: 將異步加載的文件分離,首次一般不引入,到需要異步引入的組件才會引入。
initial:將異步和非異步的文件分離,如果一個文件被異步引入也被非異步引入,那它會被打包兩次(注意和all區別),用于分離頁面首次需要加載的包。
minSize: 文件最小打包體積,單位byte,默認30000
比如說某個項目下有三個入口文件,a.js和b.js和c.js都是100byte,當我們將minSize設置為301,那么webpack就會將他們打包成一個包,不會將他們拆分成為多個包。
比如說某個項目下有三個入口文件,a.js和b.js和c.js都是100byte,當我們將minSize設置為301,那么webpack就會將他們打包成一個包,不會將他們拆分成為多個包。
automaticNameDelimiter: 連接符
假設我們生成了一個公用文件名字叫vendor,a.js,和b.js都依賴他,并且我們設置的連接符是"~"那么,最終生成的就是 vendor~a~b.js
maxInitialRequests 入口點處的最大并行請求數,默認為3
如果我們設置為1,那么每個入口文件就只會打包成為一個文件
maxAsyncRequests 最大異步請求數量,默認5
如果我們設置為1,那么每個入口文件就只會打包成為一個文件
優先級關系
maxInitialRequest / maxAsyncRequests <maxSize <minSize。
cacheGroups 定制分割包的規則
test可以配置正則和寫入function作為打包規則。其他屬性均可繼承splitChunks,這里必須說一下 priority,設置包的打包優先級,非常重要! (后面結合實踐)
minChunks
最少引入的次數
實踐
我們以一個最簡單的配置開始,將公共代碼打包出來
splitChunks: { chunks: 'all', // initial、async和all minSize: 30000, // 形成一個新代碼塊最小的體積 maxAsyncRequests: 5, // 按需加載時候最大的并行請求數 maxInitialRequests: 3, // 最大初始化請求數 automaticNameDelimiter: '~', // 打包分割符 name: true, cacheGroups: { vendors: { // 打包兩個頁面的公共代碼 minChunks: 2, // 引入兩次及以上被打包 name: 'vendors', // 分離包的名字 chunks: 'all' }, } },
兩個入口文件的公共代碼被打包到vendor文件夾下面,包括echarts d3 amcharts等一些三方包和src下的公共代碼。
這當然不是我們想要的結果!存在以下問題:
其實當我們進入網站,一般第一步都是進入一個登陸頁面,需要的只是項目的基本框架代碼,例如react,react-dom.antd等,我們可以用all(或者initial)將它們單獨打包,作為首頁必須載入的包
我們打包的公共包,首次加載頁面的時候,只想把同步加載的加載進來,所以需要一個同步的Common包
像echarts,d3,以及一些src下面一些異步加載的包,將它們利用async將打包成一個獨立異步加載包
我們修改cacheGroups為:
cacheGroups: { vendors: { // 項目基本框架等 chunks: 'all', test: /(react|react-dom|react-dom-router|babel-polyfill|mobx)/, priority: 100, name: 'vendors', }, 'async-commons': { // 異步加載公共包、組件等 chunks: 'async', minChunks: 2, name: 'async-commons', priority: 90, }, commons: { // 其他同步加載公共包 chunks: 'all', minChunks: 2, name: 'commons', priority: 80, }, }
這次webpack幫我們打出來的包主要有:
async-common:是兩個入口文件都異步加載的三方包和利用react-loader做的懶加載代碼,有echarts,d3等
vendors: 包括react,react-dom,antd等
commons: 引用超過兩次的同步代碼
這里說兩個需要注意的地方:
注意這里我們priority的設置,vendors>async-commons>commons,我們首先將react,react-dom等優先打包出來,然后再打包公共部分,如果將vendors的優先級設置小于兩個Common的優先級,那么react,react-dom將會打包到common包,將不會再生成vendors包。
如果我們這里將commons的配置去掉,將會生成一個topic~home的包,我們配置了async-common提取出異步加載的公共包后,將會默認將同步加載的公共包打包生成以automaticNameDelimiter連接符‘~'生成的名字'topic~home'包,內容其實和commons包內容完全一樣,
ok!按照我們的要求,這樣首次頁面加載只會引入vendors,commons包,而不會引入async-common包,還是挺棒的!追求更精致的我們,再認真想想,是不是還可以做一些更好的優化?
到目前為止我們打包文件的打包是這樣的:
用gzip壓縮后,最大的async-common包有391kb。公司說最近因為一些狀況,布置到生產后速度慢的時候,有時候只能有20kb/s的下載速度==。。。。于是繼續split!
分析一下:
async-common中包含了自己寫的src組件和第三方組件
async-common中比較大是echarts,zrender(echarts引入)和d3,結合項目來說,只有部分頁面我們需要echarts(d3同),所以我們可以考慮將d3和echarts這兩個比較大的包提取出來,等到某個頁面需要的時候,再讓其異步加載,這樣就大大減小了async-common的體積了。
修改
cacheGroups: { vendors: { // 基本框架 chunks: 'all', test: /(react|react-dom|react-dom-router|babel-polyfill|mobx)/, priority: 100, name: 'vendors', }, d3Venodr: { // 將體積較大的d3單獨提取包,指定頁面需要的時候再異步加載 test: /d3/, priority: 100, // 設置高于async-commons,避免打包到async-common中 name: 'd3Venodr', chunks: 'async' }, echartsVenodr: { // 異步加載echarts包 test: /(echarts|zrender)/, priority: 100, // 高于async-commons優先級 name: 'echartsVenodr', chunks: 'async' }, 'async-commons': { // 其余異步加載包 chunks: 'async', minChunks: 2, name: 'async-commons', priority: 90, }, commons: { // 其余同步加載包 chunks: 'all', minChunks: 2, name: 'commons', priority: 80, }, }
當然,每次修改后,需要在htmlWebpackPlugin中配置chunk需要的包
plugins: [ new HtmlWebpackPlugin({ // home頁面 filename: 'home.html', template: './template.html', chunks: ['vendors', 'commons', 'home'], }), new HtmlWebpackPlugin({ // topic頁面 filename: 'topic.html', template: './template.html', chunks: ['vendors', 'commons', 'topic'], }), ],
后期還做了其他的拆分和優化,大概最大的包保持在100k左右,當然也不建議拆的特別小,因為瀏覽器http1可能一次性支持6次下載文件,太多可能會適得其反。大家可以根據自己的項目做不同的拆分方法,總而言之,就是為了讓項目更完美的在線上運行,給用戶更好的體驗~
以上是“webpack4之splitchunksPlugin代碼包分拆的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。