TypeORM Fluent Migrator:两天完成拖了一年的开源项目

以前写代码是靠时间堆;现在有了 AI,可以把更多时间用在创造力上。想做的东西,别再拖了,让 AI 帮你完成它。

🎯 背景与痛点:为什么做这个项目?

这个想法已经酝酿超过一年了。在过去4年的开发中,写了数不清的 migration,对 TypeORM 的 migration API 可以说是了如指掌,也正因为如此,深知它的痛点在哪里。

为什么需要 Migration?

在项目中使用 TypeORM 时,migration(数据库迁移)是必不可少的:

Migration 的好处:

  • 版本控制:数据库结构变更可追踪、可回滚
  • 团队协作:多人开发时,数据库结构变更统一管理
  • 环境一致性:开发、测试、生产环境数据库结构保持一致
  • 可追溯性:每次变更都有记录,方便排查问题

但原生 TypeORM Migration 的痛点:

  • 代码冗长:创建一个简单的表需要大量样板代码
  • 可读性差:嵌套深、属性分散,读起来像配置文件
  • 类型不安全:字符串类型容易拼写错误,运行时才发现
  • IDE 支持弱:缺少智能提示,每次都要查文档
  • 维护成本高:修改一个字段要改多个地方

使用 Fluent API 的收益:

  • 代码量减少一半以上:从 20+ 行缩减到 4-5 行
  • 可读性提升:读起来像自然语言,一目了然
  • 类型安全:编译期检查,减少运行时错误
  • 开发效率提升:IDE 智能提示,无需查文档

在项目中使用 TypeORM 时,migration 代码总是让人头疼:

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
27
28
29
// 原生 TypeORM 的写法
await queryRunner.createTable(
new Table({
name: 'users',
columns: [
{
name: 'id',
type: 'int',
isPrimary: true,
isGenerated: true,
generationStrategy: 'increment',
},
{
name: 'name',
type: 'varchar',
length: '255',
isNullable: false,
},
{
name: 'email',
type: 'varchar',
length: '255',
isUnique: true,
isNullable: false,
},
],
}),
true
);

字段、表、索引、nullable、default,全都是一堆拼字符串和函数调用。代码冗长、嵌套深、可读性差。

在很早之前使用过 .NET 相关的库,写起来就很丝滑。.NET 的 migration 库 FluentMigrator – 代码读起来就像一句话:

1
2
3
4
Create.Table("users")
.WithColumn("id").AsInt32().PrimaryKey().Identity()
.WithColumn("name").AsString(255).NotNullable()
.WithColumn("email").AsString(255).NotNullable().Unique();

而且作者在实际工作中,也有很多半成品的设计,但每次在项目中都重复写一些工具类,一直想把想法实现成开源库发布出来。Node 社区也应该有这种东西!

但每次想开坑,总是被各种借口拖延:

  • “工作太忙,没时间”
  • “实现起来太复杂,要处理各种数据库差异”
  • “Builder 模式设计起来很麻烦”
  • “测试用例要写很多”
  • “还要写文档、做官网,太费时间”
  • “部署、配置域名这些运维工作太繁琐”
  • “npm 发布流程不熟悉,容易出错”

就这样,这个想法在 TODO 列表里躺了一年多。

🚀 AI 的角色:不是替你写代码,而是加速度

直到最近,意识到:AI 不是工具,是帮你摆脱 inertia 的 co-founder。

以前做项目,花 80% 时间查 API 和踩坑;这一次,AI 帮作者把那 80% 搬走了。

AI 如何变成 pairing partner

这次决定不再拖延,直接让 AI 帮助完成它。AI 如何变成 pairing partner:

  • 设计 DSL:描述需求,AI 设计出流畅的 API 语法
  • 生成骨架代码:Builder 模式、类型定义、核心架构,AI 快速搭建
  • 补齐细节:跨数据库兼容、类型转换、边界情况处理
  • 生成示例:十几个 migration 示例,覆盖各种使用场景

而开发者负责:

  • 决策:架构设计、API 风格、技术选型
  • Quality Control:代码 review、测试验证、性能优化
  • 指路:告诉 AI 方向,纠正错误,完善细节

AI = 乘法器。它让开发者从”想法”直接跳到”成品”,而不是卡在”开始”这一步。

💡 项目愿景 & DSL 设计:从 idea 到 API 原型

DSL 设计目标如下:

1
2
3
4
5
6
FL.use(queryRunner)
.create.table('users')
.column('id').int.primary.autoIncrement
.column('name').varchar(255).notNull
.column('email').varchar(255).unique.notNull
.execute();

读起来像英语,这就是设计目标。

与 TypeORM 原生对比:

维度 原生 TypeORM typeorm-fluent-migrator
代码量 冗长,需手动 new Table() 精简,减少 50-70%
可读性 嵌套深,属性分散 线性,像读英文句子
类型安全 可能运行时错误 编译期检查
IDE 支持 有限的自动补全 完整的 IntelliSense

TypeORM 本可以更好,但它 migration API 比较偏底层。目标是”就像写模型一样写迁移”。

⚡ 开发过程:Day 1 & Day 2

🟦 Day 1:0% 到 80% - 核心开发

这是第一次感受到”从想法到可用产品”的速度。一天时间,完成了核心功能的开发。

快速设计 DSL 语法

向 AI 描述需求:”设计一个 Fluent API,支持链式调用,要类型安全,读起来像英语。”

AI 设计出了核心架构:

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
27
// FL.ts - 核心入口
export class FL {
static use(queryRunner: QueryRunner): FL {
return new FL(queryRunner);
}

get create() {
return {
table: (name: string) => new TableBuilder(name, this.queryRunner),
index: (name: string) => new IndexBuilder(name, this.queryRunner),
};
}

get alter() {
return {
table: (name: string) => new AlterTableBuilder(name, this.queryRunner),
};
}

get drop() {
return {
table: async (name: string) => {
await this.queryRunner.dropTable(name, true);
},
};
}
}

构建 Builder 架构

AI 实现了完整的 Builder 链式调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ColumnBuilder.ts
export class ColumnBuilder extends BaseColumnBuilder {
column(name: string): ColumnBuilder {
return new ColumnBuilder(name, this.tableBuilder);
}

get int() { return this.type('int'); }
get varchar() { return this.type('varchar'); }
get text() { return this.type('text'); }
get primary() { /* 设置主键 */ return this; }
get autoIncrement() { /* 设置自增 */ return this; }
get notNull() { /* 设置非空 */ return this; }
get nullable() { /* 设置可空 */ return this; }
get unique() { /* 设置唯一 */ return this; }
default(value: any) { /* 设置默认值 */ return this; }
}

支持核心功能

一天内完成了所有核心功能:

  • createTable - 创建表,支持所有列类型
  • dropTable - 删除表
  • addColumn - 添加列(在 alter 上下文中)
  • dropColumn - 删除列
  • alterColumn - 修改列
  • 约束支持primaryautoIncrementnullable/notNulluniquedefault
  • 索引支持create.index()drop.index()
  • 外键支持references()onDelete()onUpdate()

TypeORM QueryRunner 集成

完美集成 TypeORM 的 QueryRunner API,无缝对接现有 migration 流程。

第一个成功的 Migration

当第一个 FL.use(queryRunner).create.table('users').column('id').int.primary.autoIncrement.execute() 真的成功建表时,这个项目成了。

一天结束,核心功能已经可以实际跑 migration 了。从 0% 到 80%,这就是 AI 加速的力量。


🟦 Day 2:从 80% 到 100% - 生态建设

第二天,把一个”能用的库”变成了”完整的开源产品生态”。这是文章的亮点,也是第一次感受到”开源项目完成得这么丝滑”。

1️⃣ 打磨 API 和 Examples

增加链式语法糖

优化 API 设计,让链式调用更自然、更流畅:

1
2
3
4
5
6
// 支持在链式调用中随时切换上下文
await FL.use(queryRunner)
.create.table('users')
.column('id').int.primary.autoIncrement
.column('name').varchar(255).notNull
.execute();

编写 Demo Migrations

AI 生成了十几个 migration 示例,覆盖:

  • 创建表的各种场景
  • 修改表的复杂操作
  • 外键和索引的使用
  • 不同数据库的兼容性示例

针对不同的功能,添加完整的测试

为每个核心功能编写完整的测试用例:

  • 创建表的各种场景测试
  • 修改表的操作测试(addColumn、dropColumn、alterColumn)
  • 索引和外键的测试
  • 不同数据库的兼容性测试(MySQL、PostgreSQL、SQLite)
  • 边界情况和错误处理测试

确保所有功能在不同数据库上都能完美运行。

2️⃣ npm 发布

准备发布材料

  • 完善 package.json:配置 exports、types、files
  • 生成 TypeScript 类型定义文件
  • 配置构建脚本(tsup)
  • 准备 LICENSE(MIT)

Release 到 npm

1
npm publish

包名:typeorm-fluent-migrator,版本:0.0.2

写 README

AI 写了完整的中英文 README:

  • 特性介绍
  • 快速开始
  • API 文档
  • 代码对比
  • 使用示例

3️⃣ 做官网

使用 VitePress 搭建文档站

选择 VitePress 作为文档框架,快速搭建多语言文档网站:

  • 📄 首页:项目介绍、快速开始、特性展示
  • 📚 指南:安装、使用、对比
  • 🔧 API 文档:列类型、约束、操作说明
  • 💡 示例:创建表、修改表、索引等实际案例

VitePress 文档网站

编写文档内容

AI 完成:

  • 生成完整的 API 文档
  • 编写使用示例
  • 制作代码对比图
  • 设计文档结构

API 文档网站

4️⃣ 上线到 Cloudflare Pages

绑定 GitHub 自动部署

配置 GitHub Actions,实现:

  • 代码推送到 main 分支自动触发构建
  • 自动部署到 Cloudflare Pages
  • 无服务器免费托管

部署流程

  1. 推送代码到 GitHub
  2. GitHub Actions 自动构建 VitePress 站点
  3. 自动部署到 Cloudflare Pages
  4. 几分钟内网站上线

部署到 Cloudflare Pages

5️⃣ 配置域名

选域名

刚好手里有备案好的域名,直接使用即可。

DNS 解析

配置 DNS 记录,指向 Cloudflare Pages。

HTTPS 自动签发

Cloudflare 自动提供 HTTPS 证书,无需手动配置。

6️⃣ 写开源故事 & 博客文章

宣布项目

在 GitHub 发布 Release,介绍项目愿景和特性。

解释愿景

在 README 和文档中清晰说明:

  • 为什么做这个项目
  • 解决了什么问题
  • 如何使用

7️⃣ Logo 设计 & 可视化素材

用 AI 生成 Logo

使用 AI 工具生成项目 Logo,体现”流畅”和”迁移”的概念。

更新素材

  • 更新 README 头图
  • 官网首页 Banner
  • 社交媒体分享图

🎉 两天时间,从想法到完整的开源产品生态

这是第一次感受到”开源项目完成得这么丝滑”。从核心功能开发,到 npm 发布,到官网上线,到域名配置,再到这篇博客文章,所有环节都在两天内完成。

以前做项目,花 80% 时间查 API 和踩坑;这一次,AI 帮作者们把那 80% 搬走了。

🎨 产品展示:功能、案例、对比

核心功能

1. 创建表

1
2
3
4
5
6
7
await FL.use(queryRunner)
.create.table('users')
.column('id').int.primary.autoIncrement
.column('name').varchar(255).notNull
.column('email').varchar(255).unique.notNull
.column('age').int.nullable
.execute();

2. 修改表

1
2
3
4
5
6
await FL.use(queryRunner)
.alter.table('users')
.addColumn('phone').varchar(20).nullable
.dropColumn('oldStatus')
.alterColumn('name').varchar(100).notNull
.execute();

3. 外键

1
2
3
4
5
6
7
8
9
await FL.use(queryRunner)
.create.table('posts')
.column('id').int.primary.autoIncrement
.column('title').varchar(100).notNull
.column('authorId').int.notNull
.references('users', 'id')
.onDelete('CASCADE')
.onUpdate('RESTRICT')
.execute();

4. 索引

1
2
3
4
5
6
await FL.use(queryRunner)
.create.index('idx_users_email')
.on('users')
.column('email')
.unique
.execute();

代码对比

原生 TypeORM(23 行):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
await queryRunner.createTable(
new Table({
name: 'users',
columns: [
{
name: 'id',
type: 'int',
isPrimary: true,
isGenerated: true,
generationStrategy: 'increment',
},
{
name: 'name',
type: 'varchar',
length: '255',
isNullable: false,
},
],
}),
true
);

typeorm-fluent-migrator(4 行):

1
2
3
4
await FL.use(queryRunner)
.create.table('users')
.column('id').int.primary.autoIncrement
.column('name').varchar(255).notNull.execute();

代码减少 70%,可读性提升 100%。

已支持的功能

  • ✅ 核心 API FL.use(queryRunner)
  • create.table() 支持所有列类型
  • alter.table() 支持 addColumndropColumnalterColumn
  • ✅ 外键支持 references()onDelete()onUpdate()
  • ✅ 索引支持 create.index()drop.index()
  • ✅ 数据库特定类型(MySQL、PostgreSQL、SQLite)
  • ✅ 完整的 TypeScript 类型安全

如果你对 migration 痛苦过,请来 GitHub 点个 Star,顺手提 PR 😉

🤔 收获与反思:AI + 工程师 = 新生产力范式

这次经历深刻理解了 AI + 工程师的协作模式

AI 不是帮你偷懒,是帮你开始

AI 不是帮你偷懒,是帮你开始。它让开发者进入高速迭代状态,尤其是灵感很足的时候。

以前总是卡在”从哪开始”这一步,现在 AI 帮助快速搭建架子,让开发者直接进入”创造”的状态。

工程师仍然负责核心工作

虽然 AI 帮了很多忙,但工程师仍然负责:

  • 体系架构:整体设计、模块划分、技术选型
  • Code Review:检查 AI 生成的代码,确保质量和正确性
  • 做 Tradeoff:性能 vs 可读性、功能 vs 复杂度
  • 判断正确性:验证逻辑、测试边界情况
  • 定义 API 风格:决定 DSL 的设计、用户体验

关键洞察

  1. 降低启动成本:AI 帮助快速搭建架子,不用再担心”从哪开始”
  2. 加速迭代:改一个需求,AI 帮助改所有相关代码
  3. 处理细节:跨数据库兼容、类型转换,这些繁琐的工作 AI 做得很好
  4. 保持创造力:把时间用在”做什么”,而不是”怎么做”

实际效果

  • 开发时间:从预估的 2-3 周缩短到 2 天
  • 代码质量:AI 生成的代码经过 review,质量可控
  • 测试覆盖:AI 生成了完整的测试用例
  • 文档完善:README、API 文档、示例代码,一应俱全
  • 产品生态:不仅完成了库,还做了官网、部署、域名配置

AI 不是代替工程师,而是帮你把精力留给创造。

🎉 总结 & 开源发布

项目信息:

欢迎 Star、Issue、PR!

如果社区参与,我们可以一起:

  • 添加更多功能
  • 优化性能
  • 完善文档

💭 最后的话

从拖延到完成的感受

这个项目证明了一件事:真正缺的不是时间,而是启动按钮。 AI 就是帮助按下那个按钮的力量。

以前写代码是靠时间堆;现在有了 AI,可以把更多时间用在创造力上。

下一次打算用 AI 做什么?

已经开始规划下一个项目了。有了这次经验,知道:

  • 开始永远比完美更重要
  • AI 可以帮助快速验证想法
  • 从想法到产品,可能只需要几天

给读者的建议

想做的东西,别再拖了,让 AI 帮你完成它。

无论是:

  • 一个工具库
  • 一个开源项目
  • 一个产品原型
  • 一个学习项目

开始永远比完美更重要。 AI 可以帮你快速启动,剩下的就是持续迭代。


这个项目证明了一件事:

真正缺的不是时间,而是启动按钮。
AI 就是帮助按下那个按钮的力量。


🤖 彩蛋:这篇文章也是 AI 辅助创作的

对了,这篇文章本身也是 AI 辅助创作的。不过技术创作者有个好处:AI 辅助只是减少了工作量,而不是替代了思考。代码能跑、逻辑能通、架构能立,这些都需要技术判断,AI 只是帮你把想法更快地变成文字和代码。

相比之下,文学创作者可能更”危险”一些——毕竟文笔和创意是他们的核心竞争力,而技术创作者的核心竞争力是解决问题的能力,AI 只是让这个能力发挥得更快。

整个项目使用到的 AI 技术:

  • 🤖 Cursor - 代码编辑和补全
  • 🤖 OpenAI - 代码生成和架构设计
  • 🤖 Gemini - 文档编写和代码审查
  • 🤖 Grok - 创意灵感和问题解决

所以,技术创作者们,大胆拥抱 AI 吧!它不会抢走你的饭碗,只会让你更强大。


相关链接:


TypeORM Fluent Migrator:两天完成拖了一年的开源项目
https://blog.ktzz.cc/2026/01/16/typeorm-fluent-migrator-ai-assisted-development/
作者
coco
发布于
2026年1月16日
许可协议