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:模式,见文档

QQ截图20210315111343-0

文件目录如图

require.context()的返回值是一个方法,并且该方法具有三个属性,id、keys、resolve

QQ截图20210315110738-1

从图中可以看出,id属性的值是由相对路径、模式、以及正则组成的一个字符串,keys和resolve属性都是方法,分别来执行一下

QQ截图20210315111148-2

keys方法返回的是匹配到的文件名组成的数组,从上面截图可以看到resolve方法需要接受一个参数,我们再来调用一下resolve

console.log('resolve:', modulesFile.resolve(modulesFile.keys()[0]));
console.log('resolve:', modulesFile.resolve('a'));

QQ截图20210315111709-3

可以看出resolve的结果是keys中返回结果的某一项的相对路径,并且,参数必须包含在keys返回结果的数组中,否则报错

前面说到,require.context()返回值的本身也是一个方法也需要接收一个参数,根据上面的req参数推断,这个参数也要在keys返回值的结果之中,再来执行下

QQ截图20210315112443-4

这里可以看出,执行的结果是一个Module实例(使用.default获取值),因为我在a.js中使用ES6 Module导出的,所以这里是一个模块的引用,如果这里我更换为CommonJS的的导出

// export default {
//   from: 'a.js'
// }
module.exports = {
  from: 'a.js'
}

结果就会变成值的拷贝

QQ截图20210315112731-5

应用

应用场景大多是在导入同一文件夹下的多个文件,举一个简单的例子: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

前端小白