Modullara bölmə: package-lər və melos
Qovluq bölgüsü qaydayı tövsiyə kimi saxlayır; paket bölgüsü onu məcburi edir. Fərq bir cümlədə: packages/domain paketinin pubspec.yaml-ında Flutter asılılığı yoxdursa, import 'package:flutter/material.dart' sətri kompilyasiya olunmur.
Bu, ən güclü qat qorunmasıdır, lakin qiyməti var:
- Hər paketdə ayrı
pubspec.yamlvə versiya idarəsi. - Kod generasiyası (
build_runner) hər paketdə ayrıca işlədilir. - Bir neçə paketdən sonra əmrləri hər paketdə işlətmək üçün alət lazımdır — bu, melos-un rolu.
- Yeni komanda üzvü üçün başlanğıc mürəkkəbliyi artır.
Nə vaxt bölmək. Üç konkret siqnal:
1. Kod paylaşılır: mobil tətbiq + admin paneli, ya da mobil + server tərəfi Dart. Domain modelləri və validasiya qaydaları hər iki tərəfdə eyni olmalıdır. 2. Bir neçə komanda: hər komanda öz feature paketini müstəqil inkişaf etdirir və review sərhədləri aydın olur. 3. Build vaxtı: kod generasiyası bütün layihədə işlədikdə dəqiqələr çəkir; paketlərə bölündükdə yalnız dəyişən paket yenidən generasiya olunur.
Bu siqnallardan heç biri yoxdursa, qovluq bölgüsü + CI-də grep yoxlaması tam kifayətdir.
# ══ Struktur ══
# my_app/
# ├── pubspec.yaml ← workspace + melos konfiqurasiyası
# ├── packages/
# │ ├── domain/ ← təmiz Dart: modellər, müqavilələr
# │ ├── data/ ← service, DTO, repository impl.
# │ ├── ui_kit/ ← paylaşılan widget-lər, tema
# │ ├── feature_orders/
# │ └── feature_loyalty/
# └── app/ ← giriş nöqtəsi, DI, routing
# ══ my_app/pubspec.yaml (root) ══
name: my_app_workspace
publish_to: none
environment:
sdk: ^3.6.0 # Pub workspace dəstəyi üçün minimum
# Pub workspace: paketlər bir `pub get` ilə həll olunur.
workspace:
- packages/domain
- packages/data
- packages/ui_kit
- packages/feature_orders
- packages/feature_loyalty
- app
# melos konfiqurasiyası — melos 7+ üçün eyni faylda.
dev_dependencies:
melos: ^8.0.0
melos:
scripts:
analyze:
run: dart analyze .
exec:
concurrency: 4
test:
run: flutter test
exec:
concurrency: 4
packageFilters:
dirExists: test # yalnız testi olan paketlərdə
generate:
run: dart run build_runner build --delete-conflicting-outputs
exec:
concurrency: 2
packageFilters:
dependsOn: build_runner
check-layers:
run: ../../tool/check_layers.sh
packageFilters:
scope: domain
# ══ packages/domain/pubspec.yaml ══
# name: domain
# resolution: workspace
# environment:
# sdk: ^3.6.0 ← `flutter:` bölməsi YOXDUR
# dependencies:
# freezed_annotation: ^3.0.0 (təmiz Dart)
# meta: ^1.15.0
# dev_dependencies:
# build_runner: ^2.4.0
# freezed: ^3.0.0
# test: ^1.25.0 (flutter_test DEYİL)
# ══ Əmrlər ══
# melos bootstrap → bütün paketlərin asılılıqlarını həll edir
# melos run analyze → hər paketdə `dart analyze`
# melos run test → yalnız testi olan paketlərdə `flutter test`
# melos run generate → yalnız build_runner-a ehtiyacı olanlarda
# melos exec -- <əmr> → ixtiyari əmri hər paketdə işlədirMonorepo quruluşu: root `pubspec.yaml` Pub workspace-i və melos konfiqurasiyasını daşıyır (melos 7+ ayrı `melos.yaml` işlətmir).
| Paket | Flutter asılılığı | Kimi import edə bilər | Məqsədi |
|---|---|---|---|
| `domain` | ❌ Yoxdur | Heç kimi (yalnız təmiz Dart paketləri) | Modellər, müqavilələr, `Failure`-lar, use-case-lər |
| `data` | ⚠️ Ola bilər (plugin-lər üçün) | `domain` | Service-lər, DTO-lar, repository implementasiyaları |
| `ui_kit` | ✅ Var | Heç bir feature-i (yalnız Flutter) | Tema, paylaşılan widget-lər, formatlaşdırıcılar |
| `feature_*` | ✅ Var | `domain`, `ui_kit` — digər feature-i YOX | Bir feature-in notifier-ləri və ekranları |
| `app` | ✅ Var | Hamısını | Giriş nöqtəsi, DI qrafı, routing, flavor-lar |
Paket qrafının qaydası. Ən vacib qərar: feature paketləri bir-birini import etmir. Əks halda paket bölgüsü faydasını itirir — feature_orders → feature_catalog → feature_orders zənciri yaranır və heç bir paket müstəqil build olunmur.
Feature-lər arasında əlaqə iki yolla qurulur:
- Paylaşılan məlumat →
domain+datapaketləri vasitəsilə.feature_ordersvəfeature_cataloghər ikisiProductRepository-ni işlədir. - Naviqasiya →
apppaketində. Feature yalnız "bu id ilə məhsul ekranına keç" niyyətini bildirir; marşrutlarıappbilir.
Bölgü strategiyası: tədricən. Bütün layihəni bir dəfəyə paketlərə bölmək lazım deyil. Adətən ən faydalı ardıcıllıq:
1. `domain` — ən çox qazanc verən addım: qat qaydası kompilyator səviyyəsində qorunur və testlər dart test ilə işləyir.
2. `ui_kit` — tema və paylaşılan widget-lər; ikinci tətbiq (tablet, admin) gələndə dərhal işə yarayır.
3. `data` — service-lər və repository implementasiyaları.
4. *`feature_`** — yalnız komanda sərhədləri yarandıqda.
Kod generasiyası barədə praktik qeyd. Paketlərə bölündükdən sonra build_runner hər paketdə ayrıca işlədilir. melos run generate bunu bir əmrlə edir, packageFilters: dependsOn: build_runner isə yalnız ehtiyacı olan paketləri seçir. Build vaxtı qazancı da buradan gəlir: yalnız dəyişən paket yenidən generasiya olunur.
Melos-un versiya nüansı. melos 7-ci versiyadan etibarən ayrı melos.yaml faylını işlətmir: konfiqurasiya root pubspec.yaml-ında melos açarı altında yaşayır, paketlərin yeri isə workspace açarında göstərilir (Pub workspace mexanizmi, Dart SDK 3.6.0+ tələb edir). İnternetdə tapdığın köhnə nümunələr melos.yaml göstərirsə, onlar 6.x və əvvəlki versiyalar üçündür.
Praktika (opsional — yalnız siqnallar varsa). Layihəndən domain qatını ayrı pakete çıxar:
1. packages/domain/ qovluğu yarat, pubspec.yaml-ında `flutter:` bölməsi olmadan.
2. lib/domain/* fayllarını oraya köçür (git mv).
3. Əsas pubspec.yaml-a domain: {path: packages/domain} əlavə et və import-ları düzəlt.
4. cd packages/domain && dart test işlət — Flutter olmadan işləməlidir.
Hazır sayılır: packages/domain/lib altında package:flutter import-u yazmağa cəhd etdikdə analizator xəta verir (bunu bir dəfə sınayıb geri qaytar), və domain testləri dart test ilə işləyir.
📚 Mənbələr və sənədlər
- melos paketirəsmipub.dev
`bootstrap`, `run`, `exec`, `version`, `publish` əmrləri və 7+ versiyada `pubspec.yaml`-daki konfiqurasiya.
- Dart: paketlər yaratmaqrəsmidart.dev
Paketin strukturu, `pubspec.yaml` və `lib/src/` konvensiyası.
- Dart: Pub workspaces (monorepo)rəsmidart.dev
`workspace` və `resolution: workspace` açarları — melos 7+ bunun üzərində işləyir.
- Case study: strukturun icmalırəsmidocs.flutter.dev
Müqayisə üçün: rəsmi nümunə tək paketdir və qovluq bölgüsü ilə kifayətlənir.