# Code Generation (build_runner) > **PENTING:** `build_runner` di 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`/`build` > dengan Flutter versi global (3.47). --- ## TL;DR PowerShell (Windows): ```powershell $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: ```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: 1. `freezed 2.5.8` membatasi `analyzer <8.0.0`, jadi pub me-resolve ke **analyzer 7.7.1** (language version 3.9). 2. Dart 3.13 memakai sintaks *dot-shorthand* (`.value`) di sumber SDK/framework. 3. Analyzer 7.7.1 bisa mem-*parse*-nya tapi belum bisa menuliskannya ke summary → crash saat resolve. 4. 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 ```powershell 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): ```powershell 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, jalankan `fvm use 3.41.9` lalu pakai `fvm dart run build_runner ...`, > dan tambahkan `.fvm/` ke `.gitignore`. --- ## Perintah harian Semua contoh memakai variabel `$FVM` dari bagian TL;DR. ```powershell # 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**: ```powershell 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): ```bash 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: - `freezed` 2.5.8 → 3.x, `freezed_annotation` 2.4.x → 3.x - `injectable` 2.x → 3.x, `injectable_generator` 2.7 → 3.x - `auto_route` 9.x → 11.x, `auto_route_generator` 9.x → 10.x - `build_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 `@freezed` harus dideklarasikan `abstract class` atau `sealed class`. - Migrasi konfigurasi router (auto_route 11) dan DI (injectable 3). Selama migrasi itu belum dikerjakan, gunakan alur FVM di dokumen ini.