webpack中require.context的作用
阿新 • • 發佈:2021-07-30
在我們專案開發中,經常需要import或者export各種模組,那麼有沒有什麼辦法可以簡化這種引入或者匯出操作呢?答案是肯定的,下面就為大家介紹一下require.context
我們會這樣引入元件:
import A from 'components/A'
import B from 'components/B'
import C from 'components/C'
import D from 'components/D'
// ...
這樣很蛋疼,因為每加一個元件,可能都要寫這麼一句,這樣有規律的事,是否可以通過自動化完成?
看下Webpack [Dependency Management | webpack
require.context
require.context(directory, useSubdirectories, regExp)
- directory: 要查詢的檔案路徑
- useSubdirectories: 是否查詢子目錄
- regExp: 要匹配檔案的正則
用法
require.context('./components/', true, /\.js$/)
目錄結構
上面呼叫方法,到底返回的是什麼?
var map = {
"./A.js": "./src/components/test/components/A.js",
"./B.js": "./src/components/test/components/B.js",
"./C.js": "./src/components/test/components/C.js",
"./D.js": "./src/components/test/components/D.js"
};
function webpackContext(req) {
var id = webpackContextResolve(req);
return __webpack_require__(id);
}
function webpackContextResolve(req) {
var id = map[req];
if(!(id + 1)) { // check for number or string
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
return id;
}
webpackContext.keys = function webpackContextKeys() {
return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "./src/components/test/components sync recursive \\.js$";
程式碼很簡單,require.context執行後,返回一個方法webpackContext,這個方法又返回一個__webpack_require__,這個__webpack_require__就相當於require或者import。同時webpackContext還有二個靜態方法keys與resolve,一個id屬性。
- keys: 返回匹配成功模組的名字組成的陣列
- resolve: 接受一個引數request,request為test資料夾下面匹配檔案的相對路徑,返回這個匹配檔案相對於整個工程的相對路徑
- id: 執行環境的id,返回的是一個字串,主要用在module.hot.accept,應該是熱載入
看下keys是作用
const ctx = require.context('./components/', true, /\.js$/)
console.log(ctx.keys())
// ["./A.js", "./B.js", "./C.js", "./D.js"]
其實就是
var map = {
"./A.js": "./src/components/test/components/A.js",
"./B.js": "./src/components/test/components/B.js",
"./C.js": "./src/components/test/components/C.js",
"./D.js": "./src/components/test/components/D.js"
};
Object.keys(map)
只不過map是模組內部變數,無法直接訪問,所以通過其實提供的keys方法訪問
那麼如何引入ABCD元件呢?
const ctx = require.context('./components/', true, /\.js$/)
const map = {}
for (const key of ctx.keys()) {
map[key] = ctx(key)
}
console.log(map)
看到了吧!成功import進來了,但'./A.js'這樣的key有點不太好,自己可以處理字串生成自己想要的key
可以優化一下,生成一個公共的方法
const importAll = context => {
const map = {}
for (const key of context.keys()) {
const keyArr = key.split('/')
keyArr.shift() // 移除.
map[keyArr.join('.').replace(/\.js$/g, '')] = context(key)
}
return map
}
export default importAll
使用
import importAll from '$common/importAll'
export default importAll(require.context('./', true, /\.js$/))