All skills

flutter-dart-code-review

Official
by Api.AirforcePrepends a system promptFrontend Development000 uses202,700

库无关的Flutter/Dart代码审查清单,涵盖Widget最佳实践、状态管理模式(BLoC、Riverpod、Provider、GetX、MobX、Signals)、Dart惯用法、性能、可访问性、安全性和整洁架构。

open-sourceclaude-codefrontend-developmentaffaan-m
Share

What this skill does

When applied, it prepends a system prompt before your request is sent — no extra calls and no change to how you are billed beyond the added tokens.

---
name: flutter-dart-code-review
description: 库无关的Flutter/Dart代码审查清单,涵盖Widget最佳实践、状态管理模式(BLoC、Riverpod、Provider、GetX、MobX、Signals)、Dart惯用法、性能、可访问性、安全性和整洁架构。
origin: ECC
---

# Flutter/Dart 代码审查最佳实践

适用于审查 Flutter/Dart 应用程序的全面、与库无关的清单。无论使用哪种状态管理方案、路由库或依赖注入框架,这些原则都适用。

***

## 1. 通用项目健康度

* \[ ] 项目遵循一致的文件夹结构(功能优先或分层优先)
* \[ ] 关注点分离得当:UI、业务逻辑、数据层
* \[ ] 部件中无业务逻辑;部件纯粹是展示性的
* \[ ] `pubspec.yaml` 是干净的 —— 没有未使用的依赖项,版本已适当固定
* \[ ] `analysis_options.yaml` 包含严格的 lint 规则集,并启用了严格的分析器设置
* \[ ] 生产代码中没有 `print()` 语句 —— 使用 `dart:developer` `log()` 或日志包
* \[ ] 生成的文件 (`.g.dart`, `.freezed.dart`, `.gr.dart`) 是最新的或在 `.gitignore` 中
* \[ ] 平台特定代码通过抽象进行隔离

***

## 2. Dart 语言陷阱

* \[ ] **隐式动态类型**:缺少类型注解导致 `dynamic` —— 启用 `strict-casts`, `strict-inference`, `strict-raw-types`
* \[ ] **空安全误用**:过度使用 `!`(感叹号操作符)而不是适当的空检查或 Dart 3 模式匹配 (`if (value case var v?)`)
* \[ ] **类型提升失败**:在可以使用局部变量类型提升的地方使用了 `this.field`
* \[ ] **捕获范围过宽**:`catch (e)` 没有 `on` 子句;应始终指定异常类型
* \[ ] **捕获 `Error`**:`Error` 子类型表示错误,不应被捕获
* \[ ] **未使用的 `async`**:标记为 `async` 但从未 `await` 的函数 —— 不必要的开销
* \[ ] **`late` 过度使用**:在可使用可空类型或构造函数初始化更安全的地方使用了 `late`;将错误推迟到运行时
* \[ ] **循环中的字符串拼接**:使用 `StringBuffer` 而不是 `+` 进行迭代式字符串构建
* \[ ] **`const` 上下文中的可变状态**:`const` 构造器类中的字段不应是可变的
* \[ ] **忽略 `Future` 返回值**:使用 `await` 或显式调用 `unawaited()` 来表明意图
* \[ ] **在 `final` 可用时使用 `var`**:局部变量首选 `final`,编译时常量首选 `const`
* \[ ] **相对导入**:为保持一致性,使用 `package:` 导入
* \[ ] **暴露可变集合**:公共 API 应返回不可修改的视图,而不是原始的 `List`/`Map`
* \[ ] **缺少 Dart 3 模式匹配**:优先使用 switch 表达式和 `if-case`,而不是冗长的 `is` 检查和手动类型转换
* \[ ] **为多重返回值使用一次性类**:使用 Dart 3 记录 `(String, int)` 代替一次性 DTO
* \[ ] **生产代码中的 `print()`**:使用 `dart:developer` `log()` 或项目的日志包;`print()` 没有日志级别且无法过滤

***

## 3. 部件最佳实践

### 部件分解:

* \[ ] 没有单个部件的 `build()` 方法超过约 80-100 行
* \[ ] 部件按封装方式以及按变化方式(重建边界)进行拆分
* \[ ] 返回部件的私有 `_build*()` 辅助方法被提取到单独的部件类中(支持元素重用、常量传播和框架优化)
* \[ ] 在不需要可变局部状态的地方,优先使用无状态部件而非有状态部件
* \[ ] 提取的部件在可复用时放在单独的文件中

### Const 使用:

* \[ ] 尽可能使用 `const` 构造器 —— 防止不必要的重建
* \[ ] 对不变化的集合使用 `const` 字面量 (`const []`

Use this skill

Per request

Add a "skill" field with the skill’s ID to your chat completion request. It is applied server-side before your prompt is sent — no extra calls.

{
  "model": "gpt-4o-mini",
  "skill": "imp-381198e6-8892-4789-b977-ac6fddfe317d",
  "messages": [{ "role": "user", "content": "…" }]
}
Always on — no field to send

Install the skill, enable it in your dashboard and (optionally) limit it to specific models. It then applies automatically to every matching request — with no "skill" field to send each time.

Set it up in your dashboard