手把手教你使用require.context實現前端自動化


手把手教你使用require.context實現前端自動化


隨便記錄一些東西,如有錯誤歡迎指出

轉發鏈接:https://www.jianshu.com/p/c894ea00dfec

require.context是什麼

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

什麼時候需要用到require.context

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

手把手教你使用require.context實現前端自動化

index.js

手把手教你使用require.context實現前端自動化

modules

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

分析require.context

require.context函數接受三個參數

  1. directory {String} -讀取文件的路徑
  2. useSubdirectories {Boolean} -是否遍歷文件的子目錄
  3. regExp {RegExp} -匹配文件的正則

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

借用webpakc官網的例子

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

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

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

手把手教你使用require.context實現前端自動化

在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

手把手教你使用require.context實現前端自動化

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

手把手教你使用require.context實現前端自動化

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

手把手教你使用require.context實現前端自動化

手把手教你使用require.context實現前端自動化

控制檯打印結果

可以看到

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

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

手把手教你使用require.context實現前端自動化

手把手教你使用require.context實現前端自動化

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

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

手把手教你使用require.context實現前端自動化

手把手教你使用require.context實現前端自動化

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

回到工程

  • 首先調用require.context導入某個文件夾的所有匹配文件,返回執行上下文的環境賦值給files變量
  • 聲明一個configRouters用來暴露給外層index.js作為vue-router的數組
  • 調用files函數的keys方法返回modules文件夾下所有以.js結尾的文件的文件名,返回文件名組成的數組
  • 遍歷數組每一項,如果是index.js就跳過(index.js並不是路由模塊),調用files函數傳入遍歷的元素返回一個Modules模塊
  • 因為我的路徑是用export default導出的,所以在Module模塊的default屬性中獲取到我導出的內容(即路由的結構),類似這種樣子
手把手教你使用require.context實現前端自動化

  • 將上一步返回的所有路由結構添加到configRouters數組然後暴露給外層的index.js
手把手教你使用require.context實現前端自動化

外層index.js

  • 外層引入後導入到vue-router中就可以使用了

寫在後面

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

手把手教你使用require.context實現前端自動化

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

手把手教你使用require.context實現前端自動化

require.context另外一個常用的地方是svg圖標,可以不用每次導入圖標文件,相對於以前的iconfont,svg。


作者:心_c2a2
轉發鏈接:https://www.jianshu.com/p/c894ea00dfec


分享到:


相關文章: