require.context用法
前言
在开发的时候总会碰到整个文件夹下的文件都一起引入,特别是组件化开发的项目中,有一些基础组件,肯定会全部引进的,这样组件不多,一个个引没啥问题,但随着项目的扩展,组件可能会越来越多,每次新增一个组件都手动引入,这样太麻烦了。webpack
下有个批量引入文件的函数require.context
,学习下这个函数的用法。
用法
看下webpack
官网的介绍 require.context 这个函数有三个参数。
directory
引入文件的目录useSubdirectories
是否递归查找子目录regExp
正则匹配,需要查找的文件
这个函数会返回一个以directory
目录为上下文的函数requestContext
。这个返回的函数有三个属性。
keys
函数,返回的是个数组,这个数组的元素其实是一个路径,和directory
拼接就是当前调用require.context
的相对路径。id
是上下文模块里面所包含的模块 id. 它可能在你使用module.hot.accept
的时候被用到。resolve
函数,这个函数传入keys
数组中的元素返回的是一个完整的路径。
函数requestContext
通过keys
的数组里的路径可以获取对应的文件内容。说那么多可能有点迷糊,直接来代码更直观一些。
实践
代码目录是这样的:
src/_test/index.js
index.js
utils
|___a.js
|___b.js
|___c.js
|___child
|______1.js
|______2
|_________2.js
// index.js
const requestContext = require.context('./utils', true, /\.js$/);
const map = {};
let lastFile = '';
requestContext.keys().forEach((key) => {
// key 就是一个路径
// 路径传入requestContext就是引入文件的内容
map[key] = requestContext(key);
lastFile = element;
});
console.log('requestContext====>', requestContext);
console.log('requestContext.id====>', requestContext.id);
console.log('requestContext.resolve====>', requestContext.resolve);
console.log('lastFile====>', lastFile);
console.log('requestContext.resolve(lastFile)====>', requestContext.resolve(lastFile));
console.log('map====>', map);
看下打印的内容
点击看下requestContext
内部的具体实现
var map = {
"./a.js": "./src/_test/utils/a.js",
"./b.js": "./src/_test/utils/b.js",
"./c.js": "./src/_test/utils/c.js",
"./child/1.js": "./src/_test/utils/child/1.js",
"./child/2/2.js": "./src/_test/utils/child/2/2.js"
};
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/_test/utils sync recursive \\.js$";
看完内部代码就知道怎么回事了,require.context
内部会生成map
私有变量,通过keys
函数返回这个私有变量的所有key
。然后把key
传给webpackContext
,webpackContext
通过webpackContextResolve
获取路径,然后把路径传入__webpack_require__
,这样就可以获取到文件内容了。
最后
这个函数在项目中会经常用到的,其实不止组件可以用这个,在使用大量svg
当图标的时候也可以用,这个svg
的用法具体可以看下vue-element-admin-master
这个的开源项目。