写代码这几年,我最怕的不是需求复杂,而是同一套初始化动作重复几十遍:建目录、配路由、写类型定义、复制模型模板、改配置文件。版本一升级,模板还要跟着同步改,稍微漏掉一个地方,就是运行时才能暴露的问题。t3code就是我为了解决这一摊子事自己攒的一个命令行工具,核心思路很简单:把工程样板、类型定义、目录结构和路由注册变成一段可配置、可复用的生成规则,用一条命令把整个模块的骨架拉起来。这篇文章会把 t3code 的设计思路、核心实现和实际使用过程完整拆开讲,包括它是怎么处理幂等更新、类型生成、模板复用这些关键点的,以及我在日常项目里踩过的坑和整理出来的排查思路。不管是准备自研脚手架,还是想优化团队现有初始化流程,都可以参考这里面的方案。
1. 项目背景与核心思路拆解
1.1 为什么会做 t3code
先说一下我当时的处境。团队里同时维护着好几个中后台前端项目,外加一部分 Node.js 服务端代码。表面上每个项目都有自己的目录规范和代码风格,实际上大量代码是“长得很像”的:新增一个数据列表,要手写 API 封装、类型声明、页面组件、路由配置、菜单配置;新增一个领域模型,要在服务端定义数据库映射、校验规则、接口出入参类型。这些内容的重复度极高,但不同项目里的写法又不完全一致,新人来了很难在短时间内上手。
最早我们靠 Copy-Paste 解决,先找一个最接近的老模块,复制出来再改字段名。这个方式一开始还行,但随着项目增多、版本迭代,问题就出来了:老模块里的一些废弃逻辑会被一起复制过去,新项目继承了旧债;字段名替换经常遗漏,尤其是字符串里嵌套的字段名;不同项目的目录结构开始分叉,谁也说不好标准是什么。t3code 就是在这样的背景下立项的,它要解决的不仅仅是“生成代码”,而是“让代码生成这件事具备一致性和可维护性”。
1.2 t3code 的三层定位
我给 t3code 的定义是:一个面向业务模块的代码生成与工程初始化工具。它不追求代码生成器那种“从自然语言直接生成完整应用”的效果,而是聚焦在更实际的三层能力上。
第一层是工程脚手架能力。新建项目时,t3code 可以根据预设的工程配置自动生成目录骨架、基础配置文件、CI 检查脚本和公共依赖清单,省去每开一个新仓库都要手工整理一遍配置的麻烦。
第二层是模块级生成能力。这是 t3code 最核心的价值。当需要新增一个业务模块时,t3code 会根据模块描述文件生成一套完整且符合团队规范的代码文件,包含前后端两侧的接口定义、类型定义、路由注册、基础测试用例等,把“在多个文件里同步修改”变成“一次生成,全局一致”。
第三层是规范化收口能力。t3code 内置了模板检查机制,每次生成都会与现有的代码风格、目录规范、命名规范做一次比对。不匹配的地方会给出警告,从工具层面保证所有新模块都按同一套标准落地,而不是靠代码评审人来人工把控。
1.3 为什么选择“配置驱动 + 模板渲染”而非纯代码生成
在技术选型阶段,我对比过两条路线:一条是用脚本直接拼接代码字符串,一条是配置驱动加模板渲染。最终选了后者,原因很现实。
纯代码生成的问题在于,逻辑和代码文本耦合得太紧。比如在生成接口定义时,脚本里既要处理字段类型映射,又要处理注释格式,还要兼顾缩进换行。一旦目录结构或代码风格需要调整,改的是整套脚本逻辑,维护成本非常高。而模板渲染把“生成规则”和“生成内容”分离开:字段类型映射、命名转换这些是逻辑,文件长什么样、代码怎么写是模板。规则变了改逻辑,样式变了改模板,互不干扰。
t3code 的完整生成流程可以拆成五步:读取配置文件、解析模块描述、加载对应模板、执行命名与类型映射、渲染输出文件。每个步骤之间是相对独立的,比如模板里可以调用自定义函数做类型映射,也可以直接使用模块描述里的原始字段名,灵活性比脚本拼接高很多。
2. 核心设计与技术选型解析
2.1 整体架构和目录规划
t3code 本质上是一个 Node.js 命令行工具,结构上按照功能边界拆分成几个模块:配置加载器、模板引擎封装、类型映射器、文件渲染器、脚手架交互界面。
实际目录结构大概是这样:
t3code/ ├── bin/ │ └── t3code.js # CLI 入口 ├── src/ │ ├── commands/ # 子命令实现 │ │ ├── init.js # 初始化工程 │ │ ├── generate.js # 生成模块 │ │ └── validate.js # 校验现有模块 │ ├── core/ │ │ ├── config-loader.js # 配置读取与合并 │ │ ├── schema-parser.js # 模块描述解析 │ │ ├── name-mapper.js # 命名转换(camelCase/kebab-case 等) │ │ └── type-mapper.js # 类型映射(字段类型到 TS/Java/SQL) │ ├── templates/ # 内置模板目录 │ │ ├── frontend/ │ │ ├── backend/ │ │ └── shared/ │ └── utils/ │ └── file-writer.js # 文件写出与冲突检测 └── config/ └── t3code.config.js # 全局默认配置这个结构看起来简单,但对维护非常重要。commands 层只负责解析命令参数和调用 core 层的接口,不直接包含业务逻辑。core 层是纯函数模块,输入输出明确,方便做单元测试。templates 目录则严格隔离在业务代码之外,不参与编译打包,运行时按需读取,这样团队里的前端同学即使不熟悉 Node.js 也可以直接修改模板。
2.2 模板引擎选型:为什么不用现成重框架
最开始我想直接用 handlebars 或者 ejs 这类完整模板引擎,后来仔细评估了一下,对于 t3code 的场景,它们有两个问题。
第一个问题是控制能力太强。模板引擎有自己的语法和内置函数,虽然灵活,但也容易让模板变得复杂。代码生成模板里最常用的其实就是变量替换、条件分支、循环遍历这几样,不需要页面渲染那种复杂的 helper 机制。模板写得越复杂,review 的难度就越高,出错时也更难排查。
第二个问题是与现有类型系统集成不方便。t3code 需要根据模块描述里的字段类型生成 TypeScript 类型、Java DTO、数据库表结构,甚至 OpenAPI 文档片段。这些映射规则是强逻辑性的,放在模板里做会很别扭,我想要的是模板负责“把值放到正确位置”,而“值怎么算出来”交给代码中的 mapper 函数处理。
所以 t3code 最终采用了一个非常轻量的模板方案:模板文件中支持 ${变量名} 和 <% 循环/条件 %> 两种基础语法,其余所有复杂逻辑一律走自定义函数。模板看起来就是普通代码文件,只不过夹杂着少量占位标记,可读性和上手成本都很友好。
一个典型的前端页面模板片段是这样的:
import { defineComponent } from 'vue'; import { useRequest } from '@/hooks/useRequest'; import { <%= moduleName %>ListParams, <%= moduleName %>ListItem } from './types'; export default defineComponent({ name: '<%= moduleName %>List', setup() { const { data, loading, run } = useRequest<<%= moduleName %>ListItem[]>({ url: '<%= apiBaseUrl %>/<%= modulePath %>/list', method: 'GET', }); return { data, loading, run }; }, });2.3 类型映射器的设计与实现
类型映射是 t3code 里面技术含量最高的模块。业务开发中最头疼的问题之一,就是同一个字段在不同的技术栈里类型定义不一致,常见的比如数据库里叫 created_at,Java 里叫 createdAt,前端 TypeScript 里叫 createdTime,类型还可能是 string 或 Date。t3code 的类型映射器解决的就是这个对齐问题。
我设计了一套中间类型系统,统一用类似 integer、string、datetime、boolean、decimal、array 这些标准类型作为中间表达。模块描述文件里写清楚字段的业务类型和约束条件后,t3code 会根据目标语言自动转换成对应的类型声明。
转换规则的部分示例:
| 中间类型 | TypeScript | Java | MySQL | OpenAPI |
|---|---|---|---|---|
| string | string | String | varchar(255) | type: string |
| integer | number | Integer | int | type: integer, format: int32 |
| long | number | Long | bigint | type: integer, format: int64 |
| datetime | string | Date | LocalDateTime | datetime | type: string, format: date-time |
| decimal | number | BigDecimal | decimal(10,2) | type: number, format: double |
| boolean | boolean | Boolean | tinyint(1) | type: boolean |
这个设计带来的直接好处是,模块描述文件不需要关心最终代码长什么样,只描述业务本身。如果未来团队引入新的技术栈,只需要扩展 type-mapper 模块,所有历史模板都能立即使用新类型映射,而不需要逐个改模板。
2.4 命名映射与约定
命名不一致是另一个让人头疼的问题。前端习惯用 camelCase,后端 Java 习惯用 PascalCase 和 camelCase,数据库习惯用 snake_case,路由和目录又用 kebab-case。手写代码时靠人记,生成器则必须有一套自动转换机制。
t3code 的 name-mapper 内置了这些约定之间的转换函数:camelToKebab、camelToSnake、pascalToCamel、kebabToPascal 等。同时在配置里维护了一个“命名对照表”,用来处理一些无法通过规则转换的字段,比如缩写词 ID 转成 Id、URL 转成 Url 的边界约定。这个对照表非常重要,因为纯规则的转换经常会在缩写词上栽跟头。
实际生成的模块名会遵循以下流程:模块描述中只要提供一个业务名称,比如 orderManage,t3code 就会自动生成对应的一组命名变体,包括 order-manage、OrderManage、order_manage、ORDER_MANAGE,并根据不同文件的用途使用对应的变体。比如目录名用 kebab-case,TypeScript interface 名称用 PascalCase,字段名用 camelCase,数据库表名用 snake_case。
3. 实操过程:如何用 t3code 从零生成一个完整模块
3.1 初始化工程和配置文件
先说明一下,下面这段是 t3code 在真实项目中的一次完整使用记录,我用一个相对典型的“订单管理”模块作为示例讲解。
首次使用 t3code 时,第一步是在项目根目录执行初始化命令:
npx t3code init --template vue-ts这条命令会做三件事:检测当前目录是否已经存在 package.json,如果不存在就创建一个基础工程;从内置模板目录复制 vue-ts 对应的公共配置文件到项目里;生成本项目的 t3code.config.js 配置文件。
初始化完成后的配置文件长这样:
module.exports = { projectType: 'vue-ts', sourceRoot: 'src', apiBaseUrl: '/api/v1', naming: { dir: 'kebab-case', file: 'kebab-case', component: 'PascalCase', type: 'PascalCase', }, templates: { frontend: { list: 'frontend/views/list.tpl', detail: 'frontend/views/detail.tpl', types: 'frontend/shared/types.tpl', api: 'frontend/shared/api.tpl', }, backend: { controller: 'backend/controller.tpl', service: 'backend/service.tpl', mapper: 'backend/mapper.tpl', dto: 'backend/dto.tpl', }, }, typeMappings: { // 自定义覆盖默认映射 }, };这里需要留意的是,模板路径支持相对路径和绝对路径。如果你的团队在 git 仓库里维护了一套统一模板,可以在配置里直接写远程 git 地址,t3code 在生成时会自动拉取最新模板。这个功能在团队协作时非常有用,模板迭代再也不用靠人肉同步。
3.2 编写模块描述文件
模块描述文件是 t3code 生成的核心输入,它描述了一个业务模块的所有相关信息。为了降低编写成本,我把它设计成 JSON 格式,并且支持 JSON Schema 校验,写错了字段会有明确提示。
一个订单管理模块的描述文件大概是这样的:
{ "moduleName": "orderManage", "modulePath": "order-manage", "apiBasePath": "/order/manage", "fields": [ { "name": "orderNo", "type": "string", "label": "订单编号", "required": true, "searchable": true }, { "name": "customerName", "type": "string", "label": "客户姓名", "required": true, "searchable": true }, { "name": "orderAmount", "type": "decimal", "label": "订单金额", "required": true }, { "name": "orderStatus", "type": "integer", "label": "订单状态", "required": true, "dict": "order_status" }, { "name": "paymentTime", "type": "datetime", "label": "支付时间", "required": false } ] }在这里,moduleName 是模块的业务名称,所有命名的变体都由它推导;modulePath 是前端的页面目录名;apiBasePath 是接口路径的前缀;fields 数组定义了模块中的核心字段以及它们的展示属性。这里不涉及复杂的业务逻辑,因为模板层会处理大部分展示规则,描述文件只需要提供原始的业务信息。
3.3 执行生成命令
描述文件准备好之后,在项目根目录执行:
t3code generate --desc order-manage.json --target frontend --overwrite命令执行后,控制台会输出每一步的处理结果,包括解析到的字段数量、生成的文件列表、以及是否有模板冲突。生成的核心流程是这样的:
第一步,配置加载器读取 t3code.config.js,同时合并用户在当前目录下的临时配置。这里支持配置覆盖,比如某些模块想临时换一套模板,可以直接在描述文件里指定 templateOverride 字段,不需要改全局配置。
第二步,schema-parser 解析描述文件,做字段合法性检查。这里会重点检查类型是否在中间类型系统内,字段名是否包含非法字符,moduleName 是否符合命名规范。校验失败时会直接中断并提示具体原因。
第三步,加载目标模板。t3code 根据 target 参数选择 frontend 还是 backend,然后加载全部相关模板文件到内存中。
第四步,渲染阶段。每个模板文件都会被当成一个独立的渲染任务,模板中的变量按配置的命名规则映射后填入。渲染完成后,t3code 会对生成的文件做一次“静态语法自检”,比如检查 TypeScript 文件是否包含明显的标签未闭合、括号数量不一致等问题,避免生成出来就是坏文件。
第五步,文件写出。file-writer 会比较目标路径上是否已有同名文件。如果是新增文件,直接写入;如果是已有文件,默认跳过并给出提示,除非带了 --overwrite 参数。
以上面的订单模块为例,生成的文件结构是这样的:
src/views/order-manage/ ├── index.vue ├── detail.vue ├── api.ts ├── types.ts └── components/ └── order-status-tag.vuetypes.ts 里会根据 fields 自动生成对应的接口类型:
export interface OrderManageListItem { orderNo: string; customerName: string; orderAmount: number; orderStatus: number; paymentTime?: string | Date; } export interface OrderManageListParams { pageNum: number; pageSize: number; orderNo?: string; customerName?: string; }3.4 后端模块生成与联调说明
前端生成只是 t3code 的一半能力,它还能同时生成后端的基础代码,让前后端的接口契约完全一致。继续用订单模块举例,执行这条命令:
t3code generate --desc order-manage.json --target backend --overwrite生成的 Java 侧文件结构大致如下:
com/example/order/ ├── controller/OrderManageController.java ├── service/OrderManageService.java ├── service/impl/OrderManageServiceImpl.java ├── mapper/OrderManageMapper.java ├── entity/OrderManage.java └── dto/ ├── OrderManageQueryDTO.java └── OrderManageSaveDTO.java实体类中的字段类型已经自动映射成 Java 类型,同时生成的数据库建表语句是单独输出到一个 schema 目录中的。这里有一个很关键的技巧:前端和后端必须使用同一个描述文件生成,才能保证两边的类型定义始终一致。实际操作中,t3code 也支持在一条命令里同时生成两边:
t3code generate --desc order-manage.json --target all --overwrite这种模式下,t3code 会生成一份接口契约文件,前端、后端都基于同一份类型定义推导,从源头避免“前端字段叫 orderTime、后端字段叫 payTime”这类对齐问题。
3.5 模板自定义的完整示例
t3code 虽然内置了一套通用模板,但真实项目里几乎没有哪套内置模板能直接复用,最终还是要落到自定义模板上。我以实际项目里的一个列表页面模板为例,讲一下自定义模板时需要注意的点。
模板文件本身就是一个普通的 .vue 文件,只是在需要动态变化的位置插入了模板语法:
<template> <div class="<%= modulePath %>-list"> <el-form :model="queryParams" inline> <% fields.forEach(function(field) { if (field.searchable) { %> <el-form-item label="<%= field.label %>"> <el-input v-model="queryParams.<%= field.name %>" placeholder="请输入<%= field.label %>" clearable /> </el-form-item> <% } }); %> </el-form> <el-table :data="tableData" v-loading="loading"> <% fields.forEach(function(field) { %> <el-table-column prop="<%= field.name %>" label="<%= field.label %>" min-width="120" /> <% }); %> </el-table> </div> </template>这种写法看起来简单,但其实藏着一个很容易踩的坑:模板中的小括号和大括号容易错位,特别是嵌套循环加条件判断时,少写一个闭合标签,渲染出来的代码就会有问题。所以我在 t3code 里做了一个模板语法自检工具,所有模板在发布前都会先渲染一次测试数据,并用 esbuild 做一次语法解析,通过之后才允许进入模板仓库。
另外,字段的顺序会影响生成效果的体验。描述文件里的字段顺序,就是页面表格列的展示顺序。这个设计看似简单,却非常实用,可以让接口定义、前端表单、数据库建表语句的字段顺序保持一致,代码审查时一眼就能看出哪里对不上。
4. 增量更新与多项目复用的实战经验
4.1 增量生成时的冲突处理
真正用起来之后,我发现最复杂的问题不是首次生成,而是二次生成。第一次生成模块时一切顺利,但过了一个月,团队决定给所有列表页面增加一个“批量导出”按钮,这时候不可能把所有模块都删掉重新生成一遍,而是要能对已有模块做增量更新。
t3code 的增量生成默认不覆盖已有文件。但如果模板发生了变化,新增了一个文件,或者某个已有文件只是局部需要调整,覆盖策略就变得很关键。我采用的方案是文件级冲突检测加手动确认模式。
在默认的 safety 模式下,t3code 会先生成全部目标文件到内存中,然后与磁盘上的现有文件做对比。如果内容完全一致,跳过;如果内容不一致,输出 diff 摘要,并询问是否覆盖。这样的好处是,只有实际有改动的文件才会进入确认流程,不会因为模板里增加了一个空行就全局弹出确认提示。
实际使用中,我强烈建议在 CI 流程里加上一条校验命令:
t3code validate --desc order-manage.json这条命令会判断当前模块的代码与描述文件是否匹配,如果不匹配则返回非零退出码。配合 pre-commit 钩子,可以保证任何手工改动如果偏离了模块声明,都会在提交前被拦下来。这个机制比代码评审的人工提醒强得多。
4.2 多项目间共享模板与配置
t3code 一开始只是我一个人在用一个项目里用,后来其他项目也想接入,就自然而然地遇到了模板共享问题。每个项目的技术栈略有差异,公共模板只能覆盖一部分,剩下的是项目自定义内容。
我的解决方案是模板分层:第一层是 t3code 内置的基础模板,第二层是团队公共模板仓库的模板,第三层是项目本地的覆盖模板。三层模板按优先级合并,相同路径下项目本地优先于团队公共、团队公共优先于内置。这样不同项目可以共享大约百分之六七十的模板内容,各自的特殊需求在项目本地维护即可,不会互相干扰。
这个分层机制在 t3code 里是通过配置项 templateChain 实现的:
module.exports = { templateChain: [ { type: 'builtin', filter: ['frontend', 'backend'] }, { type: 'git', url: 'https://git.example.com/templates/common.git' }, { type: 'local', path: './templates/project-custom' }, ], };执行生成时,t3code 会按照链的顺序查找模板文件,先在后层的目录里找,找不到再往前一层找。这样设计还有一个隐藏的好处:模板文件可以只覆盖某个子路径,比如只覆盖 frontend/views/detail.tpl,而 list.tpl 仍然使用团队公共版本,灵活度非常高。
4.3 模板迭代中的演进策略
模板不是一次性写好的,而是跟着业务需要不断演进的。在我维护 t3code 的过程中,几乎每个月都会有一些模板改动,有些是修复 bug,有些是调整 UI 风格,有些是为了配合新版本的组件库。
为了保证模板迭代不破坏现有代码,我建立了一套流程:所有模板修改必须同时更新对应的测试夹具数据,测试夹具是一组标准的描述文件,覆盖各种字段类型和边界情况;每个模板在合并前都要跑一遍完整渲染测试,用渲染结果和预期快照做 diff。这一步看起来繁琐,但实际运行中帮了大忙,至少三次在合并前抓到了模板语法的低级错误。
另外,在模板里标明版本号也很重要。t3code 支持在模板文件头部添加元信息注释,比如:
{{!-- t3code:template-version 2.1.0 --}}生成代码时,t3code 会把模板版本信息输出到生成文件的引导注释里。一旦线上出现问题,可以快速定位是哪个版本的模板生成的代码,排查效率提升非常明显。
5. 常见问题与排查技巧实录
5.1 模板渲染结果出现转义字符问题
模板渲染最常见的问题之一,就是代码里的特殊字符被错误转义。有一次我在模板里写了一个包含双大括号的 Vue 表达式,结果渲染出来的文件里变成了转义后的 unicode 字符,前端代码直接报错。
排查思路很简单:先单独渲染一次模板,把输出结果直接打印出来,再用肉眼对比模板源文件,一般很快就能定位到是哪个变量位置出了问题。t3code 为此提供了一个调试命令:
t3code generate --desc order-manage.json --dry-run --verbose--dry-run 表示不写入文件,只在控制台输出渲染结果;--verbose 会输出每个变量的真实值和类型。绝大多数模板渲染问题都能靠这条命令定位。
5.2 生成文件的代码风格和既有项目不一致
t3code 生成的代码是模板规定的风格,但一个已经存在很久的仓库里,代码风格可能和模板风格不一致。比如模板里用的缩进是 4 空格,但项目里实际是 2 空格;模板里字符串用单引号,项目里是双引号。
正面硬刚模板不是一个好思路,因为不同项目的风格差异没法在公共模板里统一。我的做法是引入代码格式化工具作为 t3code 生成流程的最后一步。在项目配置里可以指定 formatter 命令,生成完成后自动执行。比如配置了 prettier,t3code 就会在写完文件后调用 prettier --write 处理所有生成的文件。
这里有一个细节,formatter 执行时不能影响未生成的原始代码文件,否则会引入大量无关 diff。配置上需要把 formatter 的输入范围严格限定在本次生成的文件列表内,而不是对整个目录跑一遍。
5.3 描述文件字段太多导致生成内容过长
有一个模块的描述文件写了四十多个字段,生成的搜索表单页面非常长,体验很差。这个问题一开始我没有太重视,直到几个团队都反馈“表单太长了,没法用”才发现需要引导模板做分组处理。
解决方案是在描述文件里增加一个 group 字段,在模板里做分组渲染。比如订单模块的字段可以分成基础信息、订单状态、时间范围三组,模板里按组输出 el-card 或者 fieldset。这种分组信息属于展示层的配置,放在描述文件里非常合适,模板只是在渲染时读取这个字段而已。调整为分组模板后,长表单页面清爽了很多,而且分组顺序在描述文件里即可调整,不需要改模板。
5.4 Windows 环境下的路径兼容问题
t3code 最初在 macOS 上开发调试,团队成员在 Windows 上使用时,出现了模板路径无法加载的问题。原因很经典:模板配置里写的是 POSIX 风格的相对路径,用的是正斜杠,而 Windows 上拼接文件路径时用了反斜杠,导致部分工具函数兼容性出问题。
修复方式是在所有路径处理函数里统一使用 path.join 和 path.relative,并禁止手动拼接路径字符串。同时,在配置加载时做一个路径归一化处理,无论用户配置里写的是正斜杠还是反斜杠,最终统一转成标准的 POSIX 风格,在写文件时再转成平台原生格式。这个问题解决后,Windows 环境再也没有报过路径相关的错。
5.5 生成结果中类型引用不完整
t3code 生成 TypeScript 类型时偶尔会出现类型引用缺失的报错。比如生成 OrderManageListItem 的时候引用了 OrderStatusEnum,但枚举类型并没有被同时生成。这个问题的根本原因是模板只渲染了它负责的片段,没有考虑到类型之间的依赖关系。
我的解决方案是在类型映射器里增加一个依赖收集机制。字段类型映射时,自动记录该类型依赖的其他类型,比如 integer 类型如果关联了字典,就要输出对应的字典枚举引用。这些依赖信息在渲染阶段会汇总,并自动追加到 types.tpl 的引用声明区域。这样生成的类型文件天然自带完整的依赖注入,不会出现“类型用了但没定义”的低级错误。
6. 我的一些使用心得和扩展建议
t3code 用了大半年之后,我对它的定位有了新的认识:它不是传统意义上的低代码平台,也不是一个代码生成玩具,而是一种“代码生成规则”的播种机。所有模板的维护本质上是在维护团队业务代码的“公约数”,把重复的部分收敛成模板,把差异的部分暴露成配置项,让业务开发者把精力放在真正需要创造力的地方。
如果你也想做一个类似的项目,我建议从范围上先克制住,不要一开始就想着覆盖所有技术栈和场景,先把一个技术栈、一个业务模块类型跑通,再把范围逐步扩大。t3code 前期就是只处理列表加详情两种场景,跑顺了之后才加入后端代码生成和增量更新能力。
另外一个比较实用的扩展点是把它和接口文档管理平台打通。t3code 生成的 OpenAPI 片段可以自动同步到接口文档平台,让前端、后端、测试看的是同一份契约。这个方向我还在实践过程中,目前已经能做到接口定义从 t3code 生成到文档平台展示的自动化流转,差不多省掉了每周整理接口文档的重复劳动。