随着我们的项目越来越大,平时的常见用操作就会觉得很‘麻烦’了,比如每次要添加新的路由, vuex里面添加新的module等

{
    name: 'moduleN',
    component ModuleN,
    path: '/moduleN',
}

麻烦吗?谈不上吧,毕竟我们之前一直都是这么做的啊
最近了解到webpack打包是有个 require.context可以用,之前是不知道的。
以前最多是自己写一个数组,数组里面放置我们需要读取的文件名,然后循环数组读取里面的文件,虽然也还算不错,但是还是没有require.context爽啊。

require.context() 方法是用来创建自己的(模块)上下文,这个方法有 3 个参数:

  1. 要搜索的文件夹目录
  2. 是否还应该搜索它的子目录,
  3. 以及一个匹配文件的正则表达式。

用法

require.context(directory, useSubdirectories = false, regExp = /^\.\//);

require.context返回的是一个类require方法,这个方法接收一个参数req,根据这个参数我们可以得到相应的模块信息。
类似require.context(directory, useSubdirectories, regExp)(req)这样使用。
返回的这个方法还有三个属性( resolve, keys, id)。

  1. resolve 是一个函数,它返回请求被解析后得到的模块 id。
  2. keys 也是一个函数,它返回一个数组,由所有可能被上下文模块处理的请求组成。
  3. id 是上下文模块里面所包含的模块 id. 它可能在你使用 module.hot.accept 的时候被用到

通常我们用的最多的是keys这个方法。
还是有点懵???

举个例子:

先看看我的目录结构

准备在webapck文件夹里面运行webpack --mode=development index.js
index.js代码

const component = require.context('./', false, /.js$/);
const requireAll = context =>{
    console.log('context', context);
    console.log('context keys', context.keys);
    return context.keys().map(context);
};

requireAll(component).forEach((item) => {
   console.log('item ', item);
});

export const index = {
    hi: 'hello'
}

router.js

export default {
    name: 'test',
    url: '/test',
}

我们的目的很简单,就是用通过webpack把当前目录里面的所有.js文件都读取到,当然这里也包括index.js自己。
这里我把item打印出来了

原来我们取到每个文件export出去的内容了,成功!
我们根据示例代码打印的contex我们可以追踪到一些源代码信息。

这里我们清晰的看到返回的类require方法即是webpackContext方法,运行该方法实际就是运行了真正的webpack的require方法--__webpack_require__
其实这里运用了闭包,map对象存储了所有的模块信息,模块存在与否就是看能否再map对象里面查找的到,然后__webpack_require__(id)就返回了真正的模块信息了。
keys比较好理解了,返回map里面所有的key
resolve函数就是根据req查找id,供__webpack_require__调用的。
id是上下文模块id,返回"./ sync .js$",这个应该跟文件名webpack:///._sync_nonrecursive_.js$?有关系
官方是这么说的

id is the module id of the context module. This may be useful for module.hot.accept.

大家也可以查看require.context的官方文档

分类: Javascript

发表评论