코드 생성 — build_runner, freezed, auto_route
코드 생성 — build_runner, freezed, auto_route
Flutter 프로젝트에서 반복적인 보일러플레이트 코드를 자동 생성하는 것은 생산성의 핵심입니다. build_runner를 기반으로 하는 주요 코드 생성 도구들을 정리해보겠습니다.
build_runner란?
build_runner는 Dart의 코드 생성 프레임워크입니다. 어노테이션을 분석하여 코드를 자동 생성합니다.
# 1회 빌드
dart run build_runner build
# 파일 변경 감시 (개발 중 권장)
dart run build_runner watch
# 충돌 해결 후 재빌드
dart run build_runner build --delete-conflicting-outputs
대표적인 코드 생성 도구들
| 도구 | 생성 결과 | 생성 파일 |
|---|---|---|
| json_serializable | fromJson/toJson | .g.dart |
| freezed | 불변 클래스 + copyWith + == | .freezed.dart + .g.dart |
| auto_route | 타입 안전한 라우팅 코드 | .gr.dart |
| injectable | DI 등록 코드 | .config.dart |
| hive_generator | Hive 어댑터 | .g.dart |
| mockito | Mock 클래스 | .mocks.dart |
freezed — 불변 데이터 클래스
import 'package:freezed_annotation/freezed_annotation.dart';
part 'user.freezed.dart';
part 'user.g.dart';
@freezed
class User with _$User {
const factory User({
required int id,
required String name,
required String email,
@Default(false) bool isActive,
}) = _User;
factory User.fromJson(Map<String, dynamic> json) =>
_$UserFromJson(json);
}
// 자동 생성되는 것들:
// - copyWith
// - == / hashCode
// - toString
// - fromJson / toJson
Union 타입
@freezed
sealed class AuthState with _$AuthState {
const factory AuthState.initial() = _Initial;
const factory AuthState.loading() = _Loading;
const factory AuthState.authenticated(User user) = _Authenticated;
const factory AuthState.error(String message) = _Error;
}
// 패턴 매칭
state.when(
initial: () => const Text('초기'),
loading: () => const CircularProgressIndicator(),
authenticated: (user) => Text('안녕, ${user.name}'),
error: (message) => Text('에러: $message'),
);
auto_route — 타입 안전한 라우팅
dependencies:
auto_route: ^9.0.0
dev_dependencies:
auto_route_generator: ^9.0.0
build_runner: ^2.4.0
라우터 정의
import 'package:auto_route/auto_route.dart';
part 'app_router.gr.dart';
@AutoRouterConfig()
class AppRouter extends RootStackRouter {
@override
List<AutoRoute> get routes => [
AutoRoute(page: HomeRoute.page, initial: true),
AutoRoute(page: DetailRoute.page, path: '/detail/:id'),
AutoRoute(page: SettingsRoute.page),
// 중첩 라우팅
AutoRoute(
page: DashboardRoute.page,
children: [
AutoRoute(page: OverviewRoute.page),
AutoRoute(page: StatsRoute.page),
],
),
];
}
페이지 어노테이션
@RoutePage()
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
// 타입 안전한 네비게이션
context.router.push(DetailRoute(id: 42));
},
child: const Text('상세로'),
),
),
);
}
}
@RoutePage()
class DetailScreen extends StatelessWidget {
final int id;
const DetailScreen({super.key, @PathParam('id') required this.id});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('상세 #$id')),
);
}
}
사용
MaterialApp.router(
routerConfig: AppRouter().config(),
)
// 네비게이션
context.router.push(const HomeRoute());
context.router.push(DetailRoute(id: 42));
context.router.pop();
context.router.replaceAll([const HomeRoute()]);
여러 코드 생성기 함께 사용
# pubspec.yaml
dependencies:
freezed_annotation: ^2.4.0
json_annotation: ^4.9.0
auto_route: ^9.0.0
injectable: ^2.4.0
get_it: ^8.0.0
dev_dependencies:
build_runner: ^2.4.0
freezed: ^2.5.0
json_serializable: ^6.8.0
auto_route_generator: ^9.0.0
injectable_generator: ^2.6.0
build.yaml로 빌드 최적화
# build.yaml (프로젝트 루트)
targets:
$default:
builders:
# 특정 디렉토리만 감시 (빌드 속도 향상)
json_serializable:
generate_for:
- lib/models/**
freezed:
generate_for:
- lib/models/**
- lib/features/**/domain/**
코드 생성 실전 팁
# 1. 충돌 시 삭제 후 재빌드
dart run build_runner build --delete-conflicting-outputs
# 2. 특정 파일만 빌드 (빠름)
dart run build_runner build --build-filter="lib/models/*"
# 3. watch 모드에서 개발
dart run build_runner watch --delete-conflicting-outputs
# 4. 생성된 파일은 .gitignore에 넣지 않기
# .g.dart, .freezed.dart 등은 커밋해야 CI/CD에서 빌드 가능
.g.dart vs .freezed.dart
| 확장자 | 생성 도구 | 내용 |
|---|---|---|
.g.dart | json_serializable, hive | fromJson/toJson, 어댑터 |
.freezed.dart | freezed | copyWith, ==, toString |
.gr.dart | auto_route | 라우터 코드 |
.mocks.dart | mockito | Mock 클래스 |
.config.dart | injectable | DI 설정 |
정리
build_runner는 Flutter의 코드 생성 기반으로, 여러 생성기를 통합 실행합니다freezed로 불변 데이터 클래스와 Union 타입을 자동 생성합니다auto_route로 타입 안전한 라우팅 코드를 생성합니다dart run build_runner watch로 실시간 코드 생성하며 개발하세요- 생성된 파일(
.g.dart등)은 버전 관리에 포함시키는 것이 일반적입니다 build.yaml로 빌드 범위를 제한하면 속도를 개선할 수 있습니다
댓글 로딩 중...