require.context

1. 一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个api,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块

2. require.context(directory, useSubdirectories, regExp)

  • directory: 要查找的文件路径
  • useSubdirectories: 是否查找子目录
  • regExp: 要匹配文件的正则

3.  用法:

require.context('./components/', true, /\.js$/)
 1 var map = {
 2     "./A.js": "./src/components/test/components/A.js",
 3     "./B.js": "./src/components/test/components/B.js",
 4     "./C.js": "./src/components/test/components/C.js",
 5     "./D.js": "./src/components/test/components/D.js"
 6 };
 7 
 8 
 9 function webpackContext(req) {
10     var id = webpackContextResolve(req);
11     return __webpack_require__(id);
12 }
13 function webpackContextResolve(req) {
14     var id = map[req];
15     if(!(id + 1)) { // check for number or string
16         var e = new Error("Cannot find module '" + req + "'");
17         e.code = 'MODULE_NOT_FOUND';
18         throw e;
19     }
20     return id;
21 }
22 webpackContext.keys = function webpackContextKeys() {
23     return Object.keys(map);
24 };
25 webpackContext.resolve = webpackContextResolve;
26 module.exports = webpackContext;
27 webpackContext.id = "./src/components/test/components sync recursive \\.js$";

代码很简单,require.context执行后,返回一个方法webpackContext,这个方法又返回一个__webpack_require__,这个__webpack_require__就相当于require或者import。同时webpackContext还有二个静态方法keys与resolve,一个id属性。

  1. keys: 返回匹配成功模块的名字组成的数组
  2. resolve: 接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
  3. id: 执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载

看下keys是作用

1 const ctx = require.context('./components/', true, /\.js$/)
2 console.log(ctx.keys())   // ["./A.js", "./B.js", "./C.js", "./D.js"]

其实就是

1 var map = {
2     "./A.js": "./src/components/test/components/A.js",
3     "./B.js": "./src/components/test/components/B.js",
4     "./C.js": "./src/components/test/components/C.js",
5     "./D.js": "./src/components/test/components/D.js"
6 };
7 
8 Object.keys(map)

只不过map是模块内部变量,无法直接访问,所以通过其实提供的keys方法访问

那么如何引入ABCD组件呢?

1 const ctx = require.context('./components/', true, /\.js$/)
2 const map = {}
3 for (const key of ctx.keys()) {
4   map[key] = ctx(key)
5 }
6 console.log(map)

可以优化一下,生成一个公共的方法

 1 const importAll = context => {
 2   const map = {}
 3 
 4   for (const key of context.keys()) {
 5     const keyArr = key.split('/')
 6     keyArr.shift() // 移除.
 7     map[keyArr.join('.').replace(/\.js$/g, '')] = context(key)
 8   }
 9 
10   return map
11 }
12 
13 export default importAll

使用

1 import importAll from '$common/importAll'
2 export default importAll(require.context('./', true, /\.js$/))
posted @ 2021-05-11 17:02  icyyyy  阅读(139)  评论(0)    收藏  举报