使用require.context實(shí)現(xiàn)import自動化

require.context是什么

一個(gè)webpack的api,通過執(zhí)行require.context函數(shù)獲取一個(gè)特定的上下文,主要用來實(shí)現(xiàn)自動化導(dǎo)入模塊,在前端工程中,如果遇到從一個(gè)文件夾引入很多模塊的情況,可以使用這個(gè)api,它會遍歷文件夾中的指定文件,然后自動導(dǎo)入,使得不需要每次顯式的調(diào)用import導(dǎo)入模塊

什么時(shí)候需要用到require.context

如果有以下情況,可以考慮使用require.context替換

index.js

modules

在Vue寫的項(xiàng)目中,我把路由通過不同的功能劃分成不同的模塊,在index.js中一個(gè)個(gè)導(dǎo)入(原諒ide的警告-.-),但是如果項(xiàng)目變大了之后,每次手動import會顯得有些力不從心,這里可以使用require.context函數(shù)遍歷modules文件夾的所有文件一次性導(dǎo)入到index.js中

分析require.context

require.context函數(shù)接受三個(gè)參數(shù)

directory {String} -讀取文件的路徑

useSubdirectories {Boolean} -是否遍歷文件的子目錄

regExp {RegExp} -匹配文件的正則

語法: require.context(directory, useSubdirectories = false, regExp = /^.//);

借用webpakc官網(wǎng)的例子

require.context('./test', false, /.test.js$/);

上面的代碼遍歷當(dāng)前目錄下的test文件夾的所有.test.js結(jié)尾的文件,不遍歷子目錄

大概用圖片來表示的話就是這樣子的

在index.js中調(diào)用require.context('./test', false, /.test.js$/);會得到test文件下3個(gè)文件的執(zhí)行環(huán)境

值得注意的是require.context函數(shù)執(zhí)行后返回的是一個(gè)函數(shù),并且這個(gè)函數(shù)有3個(gè)屬性

resolve {Function} -接受一個(gè)參數(shù)request,request為test文件夾下面匹配文件的相對路徑,返回這個(gè)匹配文件相對于整個(gè)工程的相對路徑

keys {Function} -返回匹配成功模塊的名字組成的數(shù)組

id {String} -執(zhí)行環(huán)境的id,返回的是一個(gè)字符串,主要用在module.hot.accept,應(yīng)該是熱加載?

這三個(gè)都是作為函數(shù)的屬性(注意是作為函數(shù)的屬性,函數(shù)也是對象,有對應(yīng)的屬性)

talk is cheap ,show me the code

結(jié)合工程看一下這3個(gè)屬性返回了什么

我們在里層的modules文件夾新建一個(gè)index.js,用來收集所有的模塊然后一次性導(dǎo)出給外層的index.js

這里我們先上代碼,代碼是寫在里層的index.js中的(代碼借鑒于加快Vue項(xiàng)目的開發(fā)速度)

這里我把require.context函數(shù)執(zhí)行后的代碼賦值給了files變量,files中保存了圖一的以.js結(jié)尾的文件,files是個(gè)函數(shù),我們分別調(diào)用者3個(gè)屬性看看會返回什么

控制臺打印結(jié)果

可以看到

執(zhí)行了keys方法返回了一個(gè)由匹配文件的文件名組成的數(shù)組

id屬性返回了匹配的文件夾的相對于工程的相對路徑,是否遍歷子目錄,匹配正則組成的字符串

對于resolve方法可以看到它是一個(gè)函數(shù)接受req參數(shù),經(jīng)過實(shí)踐我發(fā)現(xiàn)這個(gè)req參數(shù)的值是keys方法返回的數(shù)組的元素,接著我們傳入其中一個(gè)元素執(zhí)行resolve函數(shù)

resolve方法返回了一個(gè)字符串代表著傳入?yún)?shù)的文件相對于整個(gè)工程的相對路徑

同時(shí)files作為一個(gè)函數(shù),也接受一個(gè)req參數(shù),這個(gè)和resolve方法的req參數(shù)是一樣的,即匹配的文件名的相對路徑,而files函數(shù)返回的是一個(gè)模塊,這個(gè)模塊才是真正我們需要的
(重點(diǎn),file(key).default可以獲取到真正要import的數(shù)據(jù))

這個(gè)Module模塊和使用import導(dǎo)入的模塊是一樣的

回到工程

首先調(diào)用require.context導(dǎo)入某個(gè)文件夾的所有匹配文件,返回執(zhí)行上下文的環(huán)境賦值給files變量

聲明一個(gè)configRouters用來暴露給外層index.js作為vue-router的數(shù)組

調(diào)用files函數(shù)的keys方法返回modules文件夾下所有以.js結(jié)尾的文件的文件名,返回文件名組成的數(shù)組

遍歷數(shù)組每一項(xiàng),如果是index.js就跳過(index.js并不是路由模塊),調(diào)用files函數(shù)傳入遍歷的元素返回一個(gè)Modules模塊

因?yàn)槲业穆窂绞怯胑xport default導(dǎo)出的,所以在Module模塊的default屬性中獲取到我導(dǎo)出的內(nèi)容(即路由的結(jié)構(gòu)),類似這種樣子

將上一步返回的所有路由結(jié)構(gòu)添加到configRouters數(shù)組然后暴露給外層的index.js

外層index.js

外層引入后導(dǎo)入到vue-router中就可以使用了

寫在后面

在使用require.context自動導(dǎo)入路由文件時(shí)發(fā)現(xiàn)一個(gè)問題,路由的順序不是你期望的樣子,因?yàn)閣ebpack是根據(jù)你文件夾中文件的位置排序的,這個(gè)時(shí)候需要定義一個(gè)標(biāo)識符來給路由數(shù)組排序,這里我們給每個(gè)文件夾最上層的路由添加一個(gè)sort屬性用于排序

隨后在讀取模塊后,給外層index傳入路由配置前,給路由的模塊排序

作者:心_c2a2

鏈接:http://www.itdecent.cn/p/c894ea00dfec

來源:簡書

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容