API描述
先看一眼官网文档
require.context(
(directory: String),
(includeSubdirs: Boolean) /* 可选的,默认值是 true */,
(filter: RegExp) /* 可选的,默认值是 /^\.\/.*$/,所有文件 */,
(mode: String) /* 可选的, 'sync' | 'eager' | 'weak' | 'lazy' | 'lazy-once',默认值是 'sync' */
)
require.context()方法一共可以接收4个参数:
- directory:要加载的目录
- includeSubdirs:是否遍历子目录
- filter:要加载的文件正则匹配
- mode:模式,见文档
文件目录如图
require.context()的返回值是一个方法,并且该方法具有三个属性,id、keys、resolve
从图中可以看出,id属性的值是由相对路径、模式、以及正则组成的一个字符串,keys和resolve属性都是方法,分别来执行一下
keys方法返回的是匹配到的文件名组成的数组,从上面截图可以看到resolve方法需要接受一个参数,我们再来调用一下resolve
console.log('resolve:', modulesFile.resolve(modulesFile.keys()[0]));
console.log('resolve:', modulesFile.resolve('a'));
可以看出resolve的结果是keys中返回结果的某一项的相对路径,并且,参数必须包含在keys返回结果的数组中,否则报错
前面说到,require.context()返回值的本身也是一个方法也需要接收一个参数,根据上面的req参数推断,这个参数也要在keys返回值的结果之中,再来执行下
这里可以看出,执行的结果是一个Module实例(使用.default获取值),因为我在a.js中使用ES6 Module导出的,所以这里是一个模块的引用,如果这里我更换为CommonJS的的导出
// export default {
// from: 'a.js'
// }
module.exports = {
from: 'a.js'
}
结果就会变成值的拷贝
应用
应用场景大多是在导入同一文件夹下的多个文件,举一个简单的例子:Vuex分模块引入时,可以通过require.context来动态引入模块,只需要编写一次代码,不再需要后期过多得维护
const modulesFiles = require.context('./modules', false, /\.js$/)
const modules = modulesFiles.keys().reduce((modulesTemp, currentPath) => {
// 从文件名中去除文件后缀,如./a.js => a
const temp = modulesTemp
const moduleName = currentPath.replace(/^\.\/(.*)\.\w+$/, '$1')
const value = modulesFiles(currentPath)
temp[moduleName] = value.default
return temp
}, {})
store = new Vuex.Store({
modules
})
export default store