十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Dart/Flutter 项目交付新助手:Skills CLI 将默契变为门禁

Dart/Flutter 项目交付新助手:Skills CLI 将默契变为门禁 最近两周我把自己手头一个 Flutter 项目里重复了无数遍的“交付前琐事”抽出来做成了一个小工具叫 Dart Skills CLI 1.0。做它的原因很简单AI 写代码确实越来越快但交付一个能跑的 Dart 项目从来不是把代码堆完就结束。Dart 这门语言在客户端、服务端、脚本场景都有覆盖加上 Flutter 生态的膨胀项目复杂度早就不允许靠“人肉记规范”来保证质量了。所以我把目光放在了“AI 时代的交付支持”上能不能用一套命令行工具把项目结构、依赖规则、编码规范、测试策略这些隐性知识结构化再喂给 AI 编码助手让 AI 生成的代码从一开始就贴合项目实际而不是生成一堆看着对、跑起来全是坑的“通用代码”。同时它还能在交付前自动完成分析与测试检查把“生成代码”和“可交付代码”之间的最后一公里补上。如果你在维护一个中等规模的 Dart/Flutter 项目或者正在尝试用 AI 辅助日常开发这篇博文里的设计思路、实操步骤和踩坑记录应该能给你一些参考。整个工具完全用 Dart 编写命令行的交互方式也很轻适合嵌入现有 CI/CD 流程也能单独在本地跑。1. 为什么 AI 时代需要一套“交付型”CLI1.1 Dart 项目的真实交付困境先说我现在每天面对的东西。一个典型的 Dart 项目尤其是 Flutter 应用pubspec.yaml 里往往躺着几十个依赖lib 目录下面散落着页面、模型、服务、状态管理、路由、主题、工具类。听起来不复杂但一旦团队超过三个人代码风格就开始分裂有人习惯用 sealed class 做失败分支有人还在抛字符串异常有人喜欢 Riverpod有人顺手引入 Provider还有人把网络层封装了三层结果换个 baseUrl 都要追着改半天。这些问题的共性是“约定”没有落地。传统做法靠文档、靠 Code Review、靠 reviewer 的嘴硬心软。但到了 AI 协作的时代问题会放大——AI 不读你脑子里的约定它只看训练数据里的通用模式。所以你会发现让 AI 写一个简单的列表页它能写出来但很可能把你项目里的状态管理方案换成另一个全家桶或者错误处理风格跟你现有代码完全不一致。更麻烦的是交付。每次发版前要做的事特别固定跑 dart analyze跑 dart format 检查跑一遍测试看看覆盖率有没有跌确认 pubspec.lock 没有被某人悄悄改乱扫一眼依赖有没有高危漏洞更新。这些事不是不能手工做而是太容易漏。人一旦忙起来就会跳过一两个检查然后问题就会在 Release 之后、真机反馈阶段爆炸。1.2 Skills CLI 的定位与设计思路Skills CLI 的核心思路是把“项目能力”显式化、可操作化。这里的 Skill 不是指某个单一技巧而是把一份关于项目的知识包——架构边界、依赖管理策略、错误处理约定、测试要求、代码风格——统一封装成机器可读的文件再通过命令行的方式在合适的时机注入到工作流里。它在 AI 时代扮演的角色更像一个“翻译层”开发者和 AI 对项目的理解中间隔着一大堆隐性上下文。CLI 负责把这些隐性上下文挖掘出来并落盘这样一来无论你是手动写 prompt还是接入某个 Agent 框架都能拿到一份结构化的项目说明而不是靠 AI 自己猜。选择用 CLI 而不是 IDE 插件我是有私心的。CLI 适合脚本化、适合进 CI、适合团队共享配置而且不绑定具体编辑器。Dart 生态里已经有 dart_analyzer、build_runner 这些命令行老面孔开发者对终端操作不陌生。再加上 Dart 本身写 CLI 很顺手编译成可执行文件之后分发也简单所以我第一版就定了“纯命令行工具”的形态。这个设计的另一个好处是它不强迫团队改变现有工作流。你可以只用其中的scan命令做体检也可以只生成 AI 上下文文件或者把verify挂到 git pre-push 钩子里。工具是渐进式的不是一上来就要求你全盘接受一套新规范。2. 核心能力拆解从项目扫描到技能包生成2.1 项目健康扫描比 analyze 更完整的体检第一步也是我最早实现的命令是dart_skills scan。它做的事情不是替代 dart analyze而是把散落各处的检查点统一收口。scan 会解析 pubspec.yaml遍历 lib 和 test 目录然后输出一张体检报告涵盖 SDK 版本约束、依赖引用状态、TODO/FIXME 数量、未处理的异步错误等维度。依赖引用状态这条是很多项目的盲区。比如某个 package 被加进了 pubspec.yaml但代码里已经没人用了长年累月躺在那里带来的是无意义的版本约束和编译时间。scan 会扫描 lib 下的 import 语句反向比对 pubspec 里的 dependency 列表把没被引用的依赖标成 warning。异步错误检查这块Dart 的 Future 如果没人 await 也没人 catch出了错就是静默失败。CLI 用 analyzer 的 AST 能力找出“裸调用”的 Future 方法提示加上unawaited()或者在调用链上显式处理。这个检查对服务端 Dart 特别重要因为一个被吞掉的异常可能意味着一次任务悄悄失败而监控里什么都看不到。体检报告最终会生成一份report.md按 error/warning/info 分级列出问题并给出建议命令。比如“这个类引用了测试专用路径”会提示你加visibleForTesting注解“这个依赖版本过旧”会提示dart pub upgrade某个具体包。我要的是开发者拿到报告以后能直接行动而不是再花几个小时解读一堆原始告警。2.2 技能包机制让 AI 真正“懂”你的项目技能包是整套工具里我觉得最有趣的部分。dart_skills init会在项目根目录创建一个.darts/skills/文件夹里面默认预置几个文件project_skill.md、ai_context.md、deliver_rules.yaml以及一组提示词模板。project_skill.md描述的是项目的宏观规则目录结构约定、状态管理方案、依赖注入方式、网络层封装策略、错误处理的分支约定。比如一个典型的 Riverpod 项目会在里面写明“所有状态类需要继承 AutoDisposeNotifier页面通过 ConsumerWidget 读取状态禁止在 build 方法里直接调用异步方法”。这些规则如果只放在 README 里AI 大概率不会主动读但放进技能包连同上下文文件一起注入它就没有理由“看不到”了。deliver_rules.yaml是给 CLI 自己用的机器规则。里面定义了交付检查的阈值比如测试覆盖率不得低于 80%analyze 的 error 数量必须为 0format 检查必须通过TODO 数量不能超过某个值。CLI 执行 verify 的时候会逐条核对不满足就返回非零退出码。模板目录下放的是针对不同任务的 prompt 前缀。做一个新 feature 时CLI 会读取项目技能包自动拼出一段包含项目规则的提示词再让你追加具体需求。这样既保留了人的自由度又保证了 AI 生成的内容从出生起就站在项目共识里。实测下来这种“规则前置、自由后置”的做法比直接丢给 AI 一个空 prompt 要稳得多。2.3 上下文注入AI 提示词工程的落地载体第二部分的 key 文件是ai_context.md。这个文件由 CLI 自动生成每次扫描后都会刷新。它包含仓库结构树、关键模块说明、依赖清单、测试目录组织方式以及最近修改的文件列表。这些信息是从项目里直接挖出来的不是开发者手写的介绍所以不会出现文档和代码脱节的问题。我在设计注入时机时想了很久。如果每次 AI 对话都塞一整套项目上下文token 消耗太大而且很多信息是噪音。所以 CLI 支持按“焦点”生成不同的上下文片段做 UI 变更时只要保留 widget 目录和主题相关的部分改动业务逻辑时就带上数据模型和仓库层的结构。你可以把这理解为“上下文切片”按任务类型定向投喂。这里有个我强烈建议的点把ai_context.md生成过程接入到 git pre-commit 或 CI 里保证它不会过期。AI 编码助手再聪明拿到的项目结构如果已经变了生成出来的东西也会牛头不对马嘴。至少每次提交前刷新一次成本极低收益却很明显。3. 实操用 Skills CLI 跑通一次完整交付3.1 安装与环境准备先说环境。我日常用的开发机是 macOS另外在 Linux CI 容器里也跑过Windows 下的 CMD 和 PowerShell 理论上也能跑但没做过完整回归。工具是纯 Dart 写的核心依赖只有args、yaml、glob和一个轻量 http client所以编译产物不会有太多系统级依赖。安装方式用的是全局激活dart pub global activate dart_skills_cli如果你的 Dart SDK 是通过 homebrew 或者直接解压装的激活后会提示把~/.pub-cache/bin加到 PATH 里。这一步别跳不然终端找不到dart_skills命令。执行成功后先确认版本dart_skills --version dart_skills --help工具本身不要求项目必须用什么状态管理库也不需要你预先装 build_runner。所以把它理解成一个“只读 生成辅助文件”的检查器风险很小。3.2 初始化技能包与项目体检进入一个已有的 Dart 项目根目录初始化技能包cd my_dart_app dart_skills initinit 会创建.darts/skills/目录并且自动读取 pubspec.yaml根据 SDK 版本和依赖特征生成一份最基础的项目规则。比如发现你依赖了flutter_riverpod它就会在 project_skill.md 里预填一条“状态管理方案Riverpod”如果检测到build_runner和freezed它会提示在生成代码时优先使用part文件的模式。接下来跑一次完整体检dart_skills scan这个命令会做四件事解析依赖树、遍历 lib 源码、遍历 test 目录、调用dart analyze拿到实时告警。最后把结果汇总到report.md同时直接在终端打印一个精简版的摘要。我建议第一次用的时候专门花半小时把报告里的 warning 过一遍。你会发现很多平时注意不到的细节比如某个本地文件被 import 了但没有被任何公开 API 覆盖到或者前端代码里意外引用了 dart:io 导致 Web 端编译必崩。这些如果等到集成测试再暴露排查成本会高得多。3.3 结合 AI 编码助手的典型工作流这是我最想展示的部分。假设我接到一个需求在现有列表页上增加一个“筛选”按钮弹出一个底部抽屉里面有几个筛选项确认后重新拉取数据。传统做法是手动切类、复制现有的网络请求写法、查状态管理库的文档。用 Skills CLI 配合 AI 编码助手流程会变成这样。第一生成任务上下文dart_skills context --task feature --name filter-drawer运行后终端会把一段“焦点上下文”打印出来内容只包含项目里跟 UI 页面、路由注册、状态管理相关的文件和约定不包含无关的底层工具类。第二打出提示词前缀dart_skills prompt new-feature --name filter-drawer这条命令会读取技能包里的所有规则拼出一段结构化的 prompt重点给出“不要使用的库”“必须遵循的错误处理模式”“测试文件需要放在哪个目录”等硬约束。我把这段内容复制进 AI 编码助手再补上需求描述AI 生成出来的代码就会带上项目自己的风格。第三步很关键生成完代码后不要直接 commit。先把 AI 改动的文件拉进项目跑一次dart_skills scan和dart_skills verify让 CLI 判断有没有违反交付规则。这个过程我是当“AI 生成代码的编译前置检查”来用的。AI 可以快但责任要在工具链条上兜住。3.4 交付前校验与发布当代码写完准备发版或提交 MR 时跑dart_skills verify --strict这条命令会依次执行dart format --set-exit-if-changed . dart analyze dart test --coveragecoverage dart test --reporterexpanded区别在于verify 会把结果和deliver_rules.yaml里配置的阈值做比对。覆盖率低于阈值它会直接提示失败有未处理的 analysis error它会终止流程如果 pubspec.lock 里有依赖被修改但没同步更新pubspec.yaml它也会在报告里标红。这套流程我本地跑一次大约三到六分钟取决于项目大小和测试数量。放进 CI 之后每次 MR 都会自动触发等于把交付标准变成了硬门禁不再靠某个人的记忆。有些项目会纠结会不会太严格。我的建议是严格一点好。Dart 的格式检查是明确且机械的analyze 的 error 级告警基本就是 bug 前兆覆盖率阈值可以按团队情况调节。但一旦定了别频繁改否则大家会觉得“规则是弹性的”又会回到人肉 review 的老路。4. 常见问题与排查技巧实录4.1 技能包目录被 Git 忽略导致 AI 上下文缺失这是我最先踩的一个坑。init 生成的.darts/目录如果被根目录的 .gitignore 覆盖了比如某些团队模板会默认忽略所有.darts开头的内容那么技能包文件就只能留在本地换一个同事拉代码之后就完全找不到了。排查思路很简单在项目根目录执行git status --ignored看看.darts/是否出现在 ignored 列表。如果是在 .gitignore 里加一行例外.darts/ !.darts/ !.darts/skills/我的建议是技能包这种文件必须提交到 Git 仓库因为它是团队约定的一部分跟代码本身同等重要。如果嫌.darts名字看着别扭工具也支持通过配置文件改成team/或docs/目录。4.2 analyze 误报与版本兼容的纠缠另一个常见问题是 Dart SDK 版本跨了一大步之后analyze 的告警类型会变。比如从 Dart 2.19 升到 3.x一些本来正常的代码会触发unnecessary_cast或者deprecated_member_use。这不一定是代码写错了而是语法解析规则变了。工具的做法是把 analyze 的结果按“当前 SDK 版本”重新标记一次。如果某个告警是因为 SDK 升级导致的它会提示你先看升级公告而不是直接建议你改代码。真正要改的地方报告中会单独归类成“与 SDK 版本无关的逻辑问题”。遇到这种情况我的经验是先锁定 SDK 版本再升级依赖。顺序反了的话新 SDK 和新依赖会一起带来一堆变化出了问题根本分不清是哪边造成的。用dart pub global activate的时候也要注意CLI 本身的依赖版本也可能跟项目的 SDK 冲突激活出错的话用dart pub global deactivate dart_skills_cli之后再激活一次。4.3 依赖锁定与安全巡检Dart 项目的依赖锁定机制是 pubspec.lock。如果团队里有人手动改了这个文件或者用了dart pub upgrade之后没仔细看都可能导致 CI 里包子版本不一致。Skills CLI 的 scan 命令会记录当前分支 pubspec.lock 的 hash在 verify 时检查有没有被改动。但这只是第一层防护。我建议在 CI 里再加一道命令dart pub get --offline如果依赖锁定变更没有正确同步这步会直接失败比单纯看 hash 更早暴露问题。安全巡检方面CLI 会批量获取已发布包的最新版本信息比对当前依赖版本对存在已知废弃或重大修复的包进行提示。它不会自动升级因为自动升级往往不兼容。它只负责让你知道“有这回事”是否需要升级由你来决定。4.4 兼容性速查表场景推荐命令常见坑新项目初始化dart_skills init先确认 Dart SDK 已激活且版本不低于 2.19日常体检dart_skills scan报告会生成 md 文件记得加入 gitignore 决策生成 AI 上下文dart_skills context --task feature任务类型填错会导致上下文碎片不匹配生成 AI 提示词dart_skills prompt new-feature规则太多时 prompt 会很长建议先精简 deliver_rules交付前校验dart_skills verify --strict慢是正常的测试覆盖率统计会拉长时间CI 接入dart_skills verify --jsonJSON 输出便于解析退出码和告警查看变更排行dart_skills log --changed依赖 log 分析只支持 Git 仓库5. 踩坑心得与扩展方向5.1 我在真实项目里踩过的几个坑所有功能里最让我意外的坑来自“AI 上下文生成”这一块。一开始我让上下文文件包含整个 lib 的目录树结果 prompt token 消耗大得惊人而且 AI 会去关注那些根本不相关的基础工具类生成出来的代码反而更啰嗦。后来改成“按最近修改文件的前后缀采样”效果立刻好了很多。这件事给我的教训是给 AI 的信息不是越多越好而是越聚焦越好。另一个坑是错误处理风格的自动化检测。我本来想靠 AST 判断“这个方法的异常有没有被正确捕获”但 Dart 的异常体系很灵活静态推导经常误报。后来妥协成“只检测最明确的坏味道”比如 catch 子句里没有任何日志输出、没有任何重新抛出就提示可能吞异常。这个保守很多但准确率能接受项目里不会有那种“每天报警告但没人敢碰”的巨额列表。还有一个经验是关于格式化检查的频率。把dart format --set-exit-if-changed放进 verify 里一开始团队是很抗拒的因为不少人还在用默认 tab 宽度写代码。跑了两周之后大家反而接受度高了因为格式化差异造成的 diff 噪音没了Code Review 时的注意力能真正放在逻辑上。5.2 后续可扩展的能力第一版做完之后我脑子里还有几个很值得做的方向。一个是“AI 变更影响分析”。让 CLI 在 verify 时列出被修改文件的所有引用链然后把这部分影响链路也塞进 AI 上下文让 AI 在做代码评审时更有全局观。比如你改了一个实体类它不仅要看这个类还要看哪些 service 和 widget 依赖它变更会不会破坏序列化逻辑。另一个是“多项目技能包模板”。我手里有几个 Flutter 项目结构其实大同小异目前是每个项目 init 一次规则靠拷贝。以后打算支持导入团队级模板在 init 的时候直接拉取统一的落地规则避免每个项目的规范再次分叉。还有一个设想是把 verify 的检查项插件化。第一版我只内置了 format、analyze、test、依赖安全这几项但如果项目里需要跑自定义脚本比如检查懒加载图片是否都接上了占位符或者某类接口调用是否都带了超时参数可以通过插件机制扩展。Dart 生态已经有 build_runner 的插件思路可以参考做进去不算难只是优先级排在后面。从我自己的使用体感来说这套 CLI 已经不只是“AI 辅助工具”更像是一个项目治理的抓手。它把很多以前靠人提醒、靠运气规避的问题变成了机器可校验的门禁。未来我会继续用它来跑日常项目和做代码 review也会把团队里积累的更多规则沉淀进技能包。如果你也在做 Dart 或 Flutter 项目尤其是开始重度使用 AI 编码助手我建议你今天就可以试一试用技能包把项目的“隐性共识”固化下来。第一次初始化可能会花掉一点时间但换来的是以后每一次代码交付都更稳、更可预期。
返回列表