webpack里面有thunk和module概念,thunk對應(yīng)的是文件級別的, webpack代碼拆分中,很容易出現(xiàn)的問題就是,同一個模塊打包到多個thunk文件上面,thunk打包的成一個文件的原理是根據(jù) 依賴模塊不同抽分成一個thunk, 相關(guān)的依賴關(guān)系,不重復(fù)打包thunk
比如
webpack.ensure() {
require('./lib1.js')
require('./lib2.js')
require('./lib3.js')
}
webpack.ensure() {
require('./lib1.js')
require('./lib2.js')
require('./lib4.js')
}
上面會打包成兩個thunk , 第一個thunk里面包含 lib1和lib2, lib3 , 第二個thunk里面包含了lib1和lib2, lib4, 即lib1, lib2重復(fù)打包了。
既然重復(fù)打包了,那我們得考慮如何在代碼切分中,把lib1 和 lib2拆分出來,行成一個文件, 避免重復(fù)打包. 之前提供, webpack thunk是根據(jù) 依賴的關(guān)系決定thunk的,也就是說,如果thunk依賴相同,那么就不會重復(fù)打包thunk
webpack.ensure() {
require('./lib1.js')
require('./lib2.js')
webpack.ensure([], () => {
require('./lib3.js')
})
}
webpack.ensure() {
require('./lib1.js')
require('./lib2.js')
webpack.ensure([], () => {
require('./lib4.js')
})
}
上面的話,實(shí)際會打包出三個 thunk文件,第一含有 lib1 和 lib2 其他 兩個分別含 lib3 和 lib4。異步下載代碼的時候,會先下載 含有l(wèi)ib1和lib2的 thunk, 然后下載lib3或者lib4的thunk, 最后執(zhí)行我們的業(yè)務(wù)代碼,這樣的話,就不存在重復(fù)打包的文件了。
還有更好的么
上面的代碼其實(shí)很不優(yōu)雅, 層層嵌套webpack.ensure 不是一個好方案,對代碼維護(hù)來說,更加如此。其實(shí)我們可以利用promise, 對異步的庫進(jìn)行一層封裝
thunk.js
var resolve;
var reject;
var promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
require.ensure([], (require) => {
var lib2 = require('./lib2.js');
resolve(lib2);
});
module.exports = promise;
使用
require('./thunk.js').then((lib2) => {
console.log(lib2);
})
這樣的話,把異步庫單獨(dú)放在一個js文件夾,通過返回一個promise來進(jìn)行異步獲取,而且根據(jù)模塊機(jī)制,對promise對象進(jìn)行緩存,即一旦第一次導(dǎo)入了這個庫,以后都會從緩存中獲取。
ps: webpack 2.0其實(shí)已經(jīng)實(shí)現(xiàn)了 import 異步庫的功能,具體可以查看文檔