本文基于Webpack4,如果你遇到类似问题,又懒得看全文,请直接拖到文章底部查看解决和总结部分
事件描述
我做了个小工具(站点访问点击热力图查看工具),这个小工具通过Webpack进行打包,工具中用到了Webpack的动态导入(Dynamic Imports)功能,本地测试运行良好,上线成功!撒花🎉。
数日后...运营妹子找来:“小白,我那个网站的热力图怎么显示不出来!!!”
我说:“清缓存再试”、“换浏览器再试”、“重启电脑再试”!
数分钟后,妹子脑袋上着火了,金灿灿,无比耀眼,向我走来,我都快瞎了,啊,我两眼都看不见了。
她说,“你自己看,根本不行!”
我一度操作猛如虎,F12开启,强制刷新,咦,控制台咋报错了。。。装逼失败!“妹子大怒,热力图呢!?”
问题分析
我突然感觉到,问题大了,我开发的工具居然在某些场景下出现不可用!赶紧看看其他已用该产品的工具情况,都是好的!面对这样的情况,确实有点无从下手了。
从Network面板上观察,发现有个动态加载的js没有加载到!这个js就是控制热力图渲染逻辑的。资源都没加载到,程序肯定出问题,那为啥资源莫名其妙的没有加载呢?想来想去也没想出来。
既然这样,就只能从出问题的网站上的错误提示中找线索了。部分代码如下:
Object(n.a)()).then(function(e) {
if (200 === e.code)
return document.getElementById("JlaHeatmapLayer").style.display = "none",
new Promise(function(t, n) {
t(r.e(0).then(r.bind(null, 9)).then(function(t) {
var r = t.default;
setTimeout(function() {
r(e.data)
}, 600)
}))
}
);
alert(e.msg)
}).catch(function(e) {
alert(e),
console.warn(e)
})
上面试压缩后的代码进行chrome的format后的结果,因为写这篇文章,生产线已经修复,只能简单描述下错误,错误出现在r(e.data)
,提示r未定义,这里动态导入功能利用promise,t其实就是resolve,里面执行了一个r.e(0)
,这个r方法,就是管理需要加载的文件。
这里面的细节我就不多说了,简单描述下:因为是动态载入,那肯定有个数组或对象存放需要载入的文件id,在这个方法内他会在合适的时候取出对象中的对应的文件。
而在工具使用正常的页面中,发现这个对象,只有1个,确实是我需要用的文件,而出问题的页面中,这个对象居然有10个!!!这就不对了!我没有写那么多动态导入,为啥出来这么多?
我经过断点反复分析,从Stack内查看运行逻辑,终于发现了类似的这段代码:
// 工具正常页面
(window.webpackJsonp = window.webpackJsonp || []).push([[0], [, , , , , , , , , function(e, t, n) {
// ...
// 工具异常页面
(window.webpackJsonp = window.webpackJsonp || []).push([[10], {
// ...
这个大大的window
确实十分可疑!针对这个继续深入研究一下!
这里插一段工具的动态导入的源码片段
window.onload = () => {
// init方法用来鉴权的
init()
.then((result) => {
if (result.code !== 200) {
alert(result.msg)
return
}
document.getElementById('JlaHeatmapLayer').style.display = 'none'
return new Promise((resolve, reject) => {
resolve(import(/* webpackChunkName: "draw" */ './draw').then((module) => {
const draw = module.default
setTimeout(() => {
draw(result.data)
}, 600)
}))
})
}).catch((err) => {
alert(err)
console.warn(err)
})
}
有兴趣可以看看~
解决
那遇到问题自然查文档,打开官网,搜索webpackJsonp
,一下就找到了output.jsonpFunction。
原来这是webpack打包输出选项中的一个配置。用来做什么的呢,jsonp一看还以为是跨域有关的,哈哈。其实他是一个异步加载chunks的函数。看到这里再思考下为啥这个页面就出问题呢,哈!这个出问题的页面是用KOA + NUXT
,Nuxt自带了动态加载的功能,到这里真相大白。Nuxt中的webpackJsonp全局变量和我工具中的webpackJsonp全局变量发生冲突,导致工具中的动态导入出现异常,工具就完蛋了。
于是赶紧打开工具项目,参考文档进行了修改:
output: {
path: path.resolve(__dirname, 'dist/dist/client/'),
publicPath: IS_DEV ? '' : `//${process.env.BUILD_HOST}.51.la/dist/`,
filename: 'heatmapDraw.js',
jsonpFunction: 'wpJsonp51LAHeatmapTool'
},
重新打包,更新上线(专注面向正式线编程、就是这么自信:P)。啊哈,一切正常,看看代码,已经变成了如下:
(window.wpJsonp51LAHeatmapTool = window.wpJsonp51LAHeatmapTool || []).push([[0], [, , , , , , , , , function(e, t, n) {
// ...
问题解决,简直完美,继续撒花🎉🎉🎉~开开心心找妹子原谅去咯。
总结
其实一直对Webpack都有不断的学习,但是Webpack功能太强大了,确实很多疏忽的地方,不过我个人感觉Webpack之所以强大,真的是只要你想得到的需求配置几乎全都能满足,确实值得深入研究。
另外Webpack这种会暴露全局变量的确实也让我意想不到,有遇到类似问题的朋友可以参考下咯~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。