#### 流程細節
* 初始化:啟動構建,讀取與合并參數配置參數,加載plugin,實例化compiler。
* 編譯:從Entry出發,針對每個module串行調用對應的loader去翻譯文件內容,再找到該module依賴的module,遞歸地進行編譯。
* 輸出:將編譯后的module組合成chunk,將chunk轉換成文件,輸出到文件系統中。
#### 輸出文件分析
```
//js
const show = require('./show.js');
show('webpack');
//webpack
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
path: __dirname
}
}
//bundle.js
(
//modules是存放所有模塊的數組,每一個均為函數
function(modules) {
//已加載的模塊,提升性能
var installedModules = {};
//自己模擬了一個commonJS,moduleId為module的index
function __webpack_require_(moduleId) {
//如果要加載的模塊已經被加載過,則直接從installedModules讀取
//否則,新建一個模塊然后將其存在installedModules里
var module = installedModules[moduleId] = {
//index
i: moduleId,
//has installed
l: false,
exports: {}
}
//再調用這個函數,將需要的參數傳入
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
//module設為已加載并return module.exports;
return __webpack_require__(/*啟動模塊的index,默認是0*/0)
}
}
)([/*存放所有module的數組*/])
//至于modules數組里面每個module的內容
(
function (moduleId, exports, __webpack_require__) {
//通過__webpack_require__規范導出
const show = __webpack_require__(1);
show('webpack');
/*1*/
(function (module, exports) {
/*show的業務邏輯*/
module.exports = show;
})
}
)
```
webpack之所以要將輸入文件全部合并成一個輸出文件,是為了減少網絡請求次數(瀏覽器不能像node那樣快速在本地加載一個個模塊文件,只能執行網絡請求,數量較多時加載時間會變長)。
```
//異步module的原理
//js
import ('./show').then(show => show('webpack'));
//0.bundle.js(異步代碼)
webpackJsonp([0], [
(function(module, exports) {
/*show的業務邏輯*/
module.exports = show;
})
])
//bundle.js
(
function(modules) {
//webpackJsonp用于從異步加載的文件中安裝模塊
window['webpackJsonp'] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
//小于等于chunkIds的模塊都標識為加載成功
//將需要異步加載的moreModules全部push到modules里
//為每個模塊配置加載狀態
__webpack_require__.e = function(chunkId) {
//如果已經加載成功,則直接返回resolve Promise
//如果正在網絡加載中,返回installedChunkData[2]
//如果是第一次加載,則去加載文件(向html head中插入一個script標簽去異步加載文件,路徑由publicPath和chunkId組成),與此同時
var promise = new Promise(function(resolve, reject) {
installedChunkData = installedChunks[chunkId] = [resolve, reject];
installedChunkData[2] = promise;
}
}
}
return __webpack_require__(0); //和前面的一樣,加載并執行入口模塊
}
)([/*存放所有沒有經過異步加載的,隨入口文件加載的模塊*/])
//然后,你的
import ('./show').then(show => show('webpack'))就變成了
__webpack_require__.e(0).then(__webpack_require__.bind(null, 1)).then(show => show('webpack'));
```