require.context實現前端工程自動化

require.context是什麼

一個webpack的api,經過執行require.context函數獲取一個特定的上下文,主要用來實現自動化導入模塊,在前端工程中,若是遇到從一個文件夾引入不少模塊的狀況,可使用這個api,它會遍歷文件夾中的指定文件,而後自動導入,使得不須要每次顯式的調用import導入模塊前端

何時須要用到require.context

若是有如下狀況,能夠考慮使用require.context替換vue

 
index.js
 
modules

在Vue寫的項目中,我把路由經過不一樣的功能劃分紅不一樣的模塊,在index.js中一個個導入(原諒ide的警告-.-),可是若是項目變大了以後,每次手動import會顯得有些力不從心,這裏可使用require.context函數遍歷modules文件夾的全部文件一次性導入到index.js中webpack

分析require.context

require.context函數接受三個參數web

  1. directory {String} -讀取文件的路徑vue-router

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

  3. regExp {RegExp} -匹配文件的正則數組

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

借用webpakc官網的例子函數

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

上面的代碼遍歷當前目錄下的test文件夾的全部.test.js結尾的文件,不遍歷子目錄

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

 
 

在index.js中調用 require.context('./test', false, /.test.js$/);會獲得test文件下3個文件的執行環境

值得注意的是require.context函數執行後返回的是一個函數,而且這個函數有3個屬性

  1. resolve {Function} -接受一個參數request,request爲test文件夾下面匹配文件的相對路徑,返回這個匹配文件相對於整個工程的相對路徑

  2. keys {Function} -返回匹配成功模塊的名字組成的數組

  3. id {String} -執行環境的id,返回的是一個字符串,主要用在module.hot.accept,應該是熱加載?

這三個都是做爲函數的屬性(注意是做爲函數的屬性,函數也是對象,有對應的屬性)

talk is cheap ,show me the code

結合工程看一下這3個屬性返回了什麼

咱們在裏層的modules文件夾新建一個index.js,用來收集全部的模塊而後一次性導出給外層的index.js

 
 

這裏咱們先上代碼,代碼是寫在裏層的index.js中的(代碼借鑑於加快Vue項目的開發速度)

 
 

這裏我把require.context函數執行後的代碼賦值給了files變量,files中保存了圖一的以.js結尾的文件,files是個函數,咱們分別調用者3個屬性看看會返回什麼

 
 
 
控制檯打印結果

能夠看到

執行了keys方法返回了一個由匹配文件的文件名組成的數組
id屬性返回了匹配的文件夾的相對於工程的相對路徑,是否遍歷子目錄,匹配正則組成的字符串

對於resolve方法能夠看到它是一個函數接受req參數,通過實踐我發現這個req參數的值是keys方法返回的數組的元素,接着咱們傳入其中一個元素執行resolve函數

 
 
 
 

resolve方法返回了一個字符串表明着傳入參數的文件相對於整個工程的相對路徑

同時files做爲一個函數,也接受一個req參數,這個和resolve方法的req參數是同樣的,即匹配的文件名的相對路徑,而files函數返回的是一個模塊,這個模塊纔是真正咱們須要的

 
 
 
 

這個Module模塊和使用import導入的模塊是同樣的

回到工程

  • 首先調用require.context導入某個文件夾的全部匹配文件,返回執行上下文的環境賦值給files變量

  • 聲明一個configRouters用來暴露給外層index.js做爲vue-router的數組

  • 調用files函數的keys方法返回modules文件夾下全部以.js結尾的文件的文件名,返回文件名組成的數組

  • 遍歷數組每一項,若是是index.js就跳過(index.js並非路由模塊),調用files函數傳入遍歷的元素返回一個Modules模塊

  • 由於個人路徑是用export default導出的,因此在Module模塊的default屬性中獲取到我導出的內容(即路由的結構),相似這種樣子

 
 
  • 將上一步返回的全部路由結構添加到configRouters數組而後暴露給外層的index.js
 
外層index.js
  • 外層引入後導入到vue-router中就可使用了

寫在後面

在使用require.context自動導入路由文件時發現一個問題,路由的順序不是你指望的樣子,由於webpack是根據你文件夾中文件的位置排序的,這個時候須要定義一個標識符來給路由數組排序,這裏咱們給每一個文件夾最上層的路由添加一個sort屬性用於排序

 
 

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

 
相關文章
相關標籤/搜索