概要
minSize和maxSize分別表示chunk在被拆分之前的最小體積和最大體積。(maxSize可以小於minSize)
準備工作
- 目錄
root
——dist(打包之後的文件夾)
——node_modules(下載的包)
——src(項目腳本目錄)
————entry(入口點腳本)
————modules(入口點中引入的模塊)
——package.json(包管理文件)
——webpack.config.js(webpack配置文件)
- webpack配置
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: {
entry1: './src/entry/entry1.js',
entry2: './src/entry/entry2.js'
},
plugins: [
new CleanWebpackPlugin()
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
optimization: {
splitChunks: {
chunks: 'initial',
minSize: 1,
maxSize: 0,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 1,
priority: -20,
reuseExistingChunk: true
}
}
}
}
// default config
// optimization: {
// splitChunks: {
// chunks: 'async',
// minSize: 30000,
// minChunks: 1,
// maxAsyncRequests: 5,
// maxInitialRequests: 3,
// automaticNameDelimiter: '~',
// automaticNameMaxLength: 30,
// name: true,
// cacheGroups: {
// vendors: {
// test: /[\\/]node_modules[\\/]/,
// priority: -10
// },
// default: {
// minChunks: 2,
// priority: -20,
// reuseExistingChunk: true
// }
// }
// }
// }
}
- package.json
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10"
}
}
案例
- demo1
################################
webpack.config.js:
splitChunks.maxSize設爲add.js的大小(單位爲字節byte)
splitChunks.minSize設爲1
################################
modules/add.js:(實際測試時通過註釋使得文件大小增大)
export default function add (a, b) {
return a + b
}
################################
modules/subtract.js
export default function subtract (a, b) {
return a - b
}
################################
entry/entry1.js:
import add from '../modules/add.js'
console.log('index', add(1, 2))
################################
entry/entry2.js:
import add from '../modules/add'
console.log('index', add(1, 2))
打包之後,結果爲:
Hash: 358a729f95a5c6891684
Version: webpack 4.41.5
Time: 203ms
Built at: 2020/01/31 下午2:56:45
Asset Size Chunks Chunk Names
default~entry1~entry2.bundle.js 151 bytes 0 [emitted] default~entry1~entry2
entry1.bundle.js 1.55 KiB 1 [emitted] entry1
entry2.bundle.js 1.56 KiB 2 [emitted] entry2
Entrypoint entry1 = default~entry1~entry2.bundle.js entry1.bundle.js
Entrypoint entry2 = default~entry1~entry2.bundle.js entry2.bundle.js
[0] ./src/modules/add.js 1.92 KiB {0} [built]
[1] ./src/entry/entry1.js 68 bytes {1} [built]
[2] ./src/entry/entry2.js 65 bytes {2} [built]
假設add.js體積大小爲n,如果將minSize設爲n+1時,打包結果爲:
Hash: 96013ae2b6f35e4252f0
Version: webpack 4.41.5
Time: 73ms
Built at: 2020/01/31 下午3:01:48
Asset Size Chunks Chunk Names
default~entry1.bundle.js 237 bytes 0 [emitted] default~entry1
default~entry2.bundle.js 238 bytes 1 [emitted] default~entry2
entry1.bundle.js 1.47 KiB 2 [emitted] entry1
entry2.bundle.js 1.47 KiB 3 [emitted] entry2
Entrypoint entry1 = default~entry1.bundle.js entry1.bundle.js
Entrypoint entry2 = default~entry2.bundle.js entry2.bundle.js
[0] ./src/modules/add.js 1.92 KiB {0} {1} [built]
[1] ./src/entry/entry1.js 68 bytes {0} [built]
[2] ./src/entry/entry2.js 65 bytes {1} [built]
當minSize設爲n+1時,n < n + 1,沒有達到最小值,所以add.js沒有被單獨打包出來。
- demo2
################################
webpack.config.js:
splitChunks.maxSize設爲add.js和entry1.js的大小之和(單位爲字節byte)
splitChunks.minSize設爲1
################################
modules/add.js:(實際測試時通過註釋使得文件大小增大)
export default function add (a, b) {
return a + b
}
################################
modules/subtract.js
export default function subtract (a, b) {
return a - b
}
################################
entry/entry1.js:
import add from '../modules/add.js'
console.log('index', add(1, 2))
################################
entry/entry2.js:
import subtract from '../modules/subtract'
console.log('index', subtract(1, 2))
打包結果如下:
Hash: f54c64d4b9d87060c46d
Version: webpack 4.41.5
Time: 75ms
Built at: 2020/01/31 下午3:13:24
Asset Size Chunks Chunk Names
default~entry1.bundle.js 123 bytes 0 [emitted] default~entry1
entry1.bundle.js 1.47 KiB 1 [emitted] entry1
entry2.bundle.js 976 bytes 2 [emitted] entry2
Entrypoint entry1 = default~entry1.bundle.js entry1.bundle.js
Entrypoint entry2 = entry2.bundle.js
[0] ./src/entry/entry2.js + 1 modules 139 bytes {2} [built]
| ./src/entry/entry2.js 80 bytes [built]
| ./src/modules/subtract.js 59 bytes [built]
[1] ./src/entry/entry1.js + 1 modules 1.98 KiB {0} [built]
| ./src/entry/entry1.js 65 bytes [built]
| ./src/modules/add.js 1.92 KiB [built]
如果將minSize再加1,打包結果如下:
Hash: 573ca79b89928f028819
Version: webpack 4.41.5
Time: 73ms
Built at: 2020/01/31 下午3:17:18
Asset Size Chunks Chunk Names
entry1.bundle.js 976 bytes 0 [emitted] entry1
entry2.bundle.js 977 bytes 1 [emitted] entry2
Entrypoint entry1 = entry1.bundle.js
Entrypoint entry2 = entry2.bundle.js
[0] ./src/entry/entry1.js + 1 modules 1.98 KiB {0} [built]
| ./src/entry/entry1.js 65 bytes [built]
| ./src/modules/add.js 1.92 KiB [built]
[1] ./src/entry/entry2.js + 1 modules 139 bytes {1} [built]
| ./src/entry/entry2.js 80 bytes [built]
| ./src/modules/subtract.js 59 bytes [built]
可以看到沒有被打包出來。
- demo3
前面幾個案例,我們的maxSize都是設爲0,即小於minSize,那麼如果設爲非0數值,並且值小於minSize呢,效果是否是一樣的呢?
基於demo1,我們將minSize設爲add.js的體積大小,maxSize設爲10:
################################
webpack.config.js:
splitChunks.maxSize設爲add.js的大小(單位爲字節byte)
splitChunks.minSize設爲10
################################
modules/add.js:(實際測試時通過註釋使得文件大小增大)
export default function add (a, b) {
return a + b
}
################################
modules/subtract.js
export default function subtract (a, b) {
return a - b
}
################################
entry/entry1.js:
import add from '../modules/add.js'
console.log('index', add(1, 2))
################################
entry/entry2.js:
import add from '../modules/add'
console.log('index', add(1, 2))
打包結果如下:
Hash: d922cb840f250b349314
Version: webpack 4.41.5
Time: 192ms
Built at: 2020/01/31 下午3:30:31
Asset Size Chunks Chunk Names
default~entry1~entry2~100271bb.bundle.js 151 bytes 0 [emitted] default~entry1~entry2~100271bb
entry1~14905de4.bundle.js 1.55 KiB 1 [emitted] entry1~14905de4
entry2~f28393c0.bundle.js 1.56 KiB 2 [emitted] entry2~f28393c0
Entrypoint entry1 = default~entry1~entry2~100271bb.bundle.js entry1~14905de4.bundle.js
Entrypoint entry2 = default~entry1~entry2~100271bb.bundle.js entry2~f28393c0.bundle.js
[0] ./src/modules/add.js 1.92 KiB {0} [built]
[1] ./src/entry/entry1.js 65 bytes {1} [built]
測試時我們的add.js體積大小爲1963byte,所以minSize設置成了1963,同時maxSize設置成10,通過結果可以發現add.js仍然被打包出來,和demo1唯一的不同點是,打包出來的文件名多了一個~連接的後綴部分。
所以,max設置成0和非0是有區別的。
- demo4
################################
webpack.config.js:
splitChunks.maxSize設爲add.js和entry1.js的大小之和(單位爲字節byte)
splitChunks.minSize設爲10
################################
modules/add.js:(實際測試時通過註釋使得文件大小增大)
export default function add (a, b) {
return a + b
}
################################
modules/subtract.js
export default function subtract (a, b) {
return a - b
}
################################
entry/entry1.js:
import add from '../modules/add.js'
console.log('index', add(1, 2))
################################
entry/entry2.js:
import subtract from '../modules/subtract'
console.log('index', subtract(1, 2))
打包報錯,具體原因個人不是很清楚。
基於前面四個案例,我們可以得出以下兩點:
a. maxSize默認爲0,表示最大體積沒有限制;
b. 如果設置的maxSize爲非0值,儘量保證 > minSize,< minSize可能導致腳本報錯;
- demo5
按正常的邏輯,我們讓maxSize > minSize,來看看打包的結果:
################################
webpack.config.js:
splitChunks.maxSize設爲add.js的大小(單位爲字節byte)
splitChunks.minSize設爲1
################################
modules/add.js:(實際測試時通過註釋使得文件大小增大)
export default function add (a, b) {
return a + b
}
################################
modules/subtract.js
export default function subtract (a, b) {
return a - b
}
################################
entry/entry1.js:
import add from '../modules/add.js'
console.log('index', add(1, 2))
################################
entry/entry2.js:
import add from '../modules/add'
console.log('index', add(1, 2))
打包後結果爲:
Hash: 67137a86f859192e20c3
Version: webpack 4.41.5
Time: 203ms
Built at: 2020/01/31 下午6:14:26
Asset Size Chunks Chunk Names
default~entry1~14905de4.bundle.js 147 bytes 1 [emitted] default~entry1~14905de4
default~entry1~entry2~100271bb.bundle.js 151 bytes 0 [emitted] default~entry1~entry2~100271bb
default~entry2~f28393c0.bundle.js 148 bytes 2 [emitted] default~entry2~f28393c0
entry1.bundle.js 1.47 KiB 3 [emitted] entry1
entry2.bundle.js 1.47 KiB 4 [emitted] entry2
Entrypoint entry1 = default~entry1~entry2~100271bb.bundle.js default~entry1~14905de4.bundle.js entry1.bundle.js
Entrypoint entry2 = default~entry1~entry2~100271bb.bundle.js default~entry2~f28393c0.bundle.js entry2.bundle.js
[0] ./src/modules/add.js 1.92 KiB {0} [built]
[1] ./src/entry/entry1.js 65 bytes {1} [built]
[2] ./src/entry/entry2.js 65 bytes {2} [built]
那麼如果將maxSize減1呢,也就是add.js的體積大小會大於maxSize,我們的正常邏輯思想是add.js不會被打包出來,但是結果確實和上面一樣的結果。
於是我們翻看官方文檔看看:
tells webpack to try to split chunks bigger than maxSize bytes into smaller parts.(用於告訴webpack試圖將大於maxSize的chunk拆分成更小的部分。)
這個是官方文檔中的一句話,所以我在想,正常情況下,拆分的chunk如果包含多個模塊,那麼當maxSize設爲比這個chunk小時,這個chunk會不會被拆分成多個模塊呢。
- demo6
################################
webpack.config.js:
splitChunks.maxSize設爲0
splitChunks.minSize設爲1
################################
modules/add.js:(實際測試時通過註釋使得文件大小增大)
export default function add (a, b) {
return a + b
}
################################
modules/subtract.js
export default function subtract (a, b) {
return a - b
}
################################
entry/entry1.js:
import add from '../modules/add'
import subtract from '../modules/subtract'
console.log('index', add(1, 2) + subtract(3, 0))
################################
entry/entry2.js:
console.log('index', 1)
打包後結果爲:
Hash: 03737457923b3e2fc080
Version: webpack 4.41.5
Time: 207ms
Built at: 2020/02/01 上午10:56:53
Asset Size Chunks Chunk Names
default~entry1.bundle.js 154 bytes 0 [emitted] default~entry1
default~entry2.bundle.js 98 bytes 1 [emitted] default~entry2
entry1.bundle.js 1.47 KiB 2 [emitted] entry1
entry2.bundle.js 1.47 KiB 3 [emitted] entry2
Entrypoint entry1 = default~entry1.bundle.js entry1.bundle.js
Entrypoint entry2 = default~entry2.bundle.js entry2.bundle.js
[0] ./src/entry/entry2.js 96 bytes {1} [built]
[1] ./src/entry/entry1.js + 2 modules 2.1 KiB {0} [built]
| ./src/entry/entry1.js 125 bytes [built]
| ./src/modules/add.js 1.92 KiB [built]
| ./src/modules/subtract.js 59 bytes [built]
default~entry1.bundle.js包含了add.js和subtract.js。
如果把maxSize設置爲10呢,結果如何?
結果如下:
Hash: 798f35edfa0accbcef6c
Version: webpack 4.41.5
Time: 75ms
Built at: 2020/02/01 上午11:07:06
Asset Size Chunks Chunk Names
default~entry1~100271bb.bundle.js 151 bytes 0 [emitted] default~entry1~100271bb
default~entry1~14905de4.bundle.js 172 bytes 1 [emitted] default~entry1~14905de4
default~entry1~b912b7e2.bundle.js 152 bytes 2 [emitted] default~entry1~b912b7e2
default~entry2~f28393c0.bundle.js 100 bytes 3 [emitted] default~entry2~f28393c0
entry1.bundle.js 1.47 KiB 4 [emitted] entry1
entry2.bundle.js 1.47 KiB 5 [emitted] entry2
Entrypoint entry1 = default~entry1~14905de4.bundle.js default~entry1~100271bb.bundle.js default~entry1~b912b7e2.bundle.js entry1.bundle.js
Entrypoint entry2 = default~entry2~f28393c0.bundle.js entry2.bundle.js
[0] ./src/modules/add.js 1.92 KiB {0} [built]
[1] ./src/modules/subtract.js 59 bytes {2} [built]
[2] ./src/entry/entry1.js 125 bytes {1} [built]
[3] ./src/entry/entry2.js 96 bytes {3} [built]
可以看到原來的default~entry1.bundle.js又另外單獨拆分除了add.js和subtract.js。
擴展
之前的案例中我們發現只要應用了maxSize配置(maxSize配置爲非0數值並且打包成功),那麼被拆分出來的bundle文件名都包含了隨機串的某個後綴,如上面的~100271bb。
這個隨機串是什麼?
When the chunk has a name already, each part will get a new name derived from that name. Depending on the value of optimization.splitChunks.hidePathInfo it will add a key derived from the first module name or a hash of it.
意思大概是這樣的:如果不受maxSize影響,拆分的chunk已經有一個名字name。而當我們應用了maxSize時,基於原來chunk拆分出來的bundle,它們的名稱將基於name進行派生,原理是webpack會基於splitChunks.hidePathInfo生成一個key(基於模塊名或者模塊的hash派生),這個key會被添加進name中,這個key個人猜測就是之前案例中的~100271bb,它或許是對應的bundle生成的hash值的前幾位數字或字符。
總結
- minSize表示被拆分出的bundle在拆分之前的體積的最小數值,只有 >= minSize 的bundle會被拆分出來;
- maxSize表示被拆分出的bundle在拆分之前的體積的最大數值,默認值爲0,表示bundle在拆分前的體積沒有上限;
- maxSize如果爲非0值時,切忌小於minSize;
- 如果bundle在被拆分前的體積大於maxSize,webpack將會嘗試將它拆分成更小的模塊(前提是bundle在拆分之前由多個模塊組成,如果僅僅只包含一個模塊,大於maxSize和大於minSize小於等於maxSize是一樣的效果);
- 應用maxSize打包的bundle其名稱會由“不應用maxSize時產生的bundle名稱”和“一個生成的key值”組成;
- maxSize對於直接引入(import或require引入)的部分或者按需引入的部分都有效,不過有些許區別,按需引入的包如果被拆分則使用chunk的名稱作爲bundle名,不會像前面的案例那樣包含一些key,如果非按需引入的部分包含於入口點名稱構建的bundle時,該bundle名稱將包含前面案例中類似的key;
- minSize對於按需引入的部分是沒有效的,因爲無論在什麼情況下,按需引入的部分都會被拆分打包出來;
last(最後)
非常感謝您能閱讀完這篇文章,您的閱讀是我不斷前進的動力。如果上述內容或許有些錯誤或者有些個人理解比較偏離實際,還望指出,謝謝!!!對於上面所述,有什麼新的觀點或發現有什麼錯誤,希望您能指出。
最後,附上個人常逛的社交平臺:
知乎:https://www.zhihu.com/people/bi-an-yao-91/activities
csdn:https://blog.csdn.net/YaoDeBiAn
github: https://github.com/yaodebian個人目前能力有限,並沒有自主構建一個社區的能力,如有任何問題或想法與我溝通,請通過上述某個平臺聯繫我,謝謝!!!