媒介
code-splitting是webpack最引人矚目的特性之一,此特性將代碼星散到差別的bundle文件中。細緻引見官網code-split,此次完成則在筆者上次文件打包之上做開闢。
功用分析
官網上有三種體式格局完成
- 進口出發點:運用 entry 選項手動星散代碼。
- 防備反覆:運用 CommonsChunkPlugin 去重和星散 chunk。
- 動態導入:經由過程模塊的內聯函數調用來星散代碼。
1實質則是多個進口的chunk,2則在以common.js為進口文件,將多進口的chunk切分為按切割文件,經由過程jsonp加載。在這裏筆者則引見最為龐雜的3的完成,
關於webpack 的切割文件的引入實質就是jsonp,動態引入一個約定好花樣的js,並運轉。
__webpack_require__.e = function requireEnsure(chunkId) {
....
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.src = __webpack_require__.p + "" + chunkId + ".bundle.js";
head.appendChild(script);
....
}
切割文件去除解釋以下:
webpackJsonp([1],[function(){},function(){}])
而在進口文件的webpackJsonpCallback函數內,則是將切割的文件包括的modules順次放入存儲在modules內
function webpackJsonpCallback(chunkIds, moreModules){
....
for(moduleId in moreModules) {
if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
modules[moduleId] = moreModules[moduleId];
}
}
}
....
所以完成以上功用需求以下:
- parse模塊:定位切割點並組裝異步加載文件所須要的依靠。
- chunks模塊:各個chunk包括module模塊的鳩合,經由過程文件樹內里模塊的依靠關聯天生。
- writeChunks模塊:依據chunks,經由過程文件流寫入文件。
例子
require('d');
function a() {
require.ensure(['./a'], function () {
require('c');
});
}
require.ensure(['./b'], function () {
require('./m');
});
require('./e');
完成
parse模塊
完成思緒:
- 經由過程遞歸,以及文件樹的特性定位到require.ensure
- 將arguments第一個參數的數組,第二個參數的函數內遞歸搜刮require,存入數組asyncs內,並遞歸下去
數據結構以下:
{
filename: '/Users/zhujian/Documents/workspace/webpack/simple-webpack/example/main.js',
id: 0,
requires: [{
name: 'd',
range: [8, 11],
id: 1
}],
rangeRequires: [[0, 7]],
asyncs: [{
requires: [{
name: './a',
id: 2
}, {
name: 'c',
range: [88, 91],
id: 3
}],
asyncs: [],
rangeRequires: [80, 87],
ensureRequires: [34, 58]
},
{
requires: [{
name: './b',
id: 4
}, {
name: './m',
range: [156, 161],
id: 5
}],
asyncs: [],
rangeRequires: [148, 155],
ensureRequires: [106, 130]
}],
}
chunks模塊
因為各個依靠文件的源碼都包括在modlues內,所以chunks包括的是詳細各個切割文件所包需module的moduleId。
完成思緒:
- 經由過程進口mainPath 找到modules的進口mainModule
- 將mainModule 的requires遍歷,將值歸入本chunk的modules內,將asyncs遍歷,順次新建chunk,並關聯父chunk,以上兩個順次遞歸遍歷。
- 終究天生完了以後,將各個非根節點的chunk遍歷,將依靠的modules遍歷對照父節點的chunk,若有反覆標記’in-parent’
數據結構以下
{ '0':
{ id: 0,
modules: { '0': 'include', '1': 'include', '2': 'include' } },
'1':
{ id: 1,
modules:
{ '1': 'in-parent',
'3': 'include',
'4': 'include',
'5': 'include',
'6': 'include' },
parentId: 0 },
'2':
{ id: 2,
modules: { '5': 'include', '6': 'include' },
parentId: 0
}
}
writeChunks模塊
完成思緒:
- 推斷是不是有多個chunk,來辨別引入的模版。假如chunks的個數凌駕1,進口chunk則加載包括webpackJsonp,__webpack_require__.e等支撐jsonp函數的模版,未凌駕則加載簡樸的僅包括__webpack_require__的模版
- 辨別進口chunk,進口/非進口chunk加載差別的頭部。
- webpackJsonp的入參有兩種,一種數組,一種以moduleId為key的對象。為數組時刻則須要將以[,,modlue]等體式格局保證遞次
如:
代碼完成
本人的簡易版webpack完成simple-webpack
(完)