require.context自动化导入的解析

用法

在开发的过程中如果需要 工程化 模块化 自动化导入文件 譬如svg等

1
2
3
4
5
function importAll(r) {
r.keys().forEach(r);
}

importAll(require.context('../components/', true, /\.js$/));

结论

  • require.context() 的过程会把文件夹下的文件名和路径生成一个一一对应的map对象 同时返回一个require函数(req)
    req的 keys属性就是map的keys
    req的 resolve函数通过map返回对应的文件
  • 循环遍历req的keys 执行req
  • 执行req绑定的 resolve函数
  • resolve通map找到对应的路径(id)
  • 执行 webpack_require(id) 自动化导入

https://webpack.js.org/guides/dependency-management/#requirecontext

1
2
3
4
5
6
7
8
9
10
一般需要三个参数 目录 是否解析子目录 正则匹配
The arguments passed to require.context must be literals!.
参数必须是字面量 不能用变量等

require.context(
directory,
(useSubdirectories = true),
(regExp = /^\.\/.*$/),
(mode = 'sync')
);

具体用法如下

1
2
3
4
5
6
function importAll(r) {
r.keys().forEach(r);
}

importAll(require.context('../components/', true, /\.js$/));

1
2
3
4
5
6
7
8
const cache = {};

function importAll(r) {
r.keys().forEach((key) => (cache[key] = r(key)));
}

importAll(require.context('../components/', true, /\.js$/));
// At build-time cache will be populated with all required modules.

上面的过程最主要的是 r.keys().forEach(r);

我们可以通过打印 r 看看具体做了什么

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var map = {
"./sub-customer-active-state4.svg": "./src/icons/svg/sub-customer-active-state4.svg",
"./sub-customer-state1.svg": "./src/icons/svg/sub-customer-state1.svg",
"./synergy-yw.svg": "./src/icons/svg/synergy-yw.svg",
"./warning-state.svg": "./src/icons/svg/warning-state.svg",
"./wenhao.svg": "./src/icons/svg/wenhao.svg"
};

function webpackContext(req) {
var id = webpackContextResolve(req);
return __webpack_require__(id);
}
function webpackContextResolve(req) {
if(!__webpack_require__.o(map, req)) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
return map[req];
}
webpackContext.keys = function webpackContextKeys() {
return Object.keys(map);
};
webpackContext.resolve = webpackContextResolve;
module.exports = webpackContext;
webpackContext.id = "./src/icons/svg sync \\.svg$";