[RFC] egg-bin generate
- Dominant language
- TypeScript
- Stars
- 19k
- Forks
- 1.8k
- PR merge metrics
- No merged PRs in 30d
Description
## 目标
在 egg 的各种解决方案总是会遇到自动生成代码,比如根据 http 接口生成 proxy 文件,根据数据库表信息生成 DAO,自动生成 typescript 的代码等。
在现在的模式下需要提供各种命令行工具,如何都集成到 egg-bin 中会成为庞然大物,所以系统提供一种模式来写生成器。
## 方案
`egg-bin generate` 为这个方案的命令行工具,通过一个命令可生成多种格式的文件,具体的生成工作由插件完成,这有几个好处
1. 插件的开关可影响是否生成,比如一个 orm 库,可以自动根据表结构来生成 orm 的代码,当用户执行 `egg-bin generate` 后就会执行这段逻辑,但是当开发者关闭这个插件后就不会自动生成。所以由插件开发者为应用开发者决定了这个问题。
2. 生成器和插件强相关,如果分开插件和工具两个库,使用者也会比较麻烦,如果升级了还会遇到版本不匹配的问题。
3. 对使用者透明,使用者只需要感知一个命令(某些场景下可能需要传参)。
### 执行流程
1. `egg-bin generate` 运行后根据 egg 的插件配置加载已开启的插件
2. 识别自带 generator 的插件
3. 根据插件的依赖顺序执行 generator
4. 每个 generator 运行时可拿到上下文,并同步执行
5. 执行完成
### 插件结构
egg-xxx 的目录结构,增加了 generator 这个目录
```
|- app
|- generator
| `- index.js
`- package.json
```
在 package.json 增加一个属性标识支持生成器
```json
{
"eggPlugin": {
"name": "xxx",
"generator": true
}
}
```
index.js 文件返回一个类,参数可以获取上下文
```js
module.exports = class Generator {
constructor(options) {
// options.baseDir 应用项目路径
// options.env 环境变量
// options.plugins 开启的插件
// options.config 配置文件
// options.loadUnit 加载单元
// options.args 命令行参数
// ...
}
async generate() {
// 执行逻辑
}
}
```
一般生成器都会有自己的配置文件,可以根据 baseDir 来读取,并决定如何生成,具体生成逻辑就不细说了。
### 遇到的问题
1. 多个 generator 可能会带来冲突。但是这个是无法避免的,例如在插件中也可能遇到覆盖属性的问题。
Contributor guide
Assessment
This issue has not been assessed yet.