代碼分離
大型的web項(xiàng)目捷绒,將所有的代碼放到一個(gè)文件的做法效率很差,尤其是加載一些特定環(huán)境才會(huì)使用的代碼瘩扼。
webpack可以把代碼分離成chunk焚碌,不僅可以按需打包/按需加載,還可以實(shí)現(xiàn)提取公共代碼梦鉴。
定義分離點(diǎn)
AMD和CommonJs需要不同的方式來實(shí)現(xiàn)按需加載李茫,webpack通過定義分離點(diǎn)的方式,對(duì)兩者都支持肥橙。
CommonJs require.ensure(dependencies, callback)
dependencies
會(huì)在調(diào)用callback
時(shí)被同步的請(qǐng)求過來魄宏。
require
作為實(shí)參傳入到callback
函數(shù)。
require.ensure
僅加載模塊存筏,不執(zhí)行
require.ensure(
["module-a", "module-b"],
function(require) {
var a = require("module-a");
// ...
}
);
AMD require(dependencies, callback)
加載dependencies
宠互,并把他們作為實(shí)參傳入callback
require
加載并執(zhí)行模塊塔次,自左而右,callback可以為空
require(
['module-a', 'module-b'],
function(a, b) {
// ...
}
);
分離點(diǎn)的所有模塊都會(huì)被獨(dú)立成一個(gè)分塊名秀,依賴會(huì)被遞歸添加励负。如果分離點(diǎn)的callback是一個(gè)函數(shù),webpack會(huì)把該函數(shù)里的依賴都提取到按需加載的代碼塊中匕得。
- 如果分塊包含的模塊完全一致继榆,那么這兩個(gè)模塊會(huì)被合并成一個(gè),這意味著分塊可能被多個(gè)父模塊引用汁掠。
- 如果一個(gè)模塊在一個(gè)分塊的所有父模塊中可用略吨,那么它將會(huì)從該分塊中移除。
- 如果一個(gè)分塊包含了另一個(gè)分塊的所有模塊考阱,它將會(huì)被保存起來翠忠。
分塊類型
入口塊 entry chunk
一個(gè)入口塊包含運(yùn)行時(shí)和一系列模塊,如果一個(gè)入口塊包含了模塊0
乞榨,那么運(yùn)行時(shí)將會(huì)執(zhí)行這個(gè)模塊秽之,如果沒包含,那么將會(huì)等待包含了模塊0
的分塊吃既,然后執(zhí)行
普通塊 normal chunk
一個(gè)普通塊包含一系列模塊考榨,而不包含運(yùn)行時(shí)。
初始?jí)K initial chunk
一個(gè)初始?jí)K是一個(gè)普通的分塊鹦倚,不同的是會(huì)做特別優(yōu)化河质,因?yàn)檫@關(guān)系到首次加載時(shí)間的長短。這種分塊可以結(jié)合CommonChunksPlugin
來生成
多入口塊
每個(gè)入口塊都應(yīng)該包含運(yùn)行時(shí)震叙,但一個(gè)頁面只能有一個(gè)運(yùn)行時(shí)掀鹅,通過CommonsChunkPlugin
可以解決這個(gè)問題。
使用CommonsChunkPlugin
后媒楼,運(yùn)行時(shí)會(huì)被移到公共分塊中乐尊,從而可以在同一個(gè)頁面使用多個(gè)入口塊。
{
entry: { a: "./a", b: "./b" },
output: { filename: "[name].js" },
plugins: [new webpack.optimize.CommonsChunkPlugin("init.js")]
}
<script src="init.js"></script>
<script src="a.js"></script>
<script src="b.js"></script>
擴(kuò)展問題
公共塊
使用 CommonsChunkPlugin
使用把多個(gè)入口塊的公共模塊移到一個(gè)新的入口塊(公共塊)同時(shí)也會(huì)把運(yùn)行時(shí)移到公共塊匣砖,這意味著原始入口塊變成了初始?jí)K
優(yōu)化
根據(jù)具體的場(chǎng)景使用不同的優(yōu)化插件來合并分塊
LimitChunkCountPlugin
MinChunkSizePlugin
AggressiveMergingPlugin