mcpField
F
flutter-best-practices

flutter-best-practices

github.com/evanca开发663230 次安装3 周前更新
代码仓库

关于 flutter-best-practices

面向 Flutter 开发者的应用架构与编码实践指南,覆盖分层、功能目录、状态建模、测试和项目评审。还提供按任务查阅参考资料的工作流。

主要功能

  1. 01分离 UI 与数据层
  2. 02按功能组织代码
  3. 03使用不可变显式状态
  4. 04遵循现代 Dart 编码实践
  5. 05按任务查阅架构参考资料
  6. 06提供功能开发与代码评审清单

适用场景

  1. 01规划新应用的架构与目录
  2. 02添加功能或新页面
  3. 03评审 Flutter 代码及测试
  4. 04处理多团队或多包项目

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/evanca/flutter-ai-rules --skill flutter-best-practices

安装后在 Claude Code 中输入/flutter-best-practices确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
architecture-layers.md
dart-coding-practices.md
enterprise-scale.md
feature-structure.md
localization-package-boundaries.md

详细介绍

Flutter 最佳实践

构建易于维护的 Flutter 应用的规范,汇总自官方 Flutter 架构指南,以及 LeanCode 交付 40 多个 Flutter 项目的经验(包括一款由 30 名开发人员参与开发的银行应用)。编写新代码时请遵循这些规范;修改现有代码时,优先与周边代码库保持一致。如果现有代码与这些规范冲突,请指出冲突,而不要悄悄重写。

如何使用此技能

阅读与任务相匹配的参考文件。若任务涉及多个方面,请阅读多个文件(例如,新功能同时涉及结构和编码风格)。

任务阅读
设计分层、确定逻辑归属、MVVM、仓库/服务references/architecture-layers.md
创建/组织功能、文件夹结构、状态管理接线references/feature-structure.md
编写或审查 Dart/Flutter 代码、组件、测试、lintreferences/dart-coding-practices.md
多团队/多包应用、monorepo、导航、本地化、API 契约、E2E 测试references/enterprise-scale.md
应用本地化设置、可复用 UI 包的字符串归属、语言选择器可见性references/localization-package-boundaries.md

对于简单任务(修复小组件、添加一行审查意见),仅遵循以下核心规则可能就足够了。

核心规则(始终遵循)

架构
  1. 分离 UI 与数据。 分为两个主要层:UI(视图 + 视图模型/cubit)和数据(仓库 + 服务)。依赖单向流动:View → ViewModel → Repository → Service。底层绝不导入上层。仓库之间绝不相互依赖。
  2. 视图不包含业务逻辑。 组件可以包含显示/隐藏条件、动画、布局和简单的路由逻辑,但不能转换或判断数据。所有数据逻辑都放在视图模型(或 cubit/bloc)中,且视图模型无法访问 BuildContext。
  3. 按功能组织,而不是按层组织。 功能所需的一切——状态管理、组件、模型——都放在同一个功能目录下。不要创建顶层的 blocs/、widgets/、models/ 目录,把一个功能分散到整个目录树中。
  4. 状态不可变且明确。 将 UI 状态建模为 sealed/union 类型(initial / inProgress / failure / ready),以确保穷尽处理所有情况。一次性效果(如 snackbars、导航)应作为事件,而不是状态。
  5. 仅在确有价值时增加层。 从 view-model → API 客户端开始。需要缓存、离线支持或合并多个数据源时,再引入仓库。仅当逻辑需要合并多个仓库、确实复杂,或被多个视图模型复用时,才引入用例。
编码
  1. 优先使用表达意图的组件,而不是 Container。 使用 Padding、SizedBox、ColoredBox、DecoratedBox、Center——它们可以声明为 const,且能清晰表达用途。只有在需要同时组合多个属性时,才使用 Container。
  2. 使用现代 Dart。 使用模式匹配(if (x case final v?))、可穷尽处理所有情况的 switch 表达式、records 和解构,以及集合 if/for/spread 替代 .add() 循环;透传的异步函数使用表达式体(避免冗余的 async/await)。
  3. 为返回 sliver 的组件添加 Sliver 前缀,便于一眼发现其被误用于错误滚动上下文的情况。
  4. 让测试讲述一个故事。 使用表达力强的匹配器(isEmpty、throwsA、isA、completion),并尽量减少依赖——测试 fixture 中优先使用普通的 Text/SizedBox,而非设计系统组件。脱离组件树,单独测试 cubit/视图模型。
  5. 每个 // ignore: 都必须在同一行或前一行说明原因。 使用专用的 error/stackTrace 参数记录错误,绝不要使用字符串插值。

工作流检查清单

添加新功能/屏幕
  1. 阅读 references/feature-structure.md, 并遵循现有项目的功能目录约定。
  2. 先将状态定义为联合类型,再定义 cubit/视图模型,最后编写 组件。通过构造函数注入依赖,并将其限定在功能的 组件子树内。
  3. 数据应通过仓库或类型化 API 客户端传入——绝不要在组件 内获取数据。
  4. 在连接 UI 细节之前,先为 cubit/视图模型逻辑添加单元测试。
审查 Flutter 代码

按重要性顺序检查:

  1. 逻辑是否位于正确的层(规则 1–2)?业务逻辑中是否有 BuildContext?
  2. 状态是否建模为不可变联合类型,且所有情况都已处理?
  3. 功能是否自成一体,还是会访问其他功能的内部实现?
  4. 组件选择(规则 6)、现代 Dart(规则 7)、sliver 命名(规则 8)是否合适?
  5. 是否为逻辑编写了测试,且测试易读、依赖最少?
  6. 是否存在没有说明原因的 // ignore:、使用字符串插值的错误日志,或仍在扩散的弃用模式?
启动新项目
  1. 阅读 references/architecture-layers.md 了解分层蓝图,并阅读 references/feature-structure.md 了解 目录骨架。
  2. 如果涉及的团队超过约 2 个,或领域明显可分,则阅读 references/enterprise-scale.md,并考虑从第一天起就采用 Melos 单体仓库,按领域拆分为独立包。
  3. 尽早设置严格的 lint 规则(leancode_lint 或同类工具 + 自定义规则)——事后补上要昂贵得多。

软件包选型

本规范默认使用以下方案(如果代码库已有其他方案,可替换为项目本地的对应方案):

  • 状态: 使用 bloc(Cubit)+ freezed 定义联合类型状态; 使用 bloc_presentation 处理一次性 UI 事件
  • 依赖注入: 使用限定在组件子树内的 provider(接受其缺少编译时安全性的缺点,视为较轻的弊端)
  • 减少样板代码: flutter_hooks
  • 单体仓库: melos
  • 本地化: flutter_localizations + intl,使用 .arb 文件
  • Lint: leancode_lint
  • E2E/UI 测试: patrol

Flutter 官方指南不限定状态管理方案(MVVM 配合 ChangeNotifier 也可以);关键在于分层,而非所用软件包。关于理由和权衡,请参阅参考文件。

评论

支持 Markdown