用webpack的require.context() 簡化你的程式碼
隨著我們的專案越來越大,平時的常見用操作就會覺得很‘麻煩’了,比如每次要新增新的路由, vuex裡面新增新的module等
{
name: 'moduleN',
component ModuleN,
path: '/moduleN',
}
麻煩嗎?談不上吧,畢竟我們之前一直都是這麼做的啊
最近了解到webpack打包是有個 require.context可以用,之前是不知道的。
以前最多是自己寫一個數組,數組裡面放置我們需要讀取的檔名,然後迴圈陣列讀取裡面的檔案,雖然也還算不錯,但是還是沒有require.context爽啊。
require.context() 方法是用來建立自己的(模組)上下文,這個方法有 3 個引數:
- 要搜尋的資料夾目錄
- 是否還應該搜尋它的子目錄,
- 以及一個匹配檔案的正則表示式。
用法
require.context(directory, useSubdirectories = false, regExp = /^\.\//);
require.context返回的是一個類require方法,這個方法接收一個引數req,根據這個引數我們可以得到相應的模組資訊。
類似require.context(directory, useSubdirectories, regExp)(req)
這樣使用。
返回的這個方法還有三個屬性( resolve, keys, id)。
- resolve 是一個函式,它返回請求被解析後得到的模組 id。
- keys 也是一個函式,它返回一個數組,由所有可能被上下文模組處理的請求組成。
- id 是上下文模組裡面所包含的模組 id. 它可能在你使用 module.hot.accept 的時候被用到
通常我們用的最多的是keys這個方法。
還是有點懵???
舉個例子:
先看看我的目錄結構
準備在webapck資料夾裡面執行webpack --mode=development index.js
index.js程式碼
const component = require.context('./', false, /.js$/); const requireAll = context =>{ console.log('context', context); console.log('context keys', context.keys); return context.keys().map(context); }; requireAll(component).forEach((item) => { console.log('item ', item); }); export const index = { hi: 'hello' }
router.js
export default {
name: 'test',
url: '/test',
}
我們的目的很簡單,就是用通過webpack把當前目錄裡面的所有.js檔案都讀取到,當然這裡也包括index.js自己。
這裡我把item打印出來了
原來我們取到每個檔案export出去的內容了,成功!
我們根據示例程式碼列印的contex我們可以追蹤到一些原始碼資訊。
這裡我們清晰的看到返回的類require方法即是webpackContext方法,執行該方法實際就是運行了真正的webpack的require方法--__webpack_require__
其實這裡運用了閉包,map物件儲存了所有的模組資訊,模組存在與否就是看能否再map物件裡面查詢的到,然後__webpack_require__(id)
就返回了真正的模組資訊了。
keys
比較好理解了,返回map裡面所有的key
resolve
函式就是根據req查詢id,供__webpack_require__
呼叫的。
id
是上下文模組id,返回"./ sync .js$"
,這個應該跟檔名webpack:///._sync_nonrecursive_.js$?
有關係
官方是這麼說的
id
is the module id of the context module. This may be useful formodule.hot.accept
.