6.1 KiB
Code Generation (build_runner)
PENTING:
build_runnerdi proyek ini tidak bisa dijalankan dengan Flutter 3.47 / Dart 3.13. Gunakan SDK Flutter 3.41.9 (Dart 3.11.5) lewat FVM. Aplikasinya sendiri tetap di-run/builddengan Flutter versi global (3.47).
TL;DR
PowerShell (Windows):
$FVM = "$env:USERPROFILE\fvm\versions\3.41.9\bin"
& "$FVM\flutter.bat" pub get # 1. resolve paket dgn Dart 3.11.5
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs # 2. generate
flutter pub get # 3. balik ke SDK global 3.47
Git Bash:
FVM=~/fvm/versions/3.41.9/bin
"$FVM/flutter.bat" pub get
"$FVM/dart.bat" run build_runner build --delete-conflicting-outputs
flutter pub get
Durasi normal: ±90–120 detik untuk full build (146 output).
Setelah itu jalankan flutter analyze untuk memastikan hasil generate bersih.
Kenapa harus SDK terpisah?
Kalau codegen dijalankan dengan Flutter global (3.47 / Dart 3.13), semua builder gagal dengan:
W SDK language version 3.13.0 is newer than `analyzer` language version 3.9.0.
E freezed on lib/application/.../category_analytic_loader_bloc.dart:
Exception: Missing implementation of visitDotShorthandPropertyAccess
Rantai penyebabnya:
freezed 2.5.8membatasianalyzer <8.0.0, jadi pub me-resolve ke analyzer 7.7.1 (language version 3.9).- Dart 3.13 memakai sintaks dot-shorthand (
.value) di sumber SDK/framework. - Analyzer 7.7.1 bisa mem-parse-nya tapi belum bisa menuliskannya ke summary → crash saat resolve.
- Semua generator (
freezed,json_serializable,injectable_generator,auto_route_generator) berbagi analyzer yang sama, jadi semuanya ikut mati — termasuk saat men-generate file lama yang tidak diubah.
Dart 3.11.5 (Flutter 3.41.9) adalah versi tertinggi yang masih cocok dengan analyzer 7.7.1 sekaligus memenuhi batas pubspec.lock (dart >=3.11.0-0).
Setup sekali di mesin baru
dart pub global activate fvm
Tambahkan folder binari pub ke PATH agar perintah fvm dikenali:
%LOCALAPPDATA%\Pub\Cache\bin
Lalu unduh SDK-nya (±1 GB, sekali saja):
fvm install 3.41.9
fvm list # verifikasi
SDK tersimpan di %USERPROFILE%\fvm\versions\3.41.9 dan tidak mengubah Flutter global.
Kita sengaja tidak menjalankan
fvm use, supaya repo tidak punya.fvmrc/.fvm/dan IDE tetap memakai Flutter 3.47 untuk menjalankan aplikasi. Kalau lebih suka pin per-project, jalankanfvm use 3.41.9lalu pakaifvm dart run build_runner ..., dan tambahkan.fvm/ke.gitignore.
Perintah harian
Semua contoh memakai variabel $FVM dari bagian TL;DR.
# build sekali (paling sering dipakai)
& "$FVM\dart.bat" run build_runner build --delete-conflicting-outputs
# mode watch saat banyak mengubah anotasi
& "$FVM\dart.bat" run build_runner watch --delete-conflicting-outputs
# hanya membersihkan output generated
& "$FVM\dart.bat" run build_runner clean
Wajib generate ulang setiap kali mengubah/menambah file dengan anotasi:
| Anotasi | Generator | Output |
|---|---|---|
@freezed |
freezed | *.freezed.dart |
@JsonSerializable / fromJson di DTO |
json_serializable | *.g.dart |
@injectable, @LazySingleton |
injectable_generator | lib/injection.config.dart |
@RoutePage() |
auto_route_generator | lib/presentation/router/app_router.gr.dart |
asset baru di assets/ |
flutter_gen_runner | lib/presentation/components/assets/assets.gen.dart |
Localization (i18n) — tidak lewat build_runner
flutter gen-l10n memakai tooling Flutter, bukan analyzer, jadi aman dijalankan dengan Flutter 3.47:
flutter gen-l10n
Jalankan setiap kali lib/l10n/app_id.arb / app_en.arb berubah. Hasilnya: lib/l10n/app_localizations*.dart.
Aturan penting soal --delete-conflicting-outputs
Flag ini menghapus dulu semua file generated (±55 file *.freezed.dart / *.g.dart) sebelum membuat ulang.
Kalau proses dibatalkan di tengah jalan, project akan penuh error karena file-nya sudah hilang.
Pemulihan (semua file generated ikut ter-commit di git):
git status --porcelain | grep -E "^ D" | sed 's/^ D //' | while read -r f; do git checkout -- "$f"; done
Tips: jangan pipe output build ke tail/head — outputnya jadi ter-buffer sampai proses selesai,
sehingga terlihat seperti hang padahal sedang jalan.
Troubleshooting
| Gejala | Penyebab | Solusi |
|---|---|---|
Missing implementation of visitDotShorthandPropertyAccess |
codegen dijalankan dengan Flutter global 3.47 | pakai SDK FVM 3.41.9 |
Failed to update packages + dump stack VM |
flutter pub run build_runner / fvm spawn ... pub run |
pakai dart.bat run build_runner, jangan flutter pub run |
Ratusan error “isn't defined” di IDE, file *.freezed.dart hilang |
build dibatalkan setelah --delete-conflicting-outputs |
restore lewat git checkout (lihat di atas) |
pub get gagal / versi paket bergeser |
pubspec.lock di-resolve oleh SDK berbeda |
jalankan flutter pub get dengan SDK global setelah codegen selesai |
| Build terasa lama di run pertama | asset graph baru dibuat dari nol | wajar, ±90–120 detik; run berikutnya inkremental |
Rencana jangka panjang
Perbaikan permanen = upgrade toolchain codegen supaya jalan native di Dart 3.13:
freezed2.5.8 → 3.x,freezed_annotation2.4.x → 3.xinjectable2.x → 3.x,injectable_generator2.7 → 3.xauto_route9.x → 11.x,auto_route_generator9.x → 10.xbuild_runner→ 2.16.x,json_serializable→ 6.14.x (analyzer ikut naik ke 13.x)
Konsekuensinya breaking dan cukup besar, jadi perlu dijadwalkan sendiri:
- freezed 3 menghapus
.map()/.when()/.maybeWhen()/.maybeMap()→ ±49 pemakaian (mayoritas di handler event BLoC) harus diganti pattern matching Dart 3 (switch). - ±98 file dengan
@freezedharus dideklarasikanabstract classatausealed class. - Migrasi konfigurasi router (auto_route 11) dan DI (injectable 3).
Selama migrasi itu belum dikerjakan, gunakan alur FVM di dokumen ini.