問(wèn)題二然后分析圖 2 的報(bào)錯(cuò) 。在業(yè)務(wù)方 App 工程里 yarn link 教室 SDK,使用 webpack 打包后,運(yùn)行的仍然是 CommonJS 模塊,為什么會(huì)出現(xiàn) JS 引擎級(jí)別的錯(cuò)誤呢?這不是 ES6 模塊才會(huì)出現(xiàn)的報(bào)錯(cuò)么?這里有兩個(gè)原因 。
教室 SDK 使用 Rollup[24] 進(jìn)行打包 。Rollup 會(huì)把多個(gè)文件打包成一個(gè)文件,子模塊的代碼會(huì)被放到父模塊前面 。比如,代碼 2 經(jīng)過(guò) Rollup 打包后變成了代碼 4 。
console.log(parent); // 報(bào)錯(cuò) const parent = 'parent'; export { parent };代碼 4
本地 yarn link 教室 SDK 后,引用的教室 SDK 包路徑為軟連接,而軟連接在 Babel 轉(zhuǎn)碼時(shí)會(huì)被忽略 。因此,業(yè)務(wù) App 直接引用了 Rollup 打包的 ES6+ 語(yǔ)法的教室 SDK 。如果在子模塊中直接執(zhí)行了父模塊導(dǎo)出的變量,就會(huì)報(bào)錯(cuò) 。如代碼 4 所示,執(zhí)行第一行代碼時(shí),變量 parent 有被創(chuàng)建綁定但沒(méi)有被初始化 。
解決問(wèn)題明確了問(wèn)題由模塊循環(huán)引用導(dǎo)致,并分析了具體原因 。那怎么在復(fù)雜的代碼工程中找到出現(xiàn)循環(huán)引用的模塊呢?
webpack plugincircular-dependency-plugin[25] 是一個(gè)分析模塊循環(huán)引用的 webpack 插件 。它的源碼只有 100 行左右,原理也比較簡(jiǎn)單 。在 optimizeModules[26] 鉤子中,從本模塊開(kāi)始遞歸尋找依賴模塊,并比較依賴模塊與本模塊的 debugId,如果相同,就判定為循環(huán)引用,并返回循環(huán)引用鏈 。
定位并解決循環(huán)引用在業(yè)務(wù) App 工程中引入
circular-dependency-plugin 后做一些配置,就可以看到教室 SDK 相關(guān)的循環(huán)引用模塊 。輸出的模塊循環(huán)引用鏈比較多,有 112 個(gè) 。如何進(jìn)一步定位到幾個(gè)導(dǎo)致問(wèn)題的循環(huán)引用呢?根據(jù)報(bào)錯(cuò)的堆棧找到報(bào)錯(cuò)的文件,然后找出和這個(gè)文件相關(guān)的循環(huán)引用,用 hack 的方式逐個(gè)切斷這些循環(huán)引用后驗(yàn)證報(bào)錯(cuò)是否解決 。最后,我在切斷兩個(gè)循環(huán)引用后解決了問(wèn)題 。其中一個(gè)循環(huán)引用鏈如下:
Circular dependency detected: node_modules/@byted-classroom/room/lib/service/assist/stream-validator.js -> node_modules/@byted-classroom/room/lib/service/rtc/engine.js -> node_modules/@byted-classroom/room/lib/service/rtc/definitions.js -> node_modules/@byted-classroom/room/lib/service/rtc/base.js -> node_modules/@byted-classroom/room/lib/service/monitor/index.js -> node_modules/@byted-classroom/room/lib/service/monitor/monitors.js -> node_modules/@byted-classroom/room/lib/service/monitor/room.js -> node_modules/@byted-classroom/room/lib/service/npy-courseware/student-courseware.js -> node_modules/@byted-classroom/room/lib/service/index.js -> node_modules/@byted-classroom/room/lib/service/audio-mixing/index.js -> node_modules/@byted-classroom/room/lib/service/audio-mixing/mixing-player.js -> node_modules/@byted-classroom/room/lib/index.js -> node_modules/@byted-classroom/room/lib/room/base.js -> node_modules/@byted-classroom/room/lib/service/rtc/manager.js -> node_modules/@byted-classroom/room/lib/service/assist/stream-validator.js 建議TypeScript 工程的循環(huán)引用問(wèn)題是比較普遍的,常常會(huì)因?yàn)樾枰褂靡粋€(gè)類型而增加一個(gè)文件依賴 。建議在工程中引入模塊循環(huán)引用檢測(cè)機(jī)制,比如 webpack 插件
circular-dependency-plugin 和 eslint 規(guī)則 import/no-cycle,以便及時(shí)調(diào)整文件或代碼結(jié)構(gòu)來(lái)切斷循環(huán)引用 。
總結(jié)本文從開(kāi)發(fā)時(shí)遇到的一個(gè)報(bào)錯(cuò)出發(fā),對(duì) JS 模塊機(jī)制和循環(huán)引用進(jìn)行了深度分析,并提供了定位和解決模塊循環(huán)引用問(wèn)題的方法 。根據(jù)對(duì) ES 規(guī)范的解讀,本文糾正了《ECMAScript 6 入門(mén)教程》一書(shū)中的幾個(gè)錯(cuò)誤觀點(diǎn) 。
以上關(guān)于本文的內(nèi)容,僅作參考!溫馨提示:如遇健康、疾病相關(guān)的問(wèn)題,請(qǐng)您及時(shí)就醫(yī)或請(qǐng)專業(yè)人士給予相關(guān)指導(dǎo)!
「愛(ài)刨根生活網(wǎng)」www.malaban59.cn小編還為您精選了以下內(nèi)容,希望對(duì)您有所幫助:- 怎么發(fā)面好 怎樣發(fā)面,如何發(fā)好面
- 現(xiàn)在網(wǎng)絡(luò)上流行什么詞
- 70年代的縫紉機(jī)現(xiàn)在值多少錢(qián) 70年代縫紉機(jī)回收價(jià)格
- “哭暈在廁所”這個(gè)網(wǎng)絡(luò)用語(yǔ)怎么來(lái)的?是什么意思
- 再開(kāi)個(gè)店都綽綽有余 女子十年在美發(fā)店消費(fèi)150萬(wàn)
- 你支持現(xiàn)在的網(wǎng)絡(luò)用語(yǔ)嗎?各種縮寫(xiě),諧音相繼面世是好是壞?
- 劉德華鍛煉腹肌 每天有適量運(yùn)動(dòng)
- 女性在家徒手訓(xùn)練打造翹臀
- 蘋(píng)果在生活中的妙用
- 某年墨西哥等國(guó)出現(xiàn)了流感疫情,引發(fā)全球關(guān)注.在協(xié)助墨西哥等國(guó)家防控疫情傳播過(guò)程中發(fā)揮重要作用的國(guó)際
