代码生成与 build_runner
Dart 的代码生成工具可以自动为你编写模板代码,减少重复劳动。build_runner 是 Dart 生态中最常用的代码生成运行器。
为什么要用代码生成
在 Flutter 开发中,有很多重复性的模板代码:
fromJson()/toJson()— JSON 序列化copyWith()/==/hashCode— 不可变数据类- Provider 变量声明 — 状态管理
- 路由表 — 导航
这些代码手写既繁琐又容易出错,代码生成可以自动完成。
build_runner 使用方法
安装
代码生成工具通常作为 dev_dependencies 安装:
bash
flutter pub add dev:build_runner常用命令
bash
# 一次性生成所有代码
dart run build_runner build
# 监听文件变化,自动重新生成(开发时推荐)
dart run build_runner watch
# 清理生成的文件
dart run build_runner clean
# 删除并重新生成
dart run build_runner build --delete-conflicting-outputs理解 part 指令
代码生成写法中,你会看到:
dart
part 'user.g.dart';part 是 Dart 语言的关键字,意思是「这个文件和另一个文件属于同一个库,共享私有成员」。
- 你写了章节正文(
user.dart) - 模板代码让助手写(
user.g.dart) part告诉 Dart:「我们俩合起来才是完整的一章」
关键规则
part 'xxx.g.dart'中的文件名必须与当前文件对应- 永远不要手动编辑
.g.dart文件——每次运行 build_runner 都会重新覆盖 - 用了注解就必须加上对应的
part声明
常用代码生成包
json_serializable — JSON 序列化
bash
flutter pub add json_annotation
flutter pub add dev:json_serializable
flutter pub add dev:build_runnerdart
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable()
class User {
final String name;
final int age;
final String? email;
User({required this.name, required this.age, this.email});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}freezed — 不可变数据类
freezed 可以自动生成 copyWith、==、hashCode、toString 等方法:
bash
flutter pub add freezed_annotation
flutter pub add dev:freezed
flutter pub add dev:build_runnerdart
import 'package:freezed_annotation/freezed_annotation.dart';
part 'user.freezed.dart';
part 'user.g.dart';
@freezed
class User with _$User {
const factory User({
required String name,
required int age,
String? email,
}) = _User;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}使用:
dart
final user = User(name: '张三', age: 25);
// copyWith
final updated = user.copyWith(age: 26);
// == 比较
user == updated; // false
// JSON 序列化(需要 json_serializable)
final json = user.toJson();
final fromJson = User.fromJson(json);riverpod_generator — Riverpod 代码生成
bash
flutter pub add riverpod_annotation
flutter pub add dev:riverpod_generator
flutter pub add dev:build_runnerdart
part 'counter.g.dart';
@riverpod
class Counter extends _$Counter {
@override
int build() => 0;
void increment() => state++;
}
// counterProvider 自动生成代码生成速查
| 包 | 生成内容 | 适用场景 |
|---|---|---|
| json_serializable | fromJson / toJson | API 数据模型 |
| freezed | copyWith / == / toString | 不可变数据类 |
| riverpod_generator | Provider 定义 | Riverpod 状态管理 |
| go_router_builder | 路由表 | 类型安全路由 |
建议
- 入门阶段:先手动写,理解原理
- 正式项目:使用代码生成,减少手写错误
- 开发时用
dart run build_runner watch自动生成
下一步
- 测试 — 单元测试 / Widget 测试
