在我们项目开发中,经常需要import或者export各种模块,那么有没有什么办法可以简化这种引入或者导出操作呢?答案是肯定的,下面就为大家介绍一下require.context
我们会这样引入组件:
import A from 'components/A'
import B from 'components/B'
import C from 'components/C'
import D from 'components/D'
// ...
这样很蛋疼,因为每加一个组件,可能都要写这么一句,这样有规律的事,是否可以通过自动化完成?
看下Webpack [Dependency Management | webpack]
require.context
1 | require.context(directory, useSubdirectories, regExp) |
- directory: 要查找的文件路径
- useSubdirectories: 是否查找子目录
- regExp: 要匹配文件的正则
用法
1 | require.context( './components/' , true , /\.js$/) |
目录结构
一个 context module 会导出一个(require)函数,此函数可以接收一个参数:request。
此导出函数有三个属性:resolve
, keys
, id
。
resolve
是一个函数,它返回 request 被解析后得到的模块 id。keys
也是一个函数,它返回一个数组,由所有可能被此 context module 处理的请求(译者注:参考下面第二段代码中的 key)组成。
上面调用方法,到底返回的是什么?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | var map = { "./A.js" : "./src/components/test/components/A.js" , "./B.js" : "./src/components/test/components/B.js" , "./C.js" : "./src/components/test/components/C.js" , "./D.js" : "./src/components/test/components/D.js" }; function webpackContext(req) { var id = webpackContextResolve(req); return __webpack_require__(id); } function webpackContextResolve(req) { var id = map[req]; if (!(id + 1)) { // check for number or string var e = new Error( "Cannot find module '" + req + "'" ); e.code = 'MODULE_NOT_FOUND' ; throw e; } return id; } webpackContext.keys = function webpackContextKeys() { return Object.keys(map); }; webpackContext.resolve = webpackContextResolve; module.exports = webpackContext; |
webpackContext.id = "./src/components/test/components sync recursive \\.js$";
代码很简单,require.context执行后,返回一个方法webpackContext,这个方法又返回一个__webpack_require__,这个__webpack_require__就相当于require或者import。同时webpackContext还有二个静态方法keys与resolve,一个id属性。
- keys: 返回匹配成功模块的名字组成的数组
- resolve: 接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
- id: 执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载
看下keys是作用
1 2 3 | const ctx = require.context( './components/' , true , /\.js$/) console.log(ctx.keys()) // ["./A.js", "./B.js", "./C.js", "./D.js"] |
其实就是
1 2 3 4 5 6 7 8 | var map = { "./A.js" : "./src/components/test/components/A.js" , "./B.js" : "./src/components/test/components/B.js" , "./C.js" : "./src/components/test/components/C.js" , "./D.js" : "./src/components/test/components/D.js" }; Object.keys(map) |
只不过map是模块内部变量,无法直接访问,所以通过其实提供的keys方法访问
那么如何引入ABCD组件呢?
1 2 3 4 5 6 | const ctx = require.context( './components/' , true , /\.js$/) const map = {} for ( const key of ctx.keys()) { map[key] = ctx(key) } console.log(map) |
看到了吧!成功import进来了,但'./A.js'这样的key有点不太好,自己可以处理字符串生成自己想要的key
可以优化一下,生成一个公共的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | const importAll = context => { const map = {} for ( const key of context.keys()) { const keyArr = key.split( '/' ) keyArr.shift() // 移除. map[keyArr. join ( '.' ).replace(/\.js$/g, '' )] = context(key) } return map } export default importAll 使用 import importAll from '$common/importAll' export default importAll(require.context( './' , true , /\.js$/)) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗