eggjs / eggjs/egg

[RFC] egg-bin generate

Open
#2,723 28 comments 3 reactions 1 assignee Assigned to @atian25 View on GitHub
type: proposals
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.