资讯动态

从工具链整合到流程自动化:t3code轻量级工程方案搭建实践

发布时间:2026/10/9 9:24:11 来源:尧图企业网站定制
写代码这么多年我一直对“工具链整合”这件事有种执念。项目一多仓库一杂最难受的不是业务逻辑本身而是每次新起一个项目都要把格式化、lint、提交校验、目录规范、接口联调这些基础设施重新搭一遍搭完还得跟团队成员解释“为什么这么配”。前阵子我在内部梳理了一套代号为 t3code 的轻量级工程方案核心就三件事规范先行、模板固化、流程自动化目的很简单——让团队的每个新项目从 clone 下来到能顺畅提测压到 30 分钟以内。t3code 不是某个框架也不是什么新语言它更像是一组经过验证的“工程约定”打包方案。文章里我会把这套东西的思路、关键细节、落地过程以及我们踩过的坑全部拆开讲。如果你也在维护多个前端/Node.js 项目或者正被“项目初始化三小时、代码风格吵一天”的问题折磨这篇内容应该能给你一些可复用的参考。1. 整体设计与思路拆解为什么需要一套“工程约定包”1.1 先搞清楚 t3code 到底解决什么问题不少团队会把精力放在选框架上React 还是 Vue、NestJS 还是 Koa、用 TypeScript 还是 JavaScript。但实际协作下来你会发现真正拖慢效率的往往不是框架选型而是“同一个仓库里每个人写出来的代码长得完全不像同一个项目”。有人用分号有人不用有人组件用函数声明有人用箭头函数有人把接口请求散落在页面里有人统一收口在 services 目录。t3code 这名字里 t3 取的是“三层隧道”的意思——底层是编码规范中间层是项目模板上层是自动化校验与发布流程。整套方案不绑定具体业务框架但把绝大多数团队都需要的“公共地基”固化下来。它解决了三个最痛的问题新项目初始化成本高每次都要手动配置 ESLint、Prettier、Husky、Commitlint、别名路径、环境变量样例一遍遍重复劳动。代码风格不统一人和人之间的习惯差异远比想象中大没有人愿意花时间在 review 里争论“这里该不该加分号”。流程纪律形同虚设很多仓库配了 lint-staged但开发者可以通过--no-verify跳过校验或者根本不在本地跑测试就 pushCI 挂了才追悔莫及。1.2 方案选型的取舍为什么不用现成的 All-in-One CLI市面上其实已经有像 Create React App、Vue CLI、Nx 这类工具甚至还有不少团队成员自己攒的脚手架脚本。我之所以没有直接拿来用而是整理出 t3code 这套体系主要基于三方面考虑第一CAFCreate App Framework这类工具的抽象层次太高。它们确实开箱即用但一旦你需要在生成的项目里做深度定制——比如改 Webpack 配置、接入非标准目录结构、定制多环境部署脚本——就非常难受。要么得eject要么得写一堆 patch 脚本维护生成物。t3code 的做法是“模板 变量注入”模板本身不隐藏任何构建细节生成出来的代码就是你能看懂、能改的普通工程。第二团队协作需要的是约定不只是命令。脚手架只能帮你生成代码但解决不了“为什么目录要这么分”“为什么接口层必须这么写”的问题。t3code 在模板之外配套了一份精简版约定文档把关键约束写成人话放在 README 开头。新人进来不用猜直接照着模板写就能融入节奏。第三做技术选型要防“债务外包”。直接依赖重量级 CLI意味着以后框架升级、配置变更你都得跟着它的节奏走。t3code 的核心依赖只有五个左右TypeScript、ESLint、Prettier、Husky、lint-staged都是领域事实标准路径依赖很弱哪天不想用了拆掉也很容易。1.3 方案的整体架构三个层次各司其职拿我们一个典型的中后台前端项目来举例t3code 的组成大致是这样的层次内容核心目标规范层ESLint 规则集、Prettier 配置、EditorConfig、命名约定让机器约束风格减少人为争论模板层项目目录骨架、基础配置文件、公共请求/工具模块、CI 模板初始化即具备完整工程能力流程层Husky lint-staged Commitlint、GitHub Actions / GitLab CI 脚本把质量检查嵌入提交和合并主线这套结构有一个隐含的设计原则规范层要足够严模板层要足够薄流程层要足够硬。规范严代码才统一模板薄生成物才不臃肿、不绑架你流程硬规则才会被执行而不是沦为摆设。下面每一个环节我都会展开讲清楚。2. 核心细节解析与实操要点规范与模板里的门道2.1 ESLint 规则集把“风格之争”消灭在提交之前ESLint 规则集是整个 t3code 里最琐碎、但收益最立竿见影的部分。我们没有自己发明规则而是站在巨人的肩膀上做减法。基础配置采用eslint-config-airbnb-base作为蓝本再去掉其中与 Prettier 冲突的格式类规则最后叠加typescript-eslint/recommended和eslint-plugin-import的路径校验。这里有一个关键操作必须先装eslint-config-prettier并把它放在 extends 数组的最后一位。它不会启用任何新规则唯一的职责是关掉所有与 Prettier 重复或冲突的 ESLint 规则。很多新手踩坑就是漏了这一步结果 ESLint 和 Prettier 在“缩进应该用几个空格”上互相打架保存时自动格式化完lint 依然报错。实际配置中的几个核心规则我当时是这样定的// .eslintrc.js 关键摘录 module.exports { root: true, extends: [ airbnb-base, plugin:typescript-eslint/recommended, prettier // 必须放最后关闭格式类冲突规则 ], rules: { // 允许显式标注返回值类型大型项目里收益很高 typescript-eslint/explicit-function-return-type: off, // 强制 import 顺序内置模块、第三方、内部模块、类型导入 import/order: [error, { newlines-between: always }], // 禁止 any如果某些场景必须用要求显式写注释说明原因 typescript-eslint/no-explicit-any: [error, { fixToUnknown: true }], // 组件/函数参数统一使用接口描述避免隐式 any typescript-eslint/no-unused-vars: [error, { argsIgnorePattern: ^_ }] } };no-explicit-any这条规则我们内部吵过一轮。有人觉得业务代码里经常要接第三方不规范的接口返回禁用 any 会徒增工作量。我的观点是如果你遇到必须放开约束的场景应该显式写一个类型别名并在注释里说明数据来源而不是随手一个 any 让类型检查形同虚设。这份坚持在后续重构时帮了大忙——我们有一个接口改了字段结构得益于类型收敛编译阶段就暴露了所有引用点而不是上线后靠用户反馈才发现。2.2 目录结构设计约定优于配置的“公共骨架”t3code 的模板层里有一套固定的目录骨架React 和 Node.js 项目都能套用。顶层结构如下src/ ├── api/ # 接口请求层 ├── assets/ # 静态资源 ├── components/ # 通用组件 ├── config/ # 环境配置 ├── hooks/ # 自定义 Hook ├── pages/ # 页面级组件路由对应 ├── services/ # 业务逻辑层 ├── styles/ # 全局样式 ├── types/ # TypeScript 类型声明 ├── utils/ # 工具函数 └── index.tsx # 应用入口这个结构最大的特点就是“乱也乱得有限”。它遵循一条最关键的分层约定页面组件里不允许直接 fetch 数据必须经过 services 层。举个例子一个用户列表页你需要做的不是在那里写axios.get(/api/users)而是去services/user.ts里定义一个fetchUserList函数再由它调用api/request.ts里封装好的请求实例。这样一来接口路径、请求参数、错误处理都集中在一处后续接口变更只需要改一个文件。目录约定里还有几个容易忽略的细节pages/下的文件名默认与路由一一对应省去路由表维护成本但需要约定“动态路由参数拼文件后缀”比如user/[id].tsx团队熟读 Next.js 风格的话零学习成本。components/下按业务域建子目录每个组件自带同名文件夹内部放index.tsx、style.ts、types.ts方便以后做代码分割或单元测试。utils/只放纯函数禁止引入 React 和业务 API保证可测试性。这套骨架不是一次性拍脑袋定的而是从我们维护的十来个老项目里抽象出来的“最大公约数”。它的价值在于新人接手任何一个基于 t3code 的项目都能在五分钟内找到要找的文件。2.3 配置模板的三个“必填项”环境变量、路径别名与构建输出项目生成之后有三个配置文件是我要求必须存在且不允许删改的。第一个是.env.example。很多项目把环境变量直接写在代码里或者只在本地口头传一份.env。t3code 要求所有环境变量必须先在.env.example里登记写清楚注释、类型、示例值。新同事 clone 仓库后只需执行cp .env.example .env即可开始开发也天然防止了把密钥误提交进仓库的问题。我们在.gitignore里显式加上了.env但保留了.env.example。第二个是路径别名。我们在模板的tsconfig.json和打包配置里都配好了/指向src/这样模块引用写的是/services/user而不是一长串../../../services/user。这里的坑在于TypeScript 配置变了之后打包器Vite 或 Webpack的 resolve.alias 也要同步改否则编辑器不报错、构建却找不到模块。t3code 模板直接用同一个tsconfig的 paths 作为唯一事实来源再在构建配置里读取避免两个地方各写一份导致漂移。第三个是构建产物目录。统一设为dist/并在 CI 流程里固定下来。这个看起来不起眼但部署脚本、Dockerfile、静态资源服务配置全都依赖这个约定。我们有个历史项目用过build/后来另一个项目用dist/运维同学每次都要问“这次部署目录是哪个”非常低效。t3code 里统一下来整个公司都受益。3. 实操过程与核心环节实现从零生成一个 t3code 项目3.1 准备工作本地环境与工具链安装在真正跑模板之前需要先把工具链准备好。这块我直接给一份经过验证的清单照着装不会有版本冲突问题# Node.js 版本管理器装 18 或 20 LTS # 建议装 nvm方便切换多个项目 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # 安装 Node.js 20 LTS nvm install 20 nvm alias default 20 # 全局安装 pnpmt3code 模板默认使用 pnpm 作为包管理器 npm install -g pnpm8 # 验证版本 node -v # v20.x.x pnpm -v # 8.x.x这里为什么选 pnpm 而不是 npm 或 yarn主要是磁盘占用和安装速度。我们团队十几个项目共用一套依赖pnpm 的内容寻址存储让同样的依赖包只保留一份实测磁盘占用减少了大约 60%冷安装速度也有明显提升。更关键的是 pnpm 默认的“幽灵依赖”防护能逼着开发者显式声明每个依赖避免那种“代码里明明用了 lodash 但 package.json 里没有”的经典事故。3.2 初始化项目clone 模板并安装依赖t3code 的模板仓库是个普通 Git 仓库初始化方式非常朴素# 拉取模板仓库换成本团队自己的模板仓库地址即可 git clone gitgithub.com:your-org/t3code-template.git my-project cd my-project # 快速清理模板自带的 Git 历史避免污染新项目 rm -rf .git git init # 安装依赖 pnpm install对比很多脚手架用create-xxx-app交互式询问、下载模板、生成文件的流程直接 clone 模板的优点第一是透明——你能在初始化前就完整看到模板的每个文件第二是可控——团队内部可以像维护普通仓库一样迭代模板本身。用rm -rf .git git init这步操作相当于把模板仓库的提交历史剪掉新项目从第一个 commit 开始就是自己的历史操作简单且不会有奇怪的历史负担。有同事问过为什么不用degit这类工具拉取模板那里其实也能起到同样的作用。degit 会更优雅一些它会忽略模板仓库的 Git 历史只下载工作目录文件你也就不用手动执行rm -rf .git了。不过手工方式同样完全可行而且少引入一个工具依赖对新人更友好。完成之后一次性把所有依赖锁文件也提交进仓库。这里有个原则pnpm-lock.yaml必须提交node_modules必须在.gitignore里。lockfile 保证全团队装的依赖版本完全一致避免“我本地能跑你那边报错”的经典推诿。3.3 修改项目标识与个性化配置全局搜索模板里预留的占位符t3code-app和t3code/把它们替换成你项目的实际名称和 npm scope。这里要特别小心 package.json 里的name字段它会被 pnpm workspace、构建工具、以及一些运行时的代码分割逻辑引用如果大小写或格式不规范比如包含大写字母发布 npm 包时会直接报错。npm 包名规范是小写字母、数字、连字符这一点没有商量余地。同样需要更新的是public/目录下的站点标题、favicon、manifest.json 里的元信息。这些不更新的话页面 title 会一直是模板自带的 “t3code App”看起来非常不专业。我在一份分享里专门列过这个清单团队内部也把它叫“换皮五件套”package.json 的 name/version/description/author.env.example 里的应用名和应用 IDpublic/index.html 里的title和 meta descriptionsrc/config/app.ts 里的应用名称常量README.md 的项目简介与本地启动说明这些步骤虽然琐碎但一次性做对能让后续所有环境的识别都清晰。我见过有项目上线半年了浏览器标签页还挂着隔壁项目的名字多少有点尴尬。3.4 启动与验证检查 ESLint、构建、测试三条链路依赖装好、配置改完接下来验证整套链路是否通畅。我习惯按下面这个顺序跑一遍# 1. 类型检查 pnpm type-check # 2. 全量 lint不要只看有没有错还要看警告项 pnpm lint # 3. 构建生产包 pnpm build # 4. 跑一次测试模板自带两个冒烟组件测试 pnpm test如果四步全过这个项目的工程基础就算是稳了。这里存在一个容易忽略的细节很多模板的lint脚本只配置了eslint src没有把配置文件自身纳入检查。这意味着.eslintrc.js、commitlint.config.js这些文件里的错误可能永远不会被发现。t3code 的 lint 命令有两种模式lint:src检查业务代码lint:config检查配置文件CI 里两个都跑双轨并行。构建通过后我第一次会认真看一遍dist/目录下的产物结构。重点确认三个点入口 HTML 里引用的 JS/CSS 路径带上了哈希文件名、静态资源被正确拷贝、.env里的环境变量被正确注入比如VITE_APP_API_BASE。如果这里不对后面部署到测试环境才发现就晚了排查成本高得多。3.5 初始化 Git 仓库并建立提交规范基线在完成验证之后我们再初始化 Git 仓库这一步的顺序很有讲究。如果先git init再安装依赖和构建中途产生的dist/、临时文件都可能被误加入版本控制先全部配置好、清理干净再 init首次提交的代码就是干净、可复现的工程基线。这也是 t3code 流程里“初始化”步骤专门排在最后的考量之一。git init git add -A git commit -m feat: init project from t3code templatet3code 配备了 Husky 钩子在你执行 commit 时会先触发pre-commit里的 lint-staged只对暂存区的文件做 ESLint 和 Prettier 检查接着commit-msg钩子会校验提交信息是否符合 Conventional Commits 规范feat/ fix/ docs/ chore/等前缀。这样做的好处是lint 只处理你“即将提交”的代码而不是整个仓库提交信息规范则让后续的 changelog 自动生成、代码回溯都变得有迹可循。这套机制真正厉害的地方在于它不是靠“请自觉遵守”而是把纪律写进了 Git 钩子流程。想要绕过当然也有办法比如--no-verify但从我们团队的经验看当校验反馈足够迅速、报错信息足够明确时大家是愿意遵守的毕竟多敲几个规范前缀比在流水线上被红灯拦下来要省心得多。4. 常见问题与排查技巧实录t3code 落地中的典型坑4.1 问题一本地 lint 全绿CI 上却报错这是团队里出现频率最高的问题根源几乎永远是本地没装依赖或版本不一致。比如本地 node_modules 是两周前装的ESLint 插件升过版本规则行为变了但 lockfile 没有更新。排查思路很简单按顺序来# 第一步核对 lockfile 是否与当前分支同步 git status | grep pnpm-lock.yaml # 第二步删掉 node_modules 重装这一步能解决九成玄学问题 rm -rf node_modules pnpm install # 第三步确认本地 Node 版本与 CI 严格一致 node -v echo 查看 CI 配置文件中的 node-version 字段t3code 模板的 CI 配置里特意把 pnpm 版本和 Node 版本都固定住了。如果 CI 用的是pnpm/action-setupv2且指定了 8.x本地就不能偷偷用 9.x否则装出来的依赖树不同lint 行为就可能漂移。4.2 问题二提交了不符合规范的 commit message有些人用的是 IDE 自带的 Git 面板提交时弹窗极其简洁没有显示 Husky 钩子的完整报错很多人甚至没意识到有钩子存在。然后他们来找我说怎么 commit 没反应这里要把期望摆正Husky 钩子报错会中断提交此时这个 commit 是“失败”的没有真正写入历史。但钩子也会输出解决提示最有用的信息通常包含“请使用git commit --amend重新提交”或“提交信息应以 feat/ fix 开头”之类的指引。我的建议是让终端窗口稍微留大一点报错显示不全时别盲操作先看提示再做下一步。如果提交已经被推送到远程才发现格式不对不要慌分情况处理还没推远程直接git commit --amend改完再推即可。已推远程且是个人分支用git rebase -i修改对应 commit 的 message再强推。注意是个人分支才建议强推团队共享分支请不要这么干容易把别人的提交搞乱。已合入主干别折腾历史了这个提交信息就当作历史遗留问题。重点是从当前这个 commit 开始保持规范没必要为了“修正”引发更大的协作风险。4.3 问题三lint-staged 只检查到了部分文件lint-staged 的工作机制是“读取暂存区的文件列表逐个匹配规则”它本身不关心你在 git 里配置了什么textauto换行符之类的东西。常见问题是你明明git add了十个文件却只有三个走了 lint原因多半是规则里的 glob 写得太窄比如只匹配了src/**/*.{ts,tsx}而修改的文件里恰好还有其他目录下的.js或.vue文件。t3code 的 lint-staged 配置会覆盖主流的源文件类型// package.json 中的 lint-staged 配置 { lint-staged: { *.{ts,tsx,js,jsx}: [eslint --fix, prettier --write], *.{json,md,css,scss}: [prettier --write] } }这里有两个经验值得注意。第一--fix和--write都写上ESLint 负责修代码质量问题Prettier 负责统一格式两者各司其职。第二如果遇到“暂存区只有一部分文件触发”的困惑可以手动跑一次npx lint-staged --debug它会输出匹配逻辑的完整清单问题一眼就能看出来。4.4 问题四环境变量跨端不一致本地正常、线上白屏这类问题通常不是 t3code 本身的缺陷而是环境变量作用域约定不清。举个我们真实遇到的例子模板里VITE_APP_API_BASE这个变量在开发环境指向http://localhost:3000/api生产环境指向线上网关但有一台构建机的环境变量还残留着开发环境的值构建时被 Vite 原样打进 bundle上线后所有人请求都打到了 localhost。排查这种问题唯一有效的办法就是让构建产物的“来源”可追溯。t3code 的 CI 配置里有一个专门步骤在构建成功后把.env里参与构建的关键变量打印到构建日志中变量值做脱敏处理后留档。这样一旦线上行为可疑先对照构建日志确认用的是什么环境变量而不是靠猜。另外凡是用import.meta.env或process.env读取的变量必须在.env.example里有注释说明“该变量是否会被打包进前端产物”——这点非常重要很多人认不全 Vite 的 env 加载规则导致密钥被误打包进公开 bundle。t3code 的做法是带VITE_前缀的变量才可能被打包其余变量只在构建和 Node 服务端可用两条路径严格隔离。4.5 问题五模板本身升级了存量项目怎么同步这是所有模板方案都会遇到的经典难题。头一天你改了模板里的一个公共工具函数第二天发现已经上线的那几个老项目还在用旧版本bug 可能已经埋下了。模板维护者面临的永恒矛盾是新项目要用新模板老项目不能随便动。t3code 的做法是“逐模块同步、单项升级”而不是“整体替换”。我们会把模板仓库里的公共模块拆得足够细比如request.ts、logger.ts、storage.ts都是独立文件老项目升级时按需拷贝对应文件即可。配合 semver 的版本标签模板仓库每个 commit 都打 tag需要升级的团队可以精确比对v1.2.0到v1.3.0之间的 diff只挑与自己相关的部分合入。这个思路后来演变成了一个很轻量的内部 CLI 工具支持按文件路径同步模板内容但由于维护成本考量我们还是更推荐“以 copy 为主、以 merge 为辅”的朴素策略。模板不是强约束工具它是知识沉淀的载体别把自己绑死在自动同步上。5. t3code 的扩展空间向边缘场景与自动化推进5.1 从 Web 走向全栈Node.js 服务与 Monorepo 适配t3code 最初的模板是针对前端中后台项目的但很快我们发现团队里同时有成批量的 Node.js 服务BFF 层、定时任务、内部工具需要治理。于是模板仓库里扩展了template-node-service分支保留了核心的 lint/Prettier/commit 规范但在目录结构上做了调整src/ ├── modules/ # 业务模块每个模块自带 controller/service/dao ├── common/ # 通用中间件、异常处理、日志 ├── config/ # 环境配置读取与校验 ├── database/ # 数据库连接与迁移脚本 ├── app.ts # 应用入口 └── server.ts # HTTP 服务启动模块化的好处在于写一个新接口时你可以只关注自己的modules/目录公共逻辑全部收敛到common/基本不会出现一个 200 行路由文件里塞满所有业务逻辑的“大泥球”。另外Node 服务模板里加入了进程守护与优雅退出样板这在 Node.js 服务上线时几乎是标配没有的话 pod 滚动更新时内存会无故堆积。配合 pnpm workspacet3code 进一步支持了 monorepo 形态。我们有一个后台项目同时管理了管理端、用户端和两个共享包根目录的pnpm-workspace.yaml划分好 packages 之后各子包仍各自包含 t3code 的规范配置只是执行从根目录统一调度。这里要特别注意如果子包有独立的.eslintrc.js需要显式声明root: true否则 ESLint 会向上层目录查找配置出现极其隐蔽的“配置串扰”问题。5.2 与我常用的其他工具链整合AI 时代的新协作范式要说 t3code 最近最让我兴奋的变化来自于 AI 编码工具的整合。大模型写代码已经成为每个研发团队不得不面对的新常态。但很多人只看到了效率提升的一侧没看到另一侧的隐患AI 生成的代码通常风格稳定但规则意识极差。它可能生成一个完全可行但不符合项目 lint 规则的组件甚至把any用得到处都是。我的做法是让 t3code 成为 AI 编码的“规则护栏”。具体操作是在项目的AGENTS.md文件里把项目的目录约定、命名规则、接口请求规范全部写清楚。这样带上下文的大模型自动读取这个文件后生成的代码已经能自动对齐团队规范。再配上 lint-staged 的强校验基本能做到“AI 随便写规则兜底收。”这个方案运行几个月下来团队里 AI 生成代码的 lint 通过率从接手初期的不到一半提升到了九成以上。关键不是模型变聪明了而是你给模型的上下文足够清晰。如果你正在尝试 AI 辅助编码建议立刻把团队的规范文档写入AGENTS.md这比你在对话里反复叮嘱“请遵守项目规范”要有效得多。5.3 从模板到文化把工程规范变成团队共识很多人以为推行一套工程规范最大的阻力来自技术选型但我这几年的体会是最大的阻力永远在“人”。有人觉得 lint 规则是束缚有人觉得提交信息规范是形式主义有人觉得强制类型标注浪费时间。这些观念如果不解决任何工具方案都会被绕过。t3code 在推行时有一个很“软”的做法我们不是发一个通知让大家“必须遵守”而是先在两个项目里试点跑了两周把执行前后的数据摆出来——review 耗时下降了约 40%CI 红率下降了约 60%新人上手时间缩短了一半以上。数据摆在面前大部分人的抵触情绪自然就消退了。剩下的少数执念也通过“规则可以讨论但得有替代方案”的方式逐个解决最终形成共识。我始终觉得好的工程规范应该像一个经验丰富的老同事平时不打扰你但关键节点总是提醒一句“这里可能有坑”。t3code 就是我用代码写的那个老同事。6. 写在后面给想复刻这套方案的人几点建议如果你也想在自己的团队推行类似的工程约定我给三个最实在的建议。第一永远从“当前最痛的三个问题”出发不要追求一步到位。我们最开始只是解决 commit 信息乱后来才逐步扩展出整套 t3code。你要是第一版就把 ESLint、Prettier、TypeScript、lint-staged、CI、monorepo 全铺上团队大概率会炸。分阶段、小步快跑让每个人看到变化带来的正向收益比任何行政命令都管用。第二把模板和文档当成代码一样维护。谁用模板发现了一个问题不是自己默默改一下就完事而是要回到模板仓库里更新“修复”并打 tag。模板不是一次性的它是持续演化的工程资产。配套的那份“约定文档”也要认真写不要只有工具没有思想否则换个同事依然会问“为什么这里要这么写”。第三尊重团队的“例外需求”。t3code 的定位是“公共约定”不是“铁律”。某个模块确实需要特殊处理比如外部 SDK 的 d.ts 不规范导致类型报错别让规则成为阻碍该加 ignore 注释就加该做局部豁免就做。关键在于把豁免理由写清楚不能悄悄跳过。规则是为效率服务的不是为了制造审批流程。说到底t3code 这套东西不是魔法它只是“把做过的事情沉淀下来把重复的工作自动化把该守的底线交给机器”。如果你手头也有一堆项目在各自为政不妨试着从一次规范化的提交信息、一套标准化的 lint 配置开始一步步搭建属于你自己的 t3code。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑