前端工程化之require.context应用

568 阅读2分钟

前端工程化背景

在当下的前端项目开发中,主要的模式时都是模块化开发,模块与模块之间都是通过import导入和export导出进行关联。在项目比较小,模块比较少时,我们手动的进行importexport比较的方便,但是当项目比较大,此时模块比较多时,我们如果还是手动的进行导入导出,就有点麻烦,并且如果文件进行了目录移动,维护起来也会比较的费时费力。那么有没有比较简便的办法可以批量进行导出导入操纵呢?这个必须有,它就是require.context

什么是require.context?

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

应用场景

  • vue路由文件的自动化注册
  • api层请求方法的自动化注册
  • vuex modules的合并
  • 组件库的开发应用
  • ...

如何使用require.context进行工程化

我们以vuex modules的合并为例进行说明

  1. 查找目标文件夹中的模块信息
 /*
 * 遍历获取指定文件夹中的目录
 * directory:指定的文件目录
 * deep:是否递归查找[true|false]
 * regExp:正则表达式匹配文件格式
 * return webpackContext
 */
 const importAll = require.context(directory, deep, regExp)

返回值webpackContext又返回了__webpack_require__, __webpack_require__ 有两个方法和一个属性:(我们主要用到keys方法

  • keys: 返回匹配成功模块的名字组成的数组
  • ressolve: 接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
  • id: 执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载
  1. 通过forEach解析返回的模块数组,并生成目标对象
 let modules = {};

 importAll.keys().forEach(path => {
    //根据文件的相对路径获取模块的文件名
    let moduleName = path.replace(/(.*\/)*([^.]+).*/ig, "$2");
    //兼容处理:.default获取ES6规范暴露的内容; 后者获取commonJS规范暴露的内容
    modules[moduleName] = importAll(path).default || importAll(path)
 });

此时modules对象就已经自动合并了目标文件夹匹配到的文件export出来的模块信息。

  1. 将模板对象添加到vuex模块
const store = new Vuex.Store({
    modules: {
        ...modules,
    }
})

总结

通过使用require.context这个api,可以帮助我们在开发大型项目时实现模块的自动化导入功能,极大的解放了我们的注意力,使得的我们的关注点在模块的应用,而不需要过分的关注模块是否注册,并且一旦配置,一劳永逸。