使用契機(jī)
將API接口文件分模塊存放后需要導(dǎo)入統(tǒng)一的入口文件再統(tǒng)一導(dǎo)出,然后在main.js中引用??粗珠T別類的接口文件很舒服,但是文件一多,導(dǎo)入統(tǒng)一入口文件index.js就顯得很繁瑣。效果如下:



說實(shí)話,這個(gè)看著越看越反人類。所以決定用更簡潔的require.context來處理這個(gè)問題。
require.context
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)入模塊
require.context函數(shù)接受三個(gè)參數(shù)
directory {String}-讀取文件的路徑useSubdirectories {Boolean}-是否遍歷文件的子目錄regExp {RegExp}-匹配文件的正則
webpack官網(wǎng)給出的例子是這樣的:
require.context('./test', false, /.test.js$/)
開始使用
首先根據(jù)需要讓require.context遍歷/src/api目錄。遍歷的過程中肯定會把index.js也遍歷進(jìn)去,因?yàn)椴幌胫髞硖幚肀闅v后的結(jié)果,所以先粗暴的用名稱區(qū)分。
我將以前的模塊名.js改成為了模塊名.api.js。

接著開始編寫一個(gè)導(dǎo)入函數(shù)來處理require.context返回的結(jié)果。
// importAllModule.js
/**
* @description 批量導(dǎo)入API
* @param {Object} context 上下文對象
* @param {RegExp} reg 匹配規(guī)則
* @returns {Object} 對象
*/
function importAllModule(context, reg) {
const map = {}
let tmp = {}
for (let key of context.keys()) {
const keyArr = key.split('/')
keyArr.shift()
map[keyArr.join('.').replace(reg, '')] = context(key).default
}
for (let key in map) {
tmp = {
...tmp,
...map[key]
}
}
return tmp
}
export default importAllModule
接著在index.js中導(dǎo)入importAllModule.js并調(diào)用導(dǎo)入函數(shù)。
// index.js
import importAllModule from '../common/js/importAllModule'
const api = importAllModule(require.context('api', true, /\.api.js$/), /\.api.js$/g)
export default api
結(jié)語
經(jīng)過require.context的改造,大大解放了生產(chǎn)力。首先是index.js變得更加的簡潔和可維護(hù)。其次,只要按格式編寫API文件的文件名,就會被require.context遍歷到并導(dǎo)入到index.js中。