本文基於Webpack4,若是你遇到相似問題,又懶得看全文,請直接拖到文章底部查看 解決和 總結部分
我作了個小工具(站點訪問點擊熱力圖查看工具),這個小工具經過Webpack進行打包,工具中用到了Webpack的動態導入(Dynamic Imports)功能,本地測試運行良好,上線成功!撒花🎉。javascript
很多天後...運營妹子找來:「小白,我那個網站的熱力圖怎麼顯示不出來!!!」java
我說:「清緩存再試」、「換瀏覽器再試」、「重啓電腦再試」!webpack
數分鐘後,妹子腦殼上着火了,金燦燦,無比耀眼,向我走來,我都快瞎了,啊,我兩眼都看不見了。web
她說,「你本身看,根本不行!」面試
我一度操做猛如虎,F12開啓,強制刷新,咦,控制檯咋報錯了。。。裝逼失敗!「妹子大怒,熱力圖呢!?」chrome
我忽然感受到,問題大了,我開發的工具竟然在某些場景下出現不可用!趕忙看看其餘已用該產品的工具狀況,都是好的!面對這樣的狀況,確實有點無從下手了。編程
從Network面板上觀察,發現有個動態加載的js沒有加載到!這個js就是控制熱力圖渲染邏輯的。資源都沒加載到,程序確定出問題,那爲啥資源莫名其妙的沒有加載呢?想來想去也沒想出來。json
既然這樣,就只能從出問題的網站上的錯誤提示中找線索了。部分代碼以下:跨域
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這種會暴露全局變量的確實也讓我意想不到,有遇到相似問題的朋友能夠參考下咯~