詳解webpack import()動(dòng)態(tài)加載模塊踩坑
import
webpack根據(jù)ES2015 loader 規(guī)范實(shí)現(xiàn)了用于動(dòng)態(tài)加載的import()方法。
這個(gè)功能可以實(shí)現(xiàn)按需加載我們的代碼,并且使用了promise式的回調(diào),獲取加載的包。
在代碼中所有被import()的模塊,都將打成一個(gè)單獨(dú)的包,放在chunk存儲(chǔ)的目錄下。在瀏覽器運(yùn)行到這一行代碼時(shí),就會(huì)自動(dòng)請(qǐng)求這個(gè)資源,實(shí)現(xiàn)異步加載。
這里是一個(gè)簡(jiǎn)單的demo。
import('lodash').then(_ => {
// Do something with lodash (a.k.a '_')...
})
可以看到,import()的語(yǔ)法十分簡(jiǎn)單。該函數(shù)只接受一個(gè)參數(shù),就是引用包的地址,這個(gè)地址與es6的import以及CommonJS的require語(yǔ)法用到的地址完全一致??梢詫?shí)現(xiàn)無(wú)縫切換【寫(xiě)個(gè)正則替換美滋滋】。
并且使用了Promise的封裝,開(kāi)發(fā)起來(lái)感覺(jué)十分自在?!景b一個(gè)async函數(shù)就更爽了】
然而,以上只是表象。
只是表象。
我在開(kāi)發(fā)的時(shí)候就遇到了問(wèn)題。場(chǎng)景是這樣的:一個(gè)對(duì)象,存儲(chǔ)的是各級(jí)的路由信息,及其對(duì)應(yīng)的頁(yè)面組件。為減少主包大小,我們希望動(dòng)態(tài)加載這些頁(yè)面。
同時(shí)使用了react-loadable來(lái)簡(jiǎn)化組件的懶加載封裝。代碼如下所示。
function lazyLoad(path) {
return Loadable({
loader: () => import(path),
loading: Spin,
});
}
然后我就開(kāi)始開(kāi)心的在代碼中寫(xiě)上lazyLoad('./pages/xxx')。果不其然,掛了。瀏覽器表示,沒(méi)有魚(yú)丸沒(méi)有粗面,也不知道這個(gè)傻逼模塊在哪里。
于是我查看了官方文檔,發(fā)現(xiàn)有一個(gè)黃條提示。

emmm,看來(lái)問(wèn)題出在這里了。
這個(gè)現(xiàn)象其實(shí)是與webpack import()的實(shí)現(xiàn)高度相關(guān)的。由于webpack需要將所有import()的模塊都進(jìn)行單獨(dú)打包,所以在工程打包階段,webpack會(huì)進(jìn)行依賴收集。
此時(shí),webpack會(huì)找到所有import()的調(diào)用,將傳入的參數(shù)處理成一個(gè)正則,如:
import('./app'+path+'/util') => /^\.\/app.*\/util$/
也就是說(shuō),import參數(shù)中的所有變量,都會(huì)被替換為【.*】,而webpack就根據(jù)這個(gè)正則,查找所有符合條件的包,將其作為package進(jìn)行打包。

因此,如果我們直接傳入一個(gè)變量,webpack就會(huì)把 (整個(gè)電腦的包都打包進(jìn)來(lái)[不鬧]) 認(rèn)為你在逗他,并且拋出一個(gè)WARNING: Critical dependency: the request of a dependency is an expression。
所以import的正確姿勢(shì),應(yīng)該是盡可能靜態(tài)化表達(dá)包所處的路徑,最小化變量控制的區(qū)域。
如我們要引用一堆頁(yè)面組件,可以使用import('./pages/'+ComponentName),這樣就可以實(shí)現(xiàn)引用的封裝,同時(shí)也避免打包多余的內(nèi)容。
另外一個(gè)影響功能封裝的點(diǎn),是import()中的相對(duì)路徑,是import語(yǔ)句所在文件的相對(duì)路徑,所以進(jìn)一步封裝import時(shí)會(huì)出現(xiàn)一些麻煩。
因?yàn)閕mport語(yǔ)句中的路徑會(huì)在編譯后被處理成webpack命令執(zhí)行目錄的相對(duì)路徑.
友情鏈接:https://webpack.js.org/api/module-methods/#import
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
element plus表格的表頭和內(nèi)容居中的實(shí)現(xiàn)代碼
這篇文章主要介紹了element plus表格的表頭和內(nèi)容居中的實(shí)現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
ajax 同步請(qǐng)求和異步請(qǐng)求的差異分析
ajax 同步請(qǐng)求和異步請(qǐng)求的差異分析,需要的朋友可以參考下。2011-07-07
Javascript驗(yàn)證上傳圖片大小[前臺(tái)處理]
在做上傳圖片的時(shí)候,如果不限制上傳圖片大小,后果非常的嚴(yán)重。解決這個(gè)問(wèn)題有兩種方式:后臺(tái)處理、前臺(tái)處理2014-07-07
JS開(kāi)發(fā)接入?deepseek?實(shí)現(xiàn)AI智能問(wèn)診
本文介紹了如何使用DeepSeek?API在UniApp項(xiàng)目中實(shí)現(xiàn)智能問(wèn)診功能,代碼示例展示了如何構(gòu)建請(qǐng)求并處理響應(yīng),本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2025-02-02
js實(shí)現(xiàn)網(wǎng)頁(yè)隨機(jī)切換背景圖片的方法
這篇文章主要介紹了js實(shí)現(xiàn)網(wǎng)頁(yè)隨機(jī)切換背景圖片的方法,涉及數(shù)組、隨機(jī)函數(shù)與css樣式的調(diào)用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-11-11
BootStrap Fileinput上傳插件使用實(shí)例代碼
這篇文章主要介紹了BootStrap Fileinput上傳插件使用實(shí)例代碼,,通過(guò)引入js和css文件,具體實(shí)現(xiàn)代碼大家參考下本文2017-07-07

