這篇文章主要介紹了Webpack的Bundle Split和Code Split有哪些區別,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
雙峰網站建設公司創新互聯建站,雙峰網站設計制作,有大型網站制作公司豐富經驗。已為雙峰數千家提供企業網站建設服務。企業網站搭建\成都外貿網站建設要多少錢,請找那個售后服務好的雙峰做網站的公司定做!
Webpack 文件分離包括兩個部分,一個是 Bundle 的分離,一個是 Code 代碼的分離:
Bundle splitting: 實際上就是創建多個更小的文件,并行加載,以獲得更好的緩存效果;主要的作用就是使瀏覽器并行下載,提高下載速度。并且運用瀏覽器緩存,只有代碼被修改,文件名中的哈希值改變了才會去再次加載。
Code splitting: 只加載用戶最需要的部分,其余的代碼都遵從懶加載的策略;主要的作用就是加快頁面加載速度,不加載不必要加載的東西。
準備工作
在進行文件分離之前的準備工作,我們先寫一些代碼:
入口文件 src/index.js:
const { getData } = require('./main')
const { findMaxIndex } = require('./math')
let arr = [1,2,123,21,3,21,321,1]
findMaxIndex(arr)
getData('./index.html')兩個依賴模塊:
src/main.js:
const axios = require('axios')
const getData = url => {
axios.get(url).then(d => {
console.log(d.status)
console.log(d.data.length)
})
}
module.exports = {
getData
}src/math.js:
const _ = require('lodash')
const findMaxIndex = arr => {
let x = _.max(arr)
let r = Array.prototype.indexOf.call(arr, x)
console.log(r);
}
module.exports = {
findMaxIndex
}增加一個 webpack 配置文件 webpack.config.js:
const path = require('path')
module.exports = {
mode: 'development',
entry: path.resolve(__dirname, 'src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
},
}文件分離之前打包需要的時間
在 bundle split 和 code split 操作之前,我們先看一下當前默認打包的效果:

全部依賴都被打包到 main.xxx.js 中去,大小是 609k
開始分離操作
Bundle Split
Bundle Split 的主要任務是將多個引用的包和模塊進行分離,避免全部依賴打包到一個文件下
基本用法
Webpack 4 中需要使用到 optimization.splitChunks 的配置:
const path = require('path')
module.exports = {
mode: 'development',
entry: path.resolve(__dirname, 'src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
},
optimization: {
splitChunks: {
chunks: 'all'
}
}
}optimization.splitChunks 的意思是將所有來自 node_modules 中的依賴全部打包分離出來,這個時候我們再看打包的文件是個什么樣子:
增加了 splitChunks 的配置,我們第三方模塊都被打包到了 vendors~main.xxx.js 中去了,這個文件大小有 604k,而入口文件 main.xxx.js 則只有 7k
雖然說這樣將第三方模塊單獨打包出去能夠減小入口文件的大小,但這樣仍然是個不小的文件;這個小的測試項目中我們使用到了 axios 和 lodash 這兩個第三方模塊,因此我們希望的應該是將這兩個模塊單獨分離出來兩個文件,而不是全部放到一個 vendors 中去,那么我們繼續配置 webpack.config.js:
這里我們需要使用到 webpack.HashedModuleIdsPlugin 這個插件
參考官方文檔
直接上代碼:
const path = require('path')
const webpack = require('webpack')
module.exports = {
mode: 'development',
entry: path.resolve(__dirname, 'src/index.js'),
plugins: [
new webpack.HashedModuleIdsPlugin() // 根據模塊的相對路徑生成 HASH 作為模塊 ID
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all', // 默認 async 可選值 all 和 initial
maxInitialRequests: Infinity, // 一個入口最大的并行請求數
minSize: 0, // 避免模塊體積過小而被忽略
minChunks: 1, // 默認也是一表示最小引用次數
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/, // 如果需要的依賴特別小,可以直接設置成需要打包的依賴名稱
name(module, chunks, chcheGroupKey) { // 可提供布爾值、字符串和函數,如果是函數,可編寫自定義返回值
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1] // 獲取模塊名稱
return `npm.${packageName.replace('@', '')}` // 可選,一般情況下不需要將模塊名稱 @ 符號去除
}
}
}
}
}
}這里我們主要做了幾件事:
為了避免每次打包的文件哈希變化,我們可以使用 webpack 內置的 HashedModuleIdsPlugin,這樣可以避免每次打包的文件哈希值變化首先增加 maxInitialRequests 并設置成 Infinity,指定這個入口文件最大并行請求數
然后將 minSize 和 minChunks 分別設置成 0 和 1,即使模塊非常小也將其提取出來,并且這個模塊的引用次數只有 1 也要提取
最后配置匹配的依賴以及分離出的文件名格式
另外,我們還將運行時代碼分離出來,這塊代碼還可以配合 InlineManifestWebpackPlugin直接插入到 HTML 文件中。這里我們將這個配置設置成 single,即將所有chunk的運行代碼打包到一個文件中
這樣 Bundle Split 的操作基本就完成了,讓我們看看效果如何:
.jpg)
所依賴的幾個模塊都被分離出去了
使用 HtmlWebpackPlugin 這個插件將 js 代碼注入 html 文件中
npm i -D html-webpack-plugin
修改 webpack.config.js 文件:
// 配置文件引入這個插件
var HtmlWebpackPlugin = require('html-webpack-plugin');
// ...
module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin(),
new webpack.HashedModuleIdsPlugin() // 根據模塊的相對路徑生成 HASH 作為模塊 ID
],
// ...
}安裝 http-server 或使用 vscode 的插件 Live Server 將代碼放入一個本地服務器中,打開瀏覽器的調試窗口進入到 Network 面板:

可以看到我們將模塊單獨分離出來并行加載,這樣比單獨加載一個龐大的包要快不少,接下來我們還要進行代碼分離,將不必要加載的模塊延遲加載
Code Split
代碼分離實際上就是只加載用戶需要使用到的部分代碼,不是必須的就暫時不加載。
這里我們要用到 require.ensure 這個方法去獲取依賴,這樣 webpack 打包之后將會增加運行時代碼,在設定好的條件下才會觸發獲取這個依賴。
在 ES6 中我們可以用 Dynamic Imports 來替代上述方案,如果使用 ES6 語法那么需要使用到 babel 以及 babel 的插件 plugin-syntax-dynamic-import,在瀏覽器中為了保證兼容性,還需要安裝 promise 的 polyfill,用法大同小異,可直接觀摩 webpack 的官方文檔修改我們的代碼:
const { getData } = require('./main')
let arr = [1,2,123,21,3,21,321,1]
getData('./index.html')
setTimeout(() => {
require.ensure(['./math'], function(require) {
const { findMaxIndex } = require('./math')
console.log(findMaxIndex(arr))
})
}, 3000)我們設定了一個定時器,只有在 3000 毫秒以后,瀏覽器才會去請求這個 math 模塊
編譯之后,打開調試面板刷新瀏覽器:

在頁面剛加載完畢后,瀏覽器會嘗試獲取上述這么幾個模塊,因為模塊都很小很快就加載完成了

在 3500ms 左右,瀏覽器才會去獲取 requie.ensure 方法定義的 math 模塊,因 math 模塊又包含依賴 lodash,因此這個 lodash 第三方模塊也會被按需加載。
這樣我們就完成了代碼分離的操作,這樣做的優勢就是不需要第一時間加載的模塊,可以推遲加載,以頁面的加載速度。當然,上面的 timeout 定時器完全可以換成其他諸如按鈕點擊之類的事件來觸發。
感謝你能夠認真閱讀完這篇文章,希望小編分享Webpack的Bundle Split和Code Split有哪些區別內容對大家有幫助,同時也希望大家多多支持創新互聯,關注創新互聯行業資訊頻道,遇到問題就找創新互聯,詳細的解決方法等著你來學習!
本文名稱:Webpack的BundleSplit和CodeSplit有哪些區別
標題URL:http://www.yijiale78.com/article0/ihdcio.html
成都網站建設公司_創新互聯,為您提供響應式網站、自適應網站、服務器托管、移動網站建設、網站設計、微信公眾號
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯