1. 程式人生 > >用webpack的require.context() 簡化你的程式碼

用webpack的require.context() 簡化你的程式碼

隨著我們的專案越來越大,平時的常見用操作就會覺得很‘麻煩’了,比如每次要新增新的路由, vuex裡面新增新的module等

{
    name: 'moduleN',
    component ModuleN,
    path: '/moduleN',
}

麻煩嗎?談不上吧,畢竟我們之前一直都是這麼做的啊
最近了解到webpack打包是有個 require.context可以用,之前是不知道的。
以前最多是自己寫一個數組,數組裡面放置我們需要讀取的檔名,然後迴圈陣列讀取裡面的檔案,雖然也還算不錯,但是還是沒有require.context爽啊。

require.context() 方法是用來建立自己的(模組)上下文,這個方法有 3 個引數:

  1. 要搜尋的資料夾目錄
  2. 是否還應該搜尋它的子目錄,
  3. 以及一個匹配檔案的正則表示式。

用法

require.context(directory, useSubdirectories = false, regExp = /^\.\//);

require.context返回的是一個類require方法,這個方法接收一個引數req,根據這個引數我們可以得到相應的模組資訊。
類似require.context(directory, useSubdirectories, regExp)(req)這樣使用。
返回的這個方法還有三個屬性( resolve, keys, id)。

  1. resolve 是一個函式,它返回請求被解析後得到的模組 id。
  2. keys 也是一個函式,它返回一個數組,由所有可能被上下文模組處理的請求組成。
  3. 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 for module.hot.accept.