news 2026/10/27 7:18:38

t3code实战:T3 Stack业务模块代码自动生成与落地经验

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
t3code实战:T3 Stack业务模块代码自动生成与落地经验

这几年我一直在写 Next.js 项目,从最早的 Pages Router 一路用到 App Router,中间换过不少脚手架。如果你也用 T3 Stack(Next.js + TypeScript + Tailwind + tRPC + Prisma + NextAuth),应该会有同感:create-t3-app 帮你把技术选型和项目骨架定了,但每加一个业务模块,还是要手动写一遍 Prisma model、tRPC router、React Query hooks、列表页/表单页,代码高度同构,却没有任何方式能一次生成到位。直到我开始用 t3code 这个工具,这类重复工作才算真正压了下来。这篇文章就把我对它的理解、实际用法和踩过的坑一次讲清楚。

t3code 本质上是一个面向 T3 Stack 工程的代码生成命令行工具,它的目标不是替代 create-t3-app,而是在已有 T3 项目里继续往下走:根据你给出的模型字段和页面需求,直接生成 Prisma schema、tRPC 路由、React 组件、zod 校验、路由注册等一整套业务文件。适合正在做主后台、内容管理、数据分析这类"模型多、操作模式统一"项目的开发者,也适合想把团队代码规范固化下来的前端负责人。下面我按自己的实操顺序,从原理到复现一步步展开。

1. 它解决的是哪一类问题——从"脚手架"到"业务生成器"

1.1 create-t3-app 解决了什么,又留下了什么

T3 Stack 这几年在 React 全栈圈子里扩散很快,原因很简单:它把端到端类型安全这件事做到了极致。Next.js 管页面,TypeScript 管类型,tRPC 管接口,Prisma 管数据库,NextAuth 管登录,Tailwind 管样式。create-t3-app 把这一整套整合成一条命令,几分钟就能拉起一个结构规范、类型联通的项目。对团队来说,这等于把"架构选型"这一步直接标准化了。

但真正进入业务开发后你会发现,create-t3-app 给的只是一副骨架。它能帮你的程度,到"有一个能跑通 hello world 的项目"为止。举个我自己的例子:之前做一个内容管理后台,需要文章、分类、标签、评论、友链、轮播图六个模块。每个模块的数据库表结构不同,但操作模式完全一样——增删改查、列表分页、状态筛选。也就是说,我要把同一套代码逻辑写六遍。第一遍还挺新鲜,写到第三遍就开始烦躁,到第六遍已经是一种机械劳动了。

这种重复和单纯"复制粘贴"还不一样,它分布在六个不同层面:Prisma model 要建表,tRPC router 要写接口,React Query hooks 要封装调用,页面要写列表和表单,zod 要做入参校验,TypeScript 类型要保证前后端一致。任何一个层面漏掉,都会在运行时才暴露问题。更要命的是,这类代码高度同构,最适合用"模板 + 配置"的方式自动化,但团队里很少有人真的去做沉淀。

1.2 一个普通 CRUD 模块的"手工账"

随便挑一个最简单的"留言管理"功能,字段就四个:昵称、邮箱、内容、审核状态。手工开发时你需要动这些文件:

层面文件工作量
数据层prisma/schema.prisma增加模型约 10 行
迁移执行prisma migrate一条命令,但要等
服务层tRPC router 里写createlistdelete约 80 行
校验层zod schema 定义入参约 20 行
前端调用React Query hooks / utils 封装约 40 行
页面列表页 + 表单页 + 弹窗确认约 200 行
路由app router 里注册页面路径约 10 行

合计 7 个文件、接近 360 行代码,而且这还没算 TypeScript 类型推导、加载态处理、错误提示。对一个有四五年经验的前端来说,写完不难,但纯属低水平重复。如果团队里每个人写出来的风格还不一样,后面维护起来的成本更高。我当时算过一笔账:一个六模块后台,手工开发光这类"模板性代码"就要写超过 2000 行,耗时接近一周。

1.3 t3code 的定位:它不是脚手架,是生成器

理解了上面的痛点,就能明白 t3code 的价值坐标。市场上已经有 create-t3-app 解决"项目从无到有"的问题,t3code 切入的是"项目从有到多"的区间——业务模块批量新增和规范化生成。它内部维护了一套模板引擎,预置了 T3 Stack 生态里最常见的代码范式,然后通过命令行参数或配置文件,把"你想新增什么模块、有哪些字段、要不要分页、需不需要审核流"这些需求描述变成实实在在的代码。

我最早是在一个开源仓库的 issue 里看到有人提到这个工具,那会儿它还只支持简单的 model 生成。后来版本迭代以后,逐渐加入了 zod 校验、React Query hooks、页面模板,甚至支持自定义模板目录。它的核心使用方式也就几行命令,但背后对应的是对 T3 Stack 项目结构的深度理解。接下来我详细说一下它的设计和实际用法。

2. 工具概览与快速上手——安装、初始化、生成第一个模块

2.1 环境要求与安装

先说环境要求。t3code 是一个运行在 Node.js 环境下的 CLI 工具,要求 Node.js 18 以上,考虑到 Next.js 14 / 15 本身也要求这个版本,通常不会成为障碍。包管理器方面,npm、pnpm、yarn 都可以,但建议在 T3 项目里保持一致,避免 lockfile 混乱。

安装分两步走。如果你还没有 T3 项目,先用官方脚手架建一个:

npx create-t3-app@latest my-app

等依赖装完、基础项目能跑起来之后,再引入 t3code:

npx t3code@latest init

这个init命令做的事有两个:一是在当前项目里生成t3code.config.ts配置文件,二是把默认模板目录拷贝到.t3code/templates下。配置文件里可以指定生成代码的风格、是否启用分页、是否包含审核字段等;模板目录则是自定义生成逻辑的入口。如果你不想让项目里多出一堆模板文件,也可以跳过init直接使用内置模板,但我不建议这么做,后面会讲自定义模板能带来多大的灵活性。

安装完成后,可以用下面的命令验证:

npx t3code --version

正常输出版本号就说明安装成功。如果是在 CI 环境或团队内部要统一版本,记得把它写入 devDependencies 并锁版本。

2.2 命令结构一览

t3code 的命令设计得比较克制,核心就这几个:

命令说明
t3code init初始化配置和模板目录
t3code generate根据配置生成业务模块,简写g
t3code list列出可用的模板和已生成的模块
t3code dry-run模拟生成,不写文件,只展示将产生的变化
t3code doctor检查当前项目的 T3 配置完整性

日常使用中最常碰到的自然是generate。它的参数分为两个层次:全局配置和模块描述。全局配置在t3code.config.ts里管理,例如:

import { defineConfig } from 't3code'; export default defineConfig({ projectType: 'next-app-router', databaseProvider: 'prisma', auth: 'next-auth', ui: 'tailwind', features: { pagination: true, softDelete: false, auditFields: true, }, templateDir: '.t3code/templates', outputDir: { schema: 'prisma', router: 'src/server/api/routers', page: 'src/app', hooks: 'src/hooks', }, });

模块描述则在命令行里透传。一个典型的生成命令长这样:

npx t3code g model Product \ --fields "name:string,price:float,stock:int,isActive:boolean" \ --relations "category:Category:one-to-many" \ --include list,create,edit,delete \ --pagination true

这段命令的意思是:生成一个Product模块,包含四个字段,关联到已有的Category模型,生成列表、新增、编辑、删除四个能力,并启用分页。不用几秒钟,文件就出来了。下面我拆开讲讲文件结构和关键内容。

2.3 生成后的文件结构

执行完上面的命令,t3code 会在你的项目里做这些改动:

prisma/schema.prisma # 追加 Product 模型定义 prisma/migrations/xxx_product # 自动生成迁移文件(如果配置开启) src/server/api/routers/product.ts # tRPC router,包含 create、list、delete 等方法 src/server/api/root.ts # 自动注册 productRouter src/hooks/useProduct.ts # React Query hooks 封装 src/app/products/page.tsx # 列表页(含分页) src/app/products/new/page.tsx # 新增页 src/app/products/[id]/edit/page.tsx # 编辑页 src/lib/validations/product.ts # zod 校验 schema

我特别想说的是它对schema.prisma的处理。它不会把整个文件重写,而是在文件末尾按模型块追加:

model Product { id String @id @default(cuid()) name String price Float stock Int isActive Boolean @default(true) category Category @relation(fields: [categoryId], references: [id]) categoryId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }

注意createdAt和updatedAt是它自动补的审计字段,不需要你手动声明,这就是配置文件里auditFields: true的作用。如果不需要,在配置里关掉就行。

如果配置了pagination: true,生成的 router 里会自动带上limit和cursor参数,用 Prisma 的 cursor 分页而非 offset。原因是 cursor 分页在大数据集下性能更稳定,尤其在配合搜索、筛选的场景里,不会因为页码偏移导致重复或漏数据。这个细节看得出工具作者是真踩过分页坑的。

3. 核心原理与设计——模板引擎、增量合并和命名规范

3.1 从"复制粘贴"到"模板渲染"的思路转变

用 t3code 之前,我自己也写过不少"代码片段":把常用的 router 段落存进代码片段工具,用的时候插入再改。怎么说呢,能省一点时间,但每次插入后还是要手动改类型、改字段名、改 import 路径,改到最后总有一个地方漏掉,然后运行时才报错。

t3code 的做法完全不同。它的核心是一个模板引擎,准确说是 EJS 模板和 JSON 上下文组成的渲染系统。模板里写的是"某个操作模式的长相",上下文里装的是"你这回要生成的具体业务数据"。

import { z } from 'zod'; import { createTRPCRouter, protectedProcedure, publicProcedure } from '~/server/api/trpc'; export const <%= moduleName %>Router = createTRPCRouter({ list: publicProcedure .input( z.object({ limit: z.number().min(1).max(100).default(20), cursor: z.string().optional(), }) ) .query(async ({ ctx, input }) => { return ctx.db.<%= modelName %>.findMany({ take: input.limit + 1, cursor: input.cursor ? { id: input.cursor } : undefined, orderBy: { createdAt: 'desc' }, }); }), // ... });

这里<%= moduleName %>和<%= modelName %>就是渲染时会被替换的变量。命令行里传入的Product会被转换成语境里的moduleName = 'product'、modelName = 'product'等。命名转换这块很容易出问题,工具的默认规则是:model 名 PascalCase,路由名 camelCase,restful path 中划线。比如ProductCategory会变成productCategory路由、/product-category路径。

这个思路的本质是"把代码描述成数据结构",数据结构一变,代码跟着变。手工复制是改了这里忘了那里,模板渲染则是在源头上保证一致性。

3.2 三类文件的处理策略

随着使用的深入,我发现 t3code 实际处理的文件可以分成三类,处理策略也完全不同:

第一类是新建文件,比如新的 router、hooks、页面组件。这类文件直接渲染并写入即可,不存在覆盖旧代码的风险。

第二类是修改文件,最典型的就是schema.prisma和root.ts路由聚合文件。这些文件是项目里本来就有的,生成器不能在后面直接追加一大段——比如schema.prisma有明确的 model 块结构,root.ts有 export 列表和类型推导要求。t3code 采用的是文件级分析 + 定点注入的方式。它会读取现有文件,找到合适的注入点,再写入新内容。以root.ts为例,它会先检查当前是否已经有productRouter的导入和注册,如果没有,就在对应位置追加,而不是粗暴地覆盖整个文件。

第三类是迁移文件。生成数据库模型后,迁移文件不能由用户手动写,也没办法靠模板固定,因为迁移内容完全取决于当前数据库状态。t3code 的处理方式是调用 Prisma CLI 自动执行prisma migrate dev --name add_product,然后把输出结果反馈到终端。如果开发者希望自己控制迁移时机,也可以在配置里关闭autoMigrate,生成器只改 schema,由你手动执行迁移。

区分这三类文件的意义在于:你才能预判工具执行后会产生什么后果,哪些地方要手动检查。我的经验是,修改类文件是出问题的高发区,尤其是当项目结构偏离默认约定时,定点注入可能找不到预期位置。这种场景下文会专门聊排查方法。

3.3 字段类型映射与校验规则生成

生成器最核心的一个映射是"输入字段类型"到"Prisma 类型 + TypeScript 类型 + zod 校验类型"的转换。命令行里用name:string声明的字段,实际上会一路触发三个层面的变化:

输入类型Prisma 类型zod 校验前端输入控件
stringStringz.string().min(1)input / textarea
intIntz.number().int()input number
floatFloatz.number()input number step=0.01
booleanBooleanz.boolean()switch / checkbox
dateDateTimez.coerce.date()date picker
enum需要先定义枚举z.enum()select

这个映射表看起来简单,但它决定了很多潜在地雷。比如z.string().min(1)是为了防止空字符串入参,这在手工写的接口里经常被忽略;而z.coerce.date()解决了前端传来 string 日期、后端却期望 Date 对象的经典 bug。工具把这类"行业默认经验"固化进模板,省掉的不是写代码的时间,而是避坑的时间。

枚举类型稍微特殊。如果你在命令行里写status:enum(pending,approved,rejected),它不会自动知道枚举定义在哪里,而是会在 schema.prisma 中生成一个对应的 enum 块:

enum ProductStatus { pending approved rejected }

然后在 zod 校验里对应生成z.enum(['pending', 'approved', 'rejected'])。这里有一个容易踩的坑:Prisma 的 enum 名默认是首字母大写的字段名加类型后缀,如果你后续在别处手动定义了同名 enum,就会冲突。一般建议在生成后手动检查一下 enum 定义的位置,把它们统一收拢到一个公共文件里管理。

3.4 增量合并:不是覆盖,而是可控的修改

代码生成器面临的最大质疑是:"我手写的代码会不会被覆盖?"如果工具只会生成"全新代码",那它只适合项目初期;一旦进入迭代阶段,开发者一定会对生成代码做二次修改。如果下次重新生成时修改被冲掉,这个工具就不可用了。

t3code 解决这个问题的思路是"生成标记 + 边界识别"。在每个生成的代码块里,它会自动写入一对特殊注释:

// @t3code-generated:begin export const productListQuery = ... // @t3code-generated:end

再次运行时,它通过解析注释边界来识别哪些代码是自己生成的,然后只替换边界内的内容,边界之外手写扩展的代码原样保留。也就是说,你可以在生成的 router 里自由地追加自定义 procedure,t3code 不会动它;但如果你改了模型字段,重新生成时边界内的代码会被更新,保证和模型一致。

这个设计上的取舍我认为是对的。它没有追求"全自动化地理解目标代码",而是用约定把生成区和手写区隔离开。带来的是一点心智负担:你要明白哪些区域归生成器管,哪些归自己管。我的做法是,凡是要长期手写的业务逻辑,默认写在新文件里,不要让生成器负责的代码块膨胀。

4. 实操过程:完整跑一遍"文章 + 分类"业务模块

4.1 业务目标与前置检查

下面带你完整实操一遍,不是演示,而是按照我自己实际做项目时的流程。假设我现在要做博客的"分类 + 文章"两个模块,文章需要关联分类,列表要分页,还要能通过状态筛选已发布/草稿。

开始前先做两个检查。第一,确认项目当前是干净的:git status没有未提交的重大改动,或者至少把当前改动都 commit 了。代码生成器再聪明也是机器,万一出现意外覆盖,git 是你的后悔药。第二,跑一下npx t3code doctor,让它检查当前项目的结构是否为标准的 T3 布局。如果有路径不符合预期,它会提前警告,避免生成跑到错误位置。

4.2 创建分类模块

分类模块字段少、无关联,我先拿它试水。执行:

npx t3code g model Category \ --fields "name:string,slug:string,description:string" \ --include list,create,edit,delete \ --pagination false

这里分页关闭,因为分类通常就几十条,一次性加载更简单。生成后我会快速检查两个文件:一个是prisma/schema.prisma里是否出现model Category,另一个是src/server/api/routers/category.ts是否创建成功,root.ts是否完成了注册。

通常不会有问题。此时测试一下接口能不能通:

npm run dev

打开http://localhost:3000/api/trpc/category.list(或者通过 tRPC playground 测试),确认响应正常。这一步消耗几分钟,但能提前发现 schema 与 router 之间的类型不匹配问题,比写到一半再查要省时间得多。

4.3 创建文章模块并关联分类

接下来是文章模块,它演示了关联关系、分页、状态筛选三个核心特性:

npx t3code g model Article \ --fields "title:string,content:text,status:enum(draft,published),publishedAt:date" \ --relations "category:Category:many-to-one" \ --include list,create,edit,delete \ --pagination true

注意这里我用的是content:text而不是content:string,两者在 Prisma 里的差异是String默认 191 字符、@db.Text支持长文。工具对text有专门的映射,会将其转换为String @db.Text。如果忽略这个区别,生成的文章表在写长文时会报数据超长错误。

这个命令执行后做的事情比上一个多得多:

  • schema 里新增Article模型,并自动加入category和categoryId字段作为外键
  • tRPC router 里list接口支持status过滤和 cursor 分页
  • zod schema 里 status 字段用z.enum(['draft', 'published'])校验
  • 前端列表页增加状态筛选下拉框
  • 自动执行prisma migrate dev --name add_article

生成后动手检查schema.prisma:

model Article { id String @id @default(cuid()) title String content String @db.Text status ArticleStatus @default(draft) publishedAt DateTime? category Category @relation(fields: [categoryId], references: [id], onDelete: Restrict) categoryId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }

这里一个细节是onDelete: Restrict,它是由 CLI 里的关联类型自动推导出来的。many-to-one关系默认使用Restrict,防止删分类时把文章连带误删。如果你希望"删分类时把文章一起删掉",需要在生成后手动改成onDelete: Cascade。这个业务决策不适合交给代码生成器默认决定,所以它的策略是选安全项。

4.4 dry-run 与 diff 的重要性

上面两步我都是直接生成的。但如果你处于团队协作或项目相对成熟的阶段,我强烈建议先跑一次 dry-run 看看影响面。命令很简单:

npx t3code g model Comment \ --fields "content:string,articleId:string" \ --dry-run

它会做一次完整的渲染计算,但只输出"将要新增哪些文件、修改哪些文件、迁移命令是什么",不真正落地。这个模式的价值是可以在执行前预先识别风险:如果某个文件不在预期位置,或者某段模板渲染失败,它会在这一步暴露,而不是生成到一半才报错。

如果想看得更细,可以在 dry-run 里加--diff参数,它会用类似 git diff 的格式把改动内容展示出来。我个人的习惯是,在任何人执行 generate 之前,必须跑一次 dry-run。这不只是为了检查,也是让团队成员在合并代码前对变更内容有个预期,减少 code review 的惊吓。

5. 常见问题与排查技巧实录

用 t3code 半年多,我攒了不少问题排查经验。这些问题有些是工具本身的坑,有些是我自己的项目结构不合规导致的。整理几个典型的,方便你对照排查。

5.1 命令执行成功,但页面 404 或接口 404

这是最常见的现象。生成器说成功了,文件也确实存在,但访问页面就是 404。排查路径就一句话:生成器只保证文件落位,不保证路由注册成功。

大多数情况是root.ts的注册逻辑出了问题。t3code 的定点注入会检查"是否已有articleRouter字样",但如果你的root.ts里 router 写法不是标准格式,比如拆分成了多个文件、用createTRPCContext包裹了一层工厂函数,注入就会失效。解决办法是,生成后打开src/server/api/root.ts看一眼,手动把 import 和router: { article: articleRouter }补上。

前端页面同理。App Router 下 t3code 默认在src/app/articles下生成页面,如果项目本身把页面放在app根目录而不是src/app,它检查到目录不存在,可能会自动创建,这时候访问路径和预期会有偏差。用 dry-run 提前看文件落点,是最好的预防手段。

5.2 schema 文件正确,但 Prisma 迁移不生效

现象是生成后npx prisma studio里看不到新表。这种情况首先要确认自动迁移是否执行成功。t3code 在生成时调用了 Prisma CLI,如果终端输出里出现了 migration 相关日志,说明它确实执行了。但如果你的项目用的是prisma migrate dev以外的流程,比如prisma db push或生产环境用prisma migrate deploy,生成器未必能正确触发。

我的建议是,在配置文件里把autoMigrate关掉,生成代码后手动执行迁移。这样你明确知道数据库在哪一步发生变化,也方便在迁移前备份数据。自动迁移适合开发环境,生产环境一定要手动控制。

5.3 模型命名复数化导致的冲突

t3code 有内置的英文复数规则,用于生成 restful 路径和页面目录。比如Category对应/categories,Article对应/articles。大多数情况没问题,但有些英文单词的复数形式是例外,比如Person会变成people、Status会变成statuses。如果你的业务模型用了这类词,而且你的项目已有自定义路径,就可能在生成时出现"路径重复"或"预期外的路径"。

这类问题没有通用的自动化解法,工具提供参数可以手动指定:

npx t3code g model Person --path "persons"

如果你不想每次手动指定,可以在配置文件的inflection字段里维护一张自定义复数映射表,比如"person": "persons"。这是团队落地时很实用的一个配置。

5.4 重新生成覆盖了手写代码

这是最让人紧张的情况。虽然 t3code 有生成区域标记,但有一个例外:如果你修改了模板本身,而且模板里没有保留@t3code-generated注释,生成器会认为整个文件都是模板渲染产物,从而覆盖重写。规避方法就一条——不要把自定义业务代码写进生成文件里,专门的扩展文件会安全很多。

如果你确实需要在 router 里加自定义 procedure,有三个选择:一是写在生成区域之外,紧跟在文件末尾;二是直接在src/server/api/routers下新建一个额外的 router 文件,最后通过 tRPC 的合并机制挂载进去;三是老老实实改模板,让后续生成都包含你的自定义代码。我的经验是,第一和第二种足够应对绝大多数场景,第三种只适合那种"团队所有项目都固定要这个逻辑"的情况。

5.5 生成代码风格和团队规范不一致

t3code 默认生成的代码风格可能和你团队的习惯不同,比如 import 排序、单双引号、分号、组件写法等。这种问题不用硬适配,直接在生成后接入 ESLint 和 Prettier 自动格式化即可。我的做法是在 package.json 里加一条脚本:

{ "scripts": { "codegen:fmt": "t3code g ... && prettier --write . && eslint --fix ." } }

生成流程结束后自动跑一遍格式化,把所有风格差异抹平。这条经验对团队特别重要,否则 code review 时一半的评论都在讲格式,而不是讲逻辑。

6. 进阶玩法与团队落地的注意事项

6.1 什么场景适合,什么场景别碰

用了大半年,我形成一个判断:凡是你觉得"这段代码我能复制粘贴另一遍"的地方,都是代码生成器的用武之地。T3 Stack 里的 CRUD 就是最标准的场景。反过来,如果某个业务模块强交互、状态复杂、权限分支多,生成器能做的就有限了,硬用反而会逼着你在生成区域里大量手写代码,让模板维护变得困难。我的经验是,权限设计永远不要放进模板里。权限是业务核心逻辑,它的变化频率高、上下文依赖重,由生成器产出只会导致理解成本上升。

如果你在做一个中后台系统,模块数量在五个以上,而且操作模式高度统一,用 t3code 这类工具是很划算的。它一次性投入学习成本,然后每个模块的生成时间能压缩到十分钟以内。

6.2 自定义模板:把团队规范变成默认输出

t3code 真正值得深挖的是自定义模板能力。在.t3code/templates里,每一个文件都对应项目的某类代码,模板里使用的变量来自上下文对象。你可以在里面加自己的默认字段、固定 import 顺序、统一的错误处理组件。

举个例子,我们团队要求所有列表页都要包含"导出 CSV"按钮,而且导出的列要和表格显示的列保持一致。这个逻辑在默认模板里没有,我就改写了templates/pages/list.ejs,在表格工具条区域加入导出按钮和对应的事件处理函数。从那之后,团队里所有人生成的列表页都自动带了导出功能,再也不用每次手写。

这类自定义是有长期复利价值的。团队规范越完善,模板就越厚实,新同学用一条命令就能产出符合团队标准的代码,比对着文档抄范例要高效得多。

6.3 CI 集成与生成物审查

最后说团队落地时比较关键的环节。我建议把 t3code 的生成流程纳入 CI,但不是让 CI 自动提交代码,而是做生成一致性检查:在 CI 里跑一遍t3code generate,然后用git diff --exit-code对比和已提交代码的差异。如果存在差异,说明有人手动改了生成区代码,或者模型定义和代码不同步,直接让流水线变红,强制开发者提交前重新生成。

npx t3code g model Dummy --dry-run git diff --exit-code

这比在 code review 里人工检查要可靠得多。代码生成器最大的价值不是"帮你写代码",而是"让项目结构始终保持一致"。而一致性恰恰是函数式团队协作中最容易被忽略、也最能提升长期迭代效率的东西。

最后再分享一个小习惯

说了这么多,有一条经验是我踩过几次坑之后才养成的:无论生成器看起来多聪明,执行前永远先 commit 一次当前代码,永远先跑一次 dry-run。这听起来很保守,但代码生成这件事,最大的风险从来不是工具能不能生成,而是它生成后和你的手写代码如何和平共处。把边界划清楚——哪些文件归生成器管,哪些文件归自己管——比任何配置项都重要。我自己现在维护的几个 T3 项目,都稳定地跑着这套流程:先提交,再 dry-run,确认 diff,然后真正执行,最后提交生成物。习惯之后,新增一个业务模块真的可以压缩到十分钟以内,而且再也不用为"漏写了哪个文件"这种低级错误烦心。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 7:18:36

GitHub语义搜索技术解析与开发者效率提升指南

1. GitHub Issues语义搜索&#xff1a;开发者问题查找的革命性升级第一次在GitHub Issues里输入自然语言问题并瞬间找到三年前某个冷门仓库的相关讨论时&#xff0c;我对着屏幕愣了三秒——这感觉就像在黑夜里摸索多年突然有人递给你一副夜视镜。传统的issue搜索就像用关键词在…

作者头像 李华
网站建设 2026/10/27 7:17:50

Agent-Reach 实战:用 Python 构建稳定可靠的 AI Agent 执行触达层

1. 从"Agent-Reach"这个名字说起&#xff1a;它到底想解决什么问题第一次看到 Agent-Reach 这个项目名&#xff0c;我的直觉是它跟"让 AI Agent 够得着东西"有关。Reach 这个词在工程语境里通常有两层意思&#xff1a;一是触达&#xff0c;二是延伸。放到 …

作者头像 李华
网站建设 2026/10/27 7:17:27

t3code短码编码方案:轻量级可逆编码与校验实践

1. 从“t3code”这个名字说起&#xff1a;它到底是什么第一次看到“t3code”这个词&#xff0c;很多人会下意识地把它当成某个开源库、某个命令行工具&#xff0c;或者某个内部项目的代号。我最初也是这么想的&#xff0c;直到真正把它放到实际场景里跑了一遍&#xff0c;才发现…

作者头像 李华
网站建设 2026/10/27 7:17:05

t3code契约驱动代码生成实践:从OpenAPI到类型安全与工程自动化

1. 从“t3code”这个名字说起&#xff1a;它到底是什么第一次看到“t3code”这个词&#xff0c;很多人会愣一下——它不像某个具体框架的名字&#xff0c;也不像某个库的缩写&#xff0c;更像是一个内部代号或者项目昵称。我最初接触到它是在一个开发者社群里&#xff0c;有人丢…

作者头像 李华
网站建设 2026/10/27 7:15:15

Django+知识图谱:多模态旅游推荐系统实战解析

简介&#xff1a;基于Django框架与多模态知识图谱技术实现的智能旅游推荐系统完整源码包&#xff0c;提供个性化旅游目的地推荐服务&#xff0c;适合计算机科学与技术、数据科学、人工智能、物联网工程等专业师生用于课程实践、毕业设计或科研项目开发。资源包共201个文件&…

作者头像 李华
网站建设 2026/10/27 7:14:42

管道漏水目标检测数据集:187张双格式小样本训练全流程指南

简介&#xff1a;面向管道漏水检测任务的目标检测数据集&#xff0c;覆盖家庭管道、下水管道等常见场景&#xff0c;适合用于训练和评估YOLO、Faster R-CNN等检测模型&#xff0c;也可作为智慧水务、工业巡检方向的基准数据。压缩包内共563个文件&#xff0c;大小约10.97MB&…

作者头像 李华