在学习EggJs企业级web开发框架时,Egg 奉行『约定优于配置』,按照一套统一的约定进行应用开发,Egg 的插件机制有很高的可扩展性,一个插件只做一件事(比如 Nunjucks 模板封装成了 egg-view-nunjucks、MySQL 数据库封装成了 egg-mysql)。Egg 通过框架聚合这些插件,并根据自己的业务场景定制配置,这样应用的开发成本就变得很低。
文档分析
自己需要开发eggjs的插件就需要根据官方提供的文档进行学习,按照统一的开发约定进行开发。是不是看完官方文档还是一头雾水,不知道从何下手,或者你在网上搜索的内容都是一模一样的。
官方文档关键信息
插件没有独立的 router 和 controller。这主要出于几点考虑:
- 路由一般和应用强绑定的,不具备通用性。
- 一个应用可能依赖很多个插件,如果插件支持路由可能导致路由冲突。
- 如果确实有统一路由的需求,可以考虑在插件里通过中间件来实现。
插件需要在
package.json
中的eggPlugin
节点指定插件特有的信息:{String} name
- 插件名(必须配置),具有唯一性,配置依赖关系时会指定依赖插件的 name。{Array} dependencies
- 当前插件强依赖的插件列表(如果依赖的插件没找到,应用启动失败)。{Array} optionalDependencies
- 当前插件的可选依赖插件列表(如果依赖的插件未开启,只会 warning,不会影响应用启动)。{Array} env
- 只有在指定运行环境才能开启,具体有哪些环境可以参考运行环境。此配置是可选的,一般情况下都不需要配置。
1
2
3
4
5
6
7
8
9{
"name": "egg-rpc",
"eggPlugin": {
"name": "rpc",
"dependencies": [ "registry" ],
"optionalDependencies": [ "vip" ],
"env": [ "local", "test", "unittest", "prod" ]
}
}插件没有
plugin.js
:eggPlugin.dependencies
只是用于声明依赖关系,而不是引入插件或开启插件。
包括了
path
和package
两种加载模式config/plugin.js
中通过path
来挂载插件。
1
2
3
4
5
6// config/plugin.js
const path = require('path');
exports.ua = {
enable: true,
path.join(__dirname,'../lib/plugin/egg-xml-par')
};package.json
中声明对egg-ua
的依赖。config/plugin.js
中修改依赖声明为package
方式。
1
2
3
4
5// config/plugin.js
exports.ua = {
enable: true,
package: 'egg-xml-par',
};
搭建简单的开发环境
安装eggjs基础脚手架
我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目(npm >=6.1.0
):
1 | $ mkdir egg-example && cd egg-example |
启动项目进行测试:
1 | $ npm run dev |
新建插件环境
- 新建插件文件夹lib (插件所有的配置,代码都在这里面)
- 我们是做一个解析xml请求的中间件插件,所有需要搭建下图的结构
1 | . lib |
配置插件基础信息
Egg 是通过 eggPlugin.name
来定义插件名的,只在应用或框架具备唯一性
1 | //lib/plugin/egg-xml-par/package.json |
将插件加入中间件
在 app.js
中将中间件插入到合适的位置(例如:下面将 xmlPar中间件放到 bodyParser 之前)
1 | //lib/plugin/egg-xml-par/app.js |
写插件核心代码
1 | //lib/plugin/egg-xml-par/app/middleware/xml-par.js |
1 | //lib/plugin/egg-xml-par/config/config.default.js |
Egg.js使用自定义插件
package
是npm
方式引入,也是最常见的引入方式path
是绝对路径引入,如应用内部抽了一个插件,但还没达到开源发布独立npm
的阶段,或者是应用自己覆盖了框架的一些插件- 关于这两种方式的使用场景,可以参见渐进式开发。
1 | // config/plugin.js |
取消egg.js自带解析器与关闭csrf验证
1 | // config/config.default.js |
完整项目结构
运行测试
因为接口定义未post,为了方便这里需要关闭csrf验证
1 | // config/config.default.js |
未使用插件
发现返回结果没有显示
使用插件测试
记得要关闭默认的解析
1 | // config/config.default.js |
其他说明
开发其他插件原理类似,希望看完该内容你有点收获