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内容')
【webpack,单文件懒加载分析实现】点击按钮时,控制台显示
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 = https://www.it610.com/article/inStalledChunks[chunkId]
// 依据当前是否已完成加载的状态来执行后续的逻辑
if (installedChunkData !== 0) {
if (installedChunkData) {
// push一个完整的promise
promises.push(installedChunkData[2])
} else {
// 执行加载操作
let promise = new Promise((resolve, reject) => {
installedChunkData = https://www.it610.com/article/inStalledChunks[chunkId] = [resolve, reject]
})
promises.push(installedChunkData[2] = promise)
// 创建标签
let script = document.createElement('script')
// 设置src
script.src = https://www.it610.com/article/jsonpScriptSrc(chunkId)
// 写入script标签
document.head.appendChild(script)
}
}// 执行promise
return Promise.all(promises)
}