[eggjs/egg]【请教】egg能否实现运行时挂载新的插件?

2025-10-27 346 views
9
What happens?

遇到了这样一个需求场景,希望能够在运行时,从外部导入一个插件,然后能够在运行状态下把这个新导入的插件加载进来。 想问下,大家有什么思路么,实现这样的效果。

目前我能想到的是,导入插件包,然后修改plugin.js文件,写入新的插件的配置,然后重启egg服务,达到引入新插件的目的。但是这种方案有两点不好:

  1. 需要入侵应用源代码,修改plugin.js
  2. 需要重启服务

我在想,能否通过调用egg的loader来实现这样的逻辑,但是不太确定loader能否加载plugin,以及如何加载plugin。

希望大家能给一些好的建议,谢谢各位。

回答

1

不支持动态挂载,虽然你可以调用 loader api,但生命周期,还有 Middleware,其他插件的 Config 这些已经注册过的改不了了。

建议重新 Review 下需求是否合理。

6

嗯,感谢回复,我另想办法吧。

2

插件的范畴和灵活性太大了,建议 Review 下你的需求是啥,譬如只是动态更新 DSL 配置之类的,这些还是可以做的。但你要说动态加载一个 mysql 插件,然后还要建联啥的,肯定得不偿失。

3

插件的范畴和灵活性太大了,建议 Review 下你的需求是啥,譬如只是动态更新 DSL 配置之类的,这些还是可以做的。但你要说动态加载一个 mysql 插件,然后还要建联啥的,肯定得不偿失。

那到不至于,这边主要场景是我的服务实现了一套主干业务流程,可以满足80%的业务场景,但是针对剩余20%的业务场景有个性化需求,所以我在思考以插件的方式,让使用者可以基于插件开发个性化需求,然后挂在到我的服务上,而且我会在服务上提供一些常用的基础能力,来简化插件的开发。所以我之前也在egg提过需求,希望插件能够支持路由和controller,这样插件就跟应用十分类似了,扩展性也增强了很多。

我看了一下egg的源码,发现egg在加载插件时,有一条分支是判断process.env.EGG_PLUGINS,我是不是可以利用这个变量呢,这样我在启动时,去扫描一个约定好的目录,然后把扫描到的扩展插件信息加载到这个变量上,然后让egg进行后续操作,这样就相当于具备了动态加载插件的能力,而不仅仅靠plugin.js来声明插件的加载顺序了。当然了,这种方案还是需要重启服务的。

7

也可以参考下 https://github.com/eggjs/tegg , 里面约定了一个叫 module 的规范,然后实现了 loader 加载,算是深度定制了。

9

如果你只是为了加载某些文件,直接用 loader api 就可以了,没必要用 plugin,自己约定一个目录规范即可, 可以看下 https://zhuanlan.zhihu.com/p/153322661https://zhuanlan.zhihu.com/p/154643011

插件的路由和 Controller 可以自己在插件的 app.js 里面处理下即可,暂不考虑实现。

嗯,看完这两篇文章学到了很多,尤其是框架这块,对同时支持多个应用的能力升级还是很有用的。 回过头来,插件这块,其实我这样搞的初衷还是为了让研发同学降低开发成本,用插件并且让插件支持controller的收益在于可以让研发同学无差别的开发应用和插件,因为egg默认的约定是比较合理且简单的,在原有约定下开发肯定成本是更低的。

8

也可以参考下 https://github.com/eggjs/tegg , 里面约定了一个叫 module 的规范,然后实现了 loader 加载,算是深度定制了。

这个项目做了一个什么事我没看明白。没有介绍一下背景,解决了什么问题。直接看使用示例感觉是实现了一套依赖注入的能力?。

3

你可以看下我最后发的那个,插件本身的定位是能力扩展,偏向基础服务的能力扩展。而不是业务逻辑的复用,这块我们准备抽离为 module 。

没看懂很正常,因为刚开始放出来,文档啥的还没有。

7

哦哦,好的,感谢指导,暂时我的需求用插件基本能实现。后续我会关注tegg这个项目,搞清楚了之后,我再优化一下。