log.js文件
module.exports ="lazy load logger"
index.js文件
let oBtn = document.getElementById('btn')
oBtn.addEventListener('click', function () {
import( /*webpackChunkName: "log"*/ './log.js').then((log) => {
console.log(log)
})
})
console.log('index.js內容')
點擊按鈕時,控制枱顯示lazy load logger
webpack在打包後,比之前的單文件加載多出了幾件事情。懶加載的實現主要通過Promise來實現。
實現懶加載,要調用__webpack_require__.e方法,e方法是一個promise狀態保存。e方法中,jsonP創建srcipt標籤,指定src,通過Promise.all把狀態往後傳,在過程中,動態加載要被導入的內容,這裏會通過window['webpackJsonP]調用push方法.調用webpackJsonpCallback方法,執行成功的resolve方法,__webpack_require__.e後的then方法通過__webpack_require__.t方法加載log中的內容放在value中保存.這裏多出的兩個操作一個是jsonP,一個是__webpack_require__.e
// 定義webpackJsonpCallback,合併模塊定義,改變promise狀態,還有之後的then操作
function webpackJsonpCallback(data) {
// 獲取要被動態加載的模塊id
let chunkIds = data[0];
// 獲取需要被動態加載模塊的依賴關係對象
let moreModules = data[1]
let chunkId
let resolves = []
// 循環判斷chunkIds裏對應的模塊內容是否已經完成加載
for (let i = 0; i < chunkIds.length; i++) {
chunkId = chunkIds[i]
if (Object.prototype.hasOwnProperty.call(inStalledChunks, chunkId) && inStalledChunks[chunkId]) {
//數組順序,resolve,reject,promise,這裏是已經加載,所以是0
resolves.push(inStalledChunks[chunkId][0])
}
// 更新chunk狀態
inStalledChunks[chunkId] = 0;
}
for (let moduleId in moreModules) {
if (Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
modules[moduleId] = moreModules[moduleId]
}
}
while (resolves.length) {
resolves.shift()()
}
}
// 定義inStalledChunks 用於標識某個chunkId對應的chunk是否完成加載
let inStalledChunks = {
main: 0
}
// 定義jsonpScriptSrc實現src的處理
function jsonpScriptSrc(chunkId) {
return __webpack_require__.p + "" + chunkId + '.built.js'
}
// 定義e方法,用於實現 :實現jsonP異步加載,利用promise來實現異步加載操作
__webpack_require__.e = function (chunkId) {
// 定義一個數組用於存放promise
let promises = [];
// 獲取chunkId對應的chunk是否已經完成了加載
let installedChunkData = inStalledChunks[chunkId]
// 依據當前是否已完成加載的狀態來執行後續的邏輯
if (installedChunkData !== 0) {
if (installedChunkData) {
// push一個完整的promise
promises.push(installedChunkData[2])
} else {
// 執行加載操作
let promise = new Promise((resolve, reject) => {
installedChunkData = inStalledChunks[chunkId] = [resolve, reject]
})
promises.push(installedChunkData[2] = promise)
// 創建標籤
let script = document.createElement('script')
// 設置src
script.src = jsonpScriptSrc(chunkId)
// 寫入script標籤
document.head.appendChild(script)
}
}
// 執行promise
return Promise.all(promises)
}