使用 require.context 实现模块自动导入

1,001 阅读1分钟

前言

在写资源导航的时候,我在将资源分类为一个文件的时候,发现如果我每定义一个分类,那我就需要创建一个文件,然后又要通过import form导入,就很烦躁。

image-20210912080353288

突然想到貌似vue-element-admin中的路由好像也是这样的,而store貌似定义完就无需再次导入,于是就开始研究代码,果不其然,发现了require.context

image-20210912080429237

依赖管理 | webpack 中文文档 (docschina.org)

实现

require.context:是一个webpack提供的api,通过执行require.context函数遍历获取到指定文件夹(及其下子文件夹)内的指定文件,然后自动导入。

语法:require.context(directory, useSubdirectories = false, regExp = /^.//)

  • directory 指定文件
  • useSubdirectories 是否遍历目录的子目录
  • regExp 匹配文件的正则表达式,即文件类型

而上图代码中对应的代码也明确表达要指定./modules目录下的,所有js文件

 const modulesFiles = require.context('./modules', true, /.js$/)

输出一下看看modulesFiles到底是什么(console.dir输出)

image-20210912081146031

返回一个函数,但该函数包含三个属性 resolve()、keys()、id

其中modulesFiles.keys()则是指定目录下文件名数组

  ['./app.js', './permission.js','./settings.js', './tagsView.js', './user.js']

接着看下vue-element-admin中的下一行代码

 const modules = modulesFiles.keys().reduce((modules, modulePath) => {
   // set './app.js' => 'app'
   const moduleName = modulePath.replace(/^./(.*).\w+$/, '$1')
   const value = modulesFiles(modulePath)
   modules[moduleName] = value.default
   return modules
 }, {})

这边先输出一下modules,看下结果是什么

image-20210912081553729

没错,正对应着modules下的所有文件,以及所导出的对象

其中在循环体中还调用了const value = modulesFiles(modulePath),其中value是Module对象,有个属性default,通过value.default便可获取到对应模块所导出的内容。

就此便可以实现自动导入模块。不过由于导出的是store对象,所封装的代码也有点过于复杂,这边我贴下我是如何自动导入数组对象的

 const modulesFiles = require.context('./modules', true, /.ts$/)
 ​
 let allData: any[] = []
 ​
 modulesFiles.keys().forEach((modulePath) => {
   const value = modulesFiles(modulePath)
   let data = value.default
 ​
   if (!data) return
   allData.push(...value.default)
 })

参考链接

前端优化之 -- 使用 require.context 让项目实现路由自动导入 - 沐浴点阳光 - 博客园 (cnblogs.com)