From ebcddca4bb2fc0f68aeb0a1bbf129edaf8d8186d Mon Sep 17 00:00:00 2001 From: efrilm Date: Wed, 2 Sep 2026 20:44:24 +0700 Subject: [PATCH] docs: perbarui README untuk FVM, build_runner, dan cara run/build Bagian setup lama tidak cuma kurang, tapi salah: diklaim environment dipilih otomatis dari debug/release, padahal datang dari --dart-define=ENV. Siapa pun yang mengikutinya akan menghasilkan APK 'production' yang menunjuk database dev. Tabel environment dan contoh kodenya juga sudah tidak sesuai isi lib/env.dart. Ditambah: prasyarat FVM, langkah instalasi ber-fvm, perintah build per environment, bagian Code Generation (termasuk peringatan --delete-conflicting-outputs yang menghapus seluruh file generated sebelum build), dan Troubleshooting. URL base sengaja tidak disalin ke README; cukup menunjuk lib/env.dart, karena menyalin nilai itulah yang membuat dokumen ini basi. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 133 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 114 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1a69632..8883676 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Aplikasi Point of Sale (POS) berbasis Flutter untuk manajemen kasir restoran. Me | Kategori | Library | |---|---| +| Version Manager | `fvm` — Flutter dipin di `.fvmrc` | | State Management | `flutter_bloc` + `bloc` | | Dependency Injection | `get_it` + `injectable` | | Navigation | `auto_route` | @@ -78,11 +79,13 @@ feature/ ### Prasyarat -- Flutter SDK `^3.8.1` -- Dart SDK `^3.8.1` +- **FVM** — project ini mengunci versi Flutter, jangan pakai Flutter global +- **Flutter 3.41.9** (Dart 3.11.5) — dipin di `.fvmrc` - Android SDK / Xcode (untuk iOS) - Firebase project yang sudah dikonfigurasi +> **Kenapa versinya dikunci?** Stack code generation project ini (`freezed` 2.x, `build_runner` 2.5, `analyzer` 7.7.1) hanya paham bahasa Dart sampai 3.9. Flutter 3.44 ke atas membawa framework yang ditulis di bahasa 3.10+, dan `analyzer` 7.7.1 crash saat membacanya. Selama stack codegen belum dinaikkan, **Flutter 3.41.9 adalah versi terbaru yang masih bisa menjalankan `build_runner`.** Lihat [Troubleshooting](#troubleshooting). + ### Instalasi ```bash @@ -90,44 +93,99 @@ feature/ git clone cd apskel-pos-flutter-v2 -# Install dependencies -flutter pub get +# Pasang FVM (sekali per mesin) +dart pub global activate fvm -# Generate kode (freezed, injectable, auto_route, json_serializable) -dart run build_runner build --delete-conflicting-outputs +# Ambil & pakai versi Flutter yang dipin di .fvmrc +fvm install +fvm use + +# Install dependencies +fvm flutter pub get + +# Generate kode +fvm dart run build_runner build ``` +> Semua perintah Flutter/Dart di project ini **harus diawali `fvm`**. `flutter run` tanpa `fvm` memakai Flutter global dan hasilnya bisa berbeda. + ### Menjalankan App +Environment **tidak** ditentukan otomatis dari debug/release — harus dioper lewat `--dart-define`: + ```bash # Development -flutter run +fvm flutter run --dart-define=ENV=dev -# Release -flutter run --release +# Production +fvm flutter run --dart-define=ENV=prod + +# Production, release mode +fvm flutter run --release --dart-define=ENV=prod ``` -App otomatis menggunakan environment `dev` saat debug dan `prod` saat release. +Kalau `ENV` tidak dioper, nilainya jatuh ke `dev` (lihat `defaultValue` di `lib/main.dart`). + +Di VSCode sudah tersedia konfigurasi **Dev** dan **Prod** di `.vscode/launch.json`, tinggal pilih di panel Run and Debug. + +### Build + +`--dart-define=ENV=prod` wajib ikut, kalau tidak APK-nya akan memakai database dan base URL milik dev: + +```bash +# APK +fvm flutter build apk --release --dart-define=ENV=prod + +# App Bundle (Play Store) +fvm flutter build appbundle --release --dart-define=ENV=prod + +# iOS +fvm flutter build ipa --release --dart-define=ENV=prod +``` + +--- + +## Code Generation + +Project ini banyak memakai kode generated (`freezed`, `injectable`, `auto_route`, `json_serializable`, `flutter_gen`). Kode itu **wajib di-generate ulang** setiap kali kamu: + +- menambah/mengubah kelas `@freezed` (entity, event, state, DTO) +- menambah/mengubah anotasi DI (`@injectable`, `@LazySingleton`, `@Injectable(as: ...)`) +- menambah halaman baru dengan `@RoutePage()` +- menambah aset di `pubspec.yaml` + +```bash +# Sekali jalan +fvm dart run build_runner build + +# Mode watch — regenerate otomatis saat file berubah, enak dipakai saat ngoding +fvm dart run build_runner watch +``` + +> **Hindari `--delete-conflicting-outputs`.** Flag itu menghapus seluruh file generated **sebelum** mulai build. Kalau build-nya gagal di tengah jalan, kamu berakhir tanpa kode generated sama sekali dan project tidak bisa di-compile. Pakai hanya kalau build_runner benar-benar mengeluh soal konflik output, dan pastikan working tree-mu bersih dulu supaya bisa `git restore`. --- ## Environment -Konfigurasi environment ada di `lib/env.dart`: +Konfigurasi environment ada di `lib/env.dart` — **itu sumber kebenarannya**, jangan disalin ke sini karena gampang basi. -| Environment | Base URL | Database | -|---|---|---| -| `dev` | `https://api-pos.apskel.id` | `apskel_pos_dev.db` | -| `prod` | `https://api-pos.apskel.id` | `apskel_pos_dev.db` | +| Environment | Database | +|---|---| +| `dev` | `apskel_pos_staging.db` | +| `prod` | `apskel_pos_prod.db` | -Environment dipilih otomatis di `main.dart`: +Environment dipilih dari `--dart-define=ENV=...` di `lib/main.dart`: ```dart -await configureDependencies( - kReleaseMode ? Environment.prod : Environment.dev, -); +const String env = String.fromEnvironment('ENV', defaultValue: 'dev'); +await configureDependencies(env); ``` +Nilai `env` diteruskan ke `injectable`, yang lalu memilih antara `DevEnv` (`@dev`) dan `ProdEnv` (`@prod`). Menambah environment baru berarti menambah kelas ber-anotasi di `lib/env.dart`, lalu generate ulang. + +Karena `dev` dan `prod` memakai **nama database berbeda**, berpindah environment di perangkat yang sama tidak akan mencampur datanya. + --- ## Dependency Injection @@ -210,6 +268,43 @@ App dikunci ke mode **landscape** (kiri & kanan) karena didesain untuk tablet PO ## Catatan Development +- Selalu pakai `fvm flutter` / `fvm dart`, bukan `flutter` / `dart` global - Jangan edit `injection.config.dart` dan file `*.freezed.dart` / `*.g.dart` secara manual — file tersebut di-generate otomatis +- Setelah mengubah kelas `@freezed` atau anotasi DI, jalankan build_runner sebelum menjalankan app - Gunakan `log()` dari `dart:developer` untuk logging, bukan `print()` - `print()` dinonaktifkan di release mode + +--- + +## Troubleshooting + +### `build_runner` gagal: `Missing implementation of visitDotShorthandPropertyAccess` + +Kamu sedang memakai Flutter yang terlalu baru. Cek: + +```bash +fvm flutter --version # harus 3.41.9 +flutter --version # ini Flutter global, boleh versi apa saja +``` + +Kalau versinya bukan 3.41.9, artinya perintahnya jalan tanpa `fvm`. Log build juga memberi petunjuk yang sama: + +``` +SDK language version 3.13.0 is newer than `analyzer` language version 3.9.0 +``` + +Perbaikannya: `fvm use`, lalu ulangi dengan awalan `fvm`. + +Menaikkan Flutter melewati 3.41.x mengharuskan seluruh stack codegen ikut naik — `freezed` 2 → 3/4, `build_runner` → 2.16, `injectable_generator` 2 → 3, `auto_route` 9 → 10. `freezed` 3 mewajibkan tiap kelas dideklarasikan `abstract`/`sealed` dan menghapus `when`/`map` (diganti pattern matching), jadi ini pekerjaan tersendiri, bukan sambilan. + +### Project tidak bisa di-compile, banyak error `_$Something` tidak ditemukan + +Kode generated-nya hilang atau belum dibuat. Jalankan: + +```bash +fvm dart run build_runner build +``` + +### `fvm: command not found` + +FVM terpasang di `~/AppData/Local/Pub/Cache/bin` (Windows) atau `~/.pub-cache/bin` (macOS/Linux) yang mungkin belum ada di `PATH`. Tambahkan direktori itu ke `PATH`, atau panggil dengan path lengkap.