Wzorce programowania we Flutterze
ENProgramowanie we Flutterze z Claude Code, Codeksem lub Cursorem daje weryfikowalny kod, gdy agent startuje z trzech przypiętych faktów: wersji pakietów (Riverpod 3 z generowaniem kodu, go_router, Dio, freezed), reguł architektury i jednej komendy sprawdzającej. Plugin zespołu Fluttera i serwer MCP Darta weryfikują wtedy każdą zmianę analizą, generowaniem kodu i testami.
Ta strona jest dla programistów i tech leadów, którzy wydają aplikację we Flutterze z pomocą agenta. Prosisz o provider i dostajesz StateNotifierProvider, który Riverpod 3 przeniósł do importu legacy.dart. Prosisz o interceptor Dio z ponawianiem, a jeden niedziałający ekran wysyła teraz dziesiątki żądań, bo Riverpod 3 sam ponawia providery, które zwróciły błąd. Żadnego z tych błędów nie zauważysz, przeglądając diff pobieżnie.
Co zyskasz dzięki wzorcom programowania we Flutterze
Dział zatytułowany „Co zyskasz dzięki wzorcom programowania we Flutterze”- Plugin agenta od zespołu Fluttera (skille plus serwer MCP Darta), zainstalowany w każdym narzędziu
- Blok
AGENTS.md, który przypina stos i komendę sprawdzającą, więc każda sesja je dziedziczy - Prompty do skopiowania: provider Riverpod z generowaniem kodu, przekierowanie autoryzacji w go_router bez pętli, serwis Dio z typowanymi błędami i testy widgetów
- Mechaniczne kontrole do każdego przepisu (strażniki
rg,build_runner --only-check, testy tabelaryczne), które zastępują czytanie wygenerowanego kodu - Mapę awarii: dryf
build_runner, podwójne ponawianie, minimalna wersja SDK dla go_router, błędy Gradle i CocoaPods oraz niestabilne testy golden
Jakie wersje pakietów Fluttera zakłada ta strona?
Dział zatytułowany „Jakie wersje pakietów Fluttera zakłada ta strona?”Dane treningowe agenta obejmują kilka głównych wersji każdego pakietu z tabeli, a każda z nich zmieniła API, którego agent chętnie używa. Podaj wersje w prompcie i w AGENTS.md. Tabela pokazuje, co serwował pub.dev 2026-09-26.
| Pakiet | Wersja | Na czym agent się myli |
|---|---|---|
flutter_riverpod | 3.4.3 (wymaga Darta ^3.12) | StateNotifierProvider, StateProvider i ChangeNotifierProvider są w package:flutter_riverpod/legacy.dart. Providery z błędem są ponawiane automatycznie. |
riverpod_annotation / riverpod_generator | 4.0.7 / 4.0.9 | Główna wersja generatora (4) różni się od wersji runtime’u (3). Trzymaj adnotacje i generator na tej samej głównej wersji. Providery przyjmują zwykły Ref; generowane podklasy w stylu UserProfileRef zniknęły. |
riverpod_lint | 3.1.9 (wymaga Darta 3.13) | Oparty na analysis_server_plugin, nie na custom_lint. Konfiguruj go według jego README, nie według przepisu z custom_lint ze starszego artykułu. |
go_router | 18.0.1 | 18.0.0 wymaga Fluttera 3.44 / Darta 3.12. Na starszym Flutterze przypnij ^17.5.0. Od 15.0.0 adresy URL rozróżniają wielkość liter. |
dio | 5.11.1 | Stabilne API 5.x: InterceptorsWrapper, DioException. |
freezed | 4.0.2 (wymaga Darta 3.13) | 4.0.0 nie akceptuje już final w parametrach konstruktora. Klasy muszą być sealed albo abstract (od 3.0). |
build_runner | 2.16.1 | Domyślnie poprawia nieaktualne wygenerowane pliki. --delete-conflicting-outputs to usunięta flaga, ignorowana z ostrzeżeniem. --only-check przerywa build, gdy pliki na dysku różnią się od tego, co zapisałby generator. |
Niech agent dodaje pakiety przez flutter pub add <pakiet>, które dobiera wersję zgodną z twoim SDK, zamiast wpisywać numery wersji do pubspec.yaml.
Zainstaluj plugin agenta od zespołu Fluttera i serwer MCP Darta
Dział zatytułowany „Zainstaluj plugin agenta od zespołu Fluttera i serwer MCP Darta”Zespół Fluttera publikuje flutter/agent-plugins, repozytorium przemianowane z flutter/skills. Jego plugin dart-flutter (1.0.6 na 2026-09-26) zawiera 25 skilli, 10 dla Fluttera i 15 dla Darta, na przykład flutter-add-widget-test, flutter-fix-layout-issues i dart-resolve-package-conflicts. Rejestruje też serwer MCP Darta (dart mcp-server, dostarczany z Dart SDK). Zespół Darta publikuje swoje skille także w dart-lang/skills.
# Marketplace and plugin are both named dart-flutterclaude plugin marketplace add flutter/agent-pluginsclaude plugin install dart-flutter@dart-flutterAby dodać tylko serwer MCP, uruchom claude mcp add dart -- dart mcp-server. Otwórz /mcp w sesji, aby sprawdzić, czy serwer się połączył.
# The repository ships a Codex marketplace named dart-fluttercodex plugin marketplace add flutter/agent-pluginscodex plugin add dart-flutter@dart-flutterAby dodać tylko serwer MCP, uruchom codex mcp add dart -- dart mcp-server.
Repozytorium zawiera też manifest pluginu Cursora (.cursor-plugin/plugin.json); opisana niżej ścieżka przez CLI skills działa bez niego.
Zainstaluj skille przez CLI skills, które obsługuje wielu agentów (wersja 1.7.0 na npm); zapisuje je w .agents/skills:
npx skills@latest add flutter/agent-plugins --skill '*' --agent universal --yesPotem dodaj serwer MCP Darta do .cursor/mcp.json:
{ "mcpServers": { "dart": { "command": "dart", "args": ["mcp-server"] } }}To serwer MCP zmienia pętlę pracy. Bez niego agent pisze widget i liczy na szczęście. Z nim może wywołać analyze_files, odczytać get_runtime_errors z działającej aplikacji, uruchomić hot_reload i przejść drzewo widgetów przez widget_inspector (nazwy narzędzi z README dart-lang/ai, odczytane 2026-09-26). Serwer wymaga Darta 3.9 lub nowszego. Do działającej aplikacji dociera przez Dart Tooling Daemon, który flutter run uruchamia w trybie debug i profile.
Porównanie skilli i serwerów MCP znajdziesz w artykułach jak instalować skille i nimi zarządzać oraz oficjalne skille dostawców.
Przypnij stos Fluttera w AGENTS.md
Dział zatytułowany „Przypnij stos Fluttera w AGENTS.md”Prompt przypina stos na jedną sesję. Plik z instrukcjami projektu przypina go dla każdej sesji. Codex czyta AGENTS.md, a Claude Code czyta go, gdy repozytorium nie ma CLAUDE.md (od v2.1.277, oba kanały wydań, stan na 2026-10-12). Jeśli masz CLAUDE.md, wstaw tam ten sam blok. W Cursorze umieść ten sam blok w regule projektu (Cursor Rules). Skopiuj go i dostosuj wersje.
## Flutter stack (do not substitute)- Flutter 3.47+, Dart 3.13+. Add packages with `flutter pub add`, never by typing versions.- State: Riverpod 3 with code generation (`@riverpod`, `part '*.g.dart';`). Never import `package:flutter_riverpod/legacy.dart`. No StateNotifier, no get_it.- Navigation: go_router 18 with one `GoRouter` provided through Riverpod.- Networking: Dio behind `ApiService`. Map every `DioException` to the sealed `ApiFailure`.- Models: freezed 4 (`sealed` or `abstract` classes). No hand-written fromJson.- Layout: lib/features/<feature>/{data,domain,presentation}. domain/ imports no Flutter and no Dio.
## Check command (run before you say a task is done)dart run build_runner build && dart format --output=none --set-exit-if-changed . \ && flutter analyze && flutter testOstatnia linia to umowa. Agent, który zgłasza „gotowe” bez zielonej komendy sprawdzającej, nie skończył, i możesz go z tego rozliczyć bez otwierania choćby jednego pliku.
Uruchom prompt w narzędziu, którego używasz. W Claude Code podaj go jako pierwszy argument (claude "…"). W Codeksie tak samo (codex "…"); sesja pyta o zgodę przed komendami, które jej wymagają. W Cursorze wklej go do czatu agenta. Każde narzędzie stosuje blok tylko z pliku, który czyta. Gdy zmieniasz stos, zaktualizuj każdą kopię bloku w tym samym commicie.
Napisz provider Riverpod z generowaniem kodu
Dział zatytułowany „Napisz provider Riverpod z generowaniem kodu”Zaletą @riverpod jest to, że ładowanie, cache i parametry stają się deklaratywne. Ryzykiem jest to, że agent domiesza klasy providerów w starym stylu ze swoich danych treningowych.
Sprawdź wynik mechanicznie zamiast go czytać:
# Must print nothing: legacy providers or pre-3.0 generated refsrg -n "flutter_riverpod/legacy.dart|StateNotifier|ProviderRef\b|FutureProviderRef" lib# Generated files must match what the generator writesdart run build_runner build --only-checkLinia z --only-check ma znaczenie tylko wtedy, gdy commitujesz pliki .g.dart i .freezed.dart. Jeśli je commitujesz, wyłapuje agenta, który ręcznie zmienił wygenerowany plik albo zapomniał ponownie uruchomić generator.
Zbuduj przekierowanie autoryzacji w go_router, które nie może się zapętlić
Dział zatytułowany „Zbuduj przekierowanie autoryzacji w go_router, które nie może się zapętlić”Klasyczny błąd w go_router to nieskończone przekierowanie: strażnik odsyła niezalogowanych do /login, ale zapomina przepuścić samo /login. Naprawa to jedna klauzula, i to ją agent pomija najczęściej. Nie polegaj na tym, że wypatrzysz ją w kodzie. Zrób z przekierowania czystą funkcję i ją przetestuj.
Test tabelaryczny jest kryterium akceptacji. Jeśli obejmuje każdą parę statusu i trasy i przechodzi, przekierowanie nie może się zapętlić, niezależnie od tego, jak wygląda implementacja. Wiersz z /LOGIN jest ważny, bo od wersji 15.0.0 adresy w go_router rozróżniają wielkość liter.
Zbuduj serwis API na Dio z typowanymi błędami i jedną warstwą ponawiania
Dział zatytułowany „Zbuduj serwis API na Dio z typowanymi błędami i jedną warstwą ponawiania”Podstawowa ścieżka serwisu Dio jest prosta. O gotowości produkcyjnej decydują trzy rzeczy: odświeżenie tokenu po 401 z ponowieniem żądania, typowany błąd i miejsce, w którym zachodzi ponawianie.
Riverpod 3 domyślnie ponawia provider, który zwrócił błąd. W riverpod 3.4.3 ProviderContainer.defaultRetry pozwala na maksymalnie 10 ponowień, od 200 ms z podwajaniem do limitu 6,4 s, dla każdego błędu, który nie jest Error ani ProviderException. ApiFailure nie jest żadnym z nich. Dodaj interceptor Dio, który ponawia trzy razy, a jeden niedziałający ekran może wysłać dziesiątki żądań. Wybierz jedną warstwę do ponawiania.
Trzy testy dowodzą zachowania, które ma znaczenie. Dołóż do nich jeden mechaniczny strażnik: rg -n "rethrow|throw e\b" lib/core/network nie powinno nic wypisać, gdy każdy DioException jest już zmapowany. Kontrakt API po stronie serwera opisują wzorce tworzenia API.
Pilnuj warstw czystej architektury kontrolą, nie lekturą
Dział zatytułowany „Pilnuj warstw czystej architektury kontrolą, nie lekturą”W większej aplikacji proś o konkretną funkcję, nie o „ustawienie czystej architektury”. Liczy się jedno ograniczenie: domain nie importuje ani Fluttera, ani Dio. Przeciekający package:flutter/material.dart w przypadku użycia oznacza, że warstwy są tylko dekoracją, a grep znajdzie go szybciej niż recenzent.
Dodaj regułę warstw do CI, aby przetrwała kolejne sto edycji agenta. Krok przechodzi tylko wtedy, gdy rg nic nie znajdzie (kod wyjścia 1); trafienie (kod 0) albo błąd rg, na przykład brak katalogu (kod 2), go przerywa, a forma || rc=$? działa także w powłoce bash -e, której używają runnery CI:
rc=0rg -n 'package:(flutter|dio)/' lib/features --glob '**/domain/**' || rc=$?test "$rc" -eq 1Weryfikuj każdą zmianę we Flutterze bez czytania każdej linii
Dział zatytułowany „Weryfikuj każdą zmianę we Flutterze bez czytania każdej linii”Komenda sprawdzająca z AGENTS.md to pętla wewnętrzna. Pull request potrzebuje bramki, która uruchamia te same kontrole oraz te zbyt wolne na każdą edycję. Kolejność poniżej zaczyna od najtańszych, więc błąd kosztuje jak najmniej czasu CI.
- Wygenerowany kod jest aktualny.
dart run build_runner build --only-check(jeśli commitujesz wygenerowane pliki), w przeciwnym raziedart run build_runner build. - Formatowanie i analiza statyczna.
dart format --output=none --set-exit-if-changed .orazflutter analyze. Traktuj uwagiriverpod_lintjak błędy. - Kontrole strażnicze. Strażniki
rgdla importów Riverpod legacy i importów w warstwie domain z poprzednich sekcji. - Testy jednostkowe i widgetów.
flutter test, łącznie z tabelą przekierowań i testami Dio. - Testy golden na jednym systemie. Testy golden uruchamiasz przez
flutter testna linuksowym obrazie CI i porównujesz z zacommitowanymi obrazami. Generuj je ponownie przezflutter test --update-goldenstylko na tym obrazie, w osobnym commicie. - Testy integracyjne na urządzeniu.
flutter test integration_testna emulatorze dla przepływów, które dotykają pluginów, takich jak logowanie i płatność. Farmy urządzeń i triage niestabilnych testów opisuje strona wzorce testowania aplikacji mobilnych.
Kto zatwierdza: recenzent pull requesta sprawdza, że bramka jest zielona, a testy odpowiadają kryteriom akceptacji z zadania, takim jak tabela przekierowań i trzy przypadki Dio. Ludzka lektura trafia do tych testów i do warstwy domain, nie do wygenerowanego kodu ani do szablonowych widgetów. Sam proces opisuje artykuł code review PR-a agenta bez czytania każdej linii.
Jeśli agent ma sam napisać zadanie CI, najpierw podłącz serwer MCP GitHuba, aby czytał twoje prawdziwe workflowy i nazwy sekretów, zamiast je wymyślać. Konfigurację dla każdego narzędzia opisuje przewodnik po serwerze MCP GitHuba, a strukturę zadania wzorce potoków CI/CD. Przy awariach na produkcji serwer MCP do obserwowalności, na przykład serwer Sentry, pozwala agentowi odczytać prawdziwy stack trace dla wydania, zanim zaproponuje poprawkę.
Co się psuje, gdy agenci piszą kod we Flutterze?
Dział zatytułowany „Co się psuje, gdy agenci piszą kod we Flutterze?”- Dryf
build_runner. Objawy: provider, który „nie istnieje”, nieaktualny.g.dartalbo błąd typu w wygenerowanym kodzie. Wyjście: uruchomdart run build_runner clean, a potemdart run build_runner build. Flaga--delete-conflicting-outputswbuild_runner2.16.1 nic już nie robi, więc agent, który ciągle ją dodaje, nie znalazł przyczyny. Wklej agentowi pierwszy błąd i zapytaj, która z trzech przyczyn zachodzi: brak dyrektywypart, mieszanie składni legacy z codegenem, czyriverpod_annotationiriverpod_generatorw różnych głównych wersjach. - Wraca Riverpod legacy. Objaw: strażnik
rgznajdujelegacy.dartalboStateNotifier. Wyjście: odrzuć zmianę i wklej do promptu jeden z istniejących providerów jako wzorzec stylu. Dopisz regułę doAGENTS.md, jeśli jej brakuje. - Niedziałający ekran zalewa API żądaniami. Objaw: logi pokazują ten sam GET wiele razy przy jednym otwarciu ekranu. Przyczyna: automatyczne ponawianie Riverpoda nałożone na interceptor Dio. Wyjście: przekaż do
ProviderScopefunkcjęretry, która zwracanulldlaApiFailure, jak w prompcie o Dio. - Testy oczekują surowego błędu. Objaw: test, który oczekuje
ApiFailurezref.readlubref.watch, przestaje przechodzić po aktualizacji do Riverpoda 3. Przyczyna: Riverpod 3 opakowuje ponownie rzucony błąd providera wProviderException. Wyjście: sprawdzaj stanAsyncValueprovidera albo rozpakuj wyjątek i powiedz agentowi, której konwencji używa twój zestaw testów. - freezed 4 rozwiązuje się jako 3.2.x. Objaw:
flutter pub add freezedwybiera freezed 3.2.5 i riverpod_lint 3.1.8, a kod agenta pisany pod freezed 4 się nie buduje. Przyczyna: freezed od 4.0.0 i riverpod_lint 3.1.9 wymagają Darta 3.13, który jest dostarczany z Flutterem 3.47. Wyjście: zaktualizuj Fluttera do 3.47+ w osobnej zmianie albo, na Darcie 3.12, wpisz wAGENTS.md„freezed 3”, aby agent celował w wersję, którą faktycznie dostaje. - go_router 18 się nie rozwiązuje. Objaw:
flutter pub getpada na ograniczeniu SDK. Przyczyna: 18.0.0 wymaga Fluttera 3.44 i Darta 3.12. Wyjście: przypnijgo_router: ^17.5.0do czasu aktualizacji Fluttera. Nie pozwól agentowi aktualizować Flutter SDK przy okazji zadania funkcjonalnego. - Błędy Gradle i CocoaPods. Awarie Androida po podbiciu zależności to zwykle niezgodność wersji Android Gradle Plugin, Gradle lub Kotlina. Awarie iOS to zwykle pod, który wymaga
pod repo updatealbo wyższego deployment target. Wyjście: wklej pełny log builda, poproś agenta o przypięcie konkretnych wersji pluginów i zabroń mu zmieniać wersję Flutter SDK, aby naprawić poda. - Goldeny przechodzą lokalnie i padają w CI. Przyczyna: macOS i Linux renderują fonty inaczej. Wyjście: generuj goldeny tylko na obrazie CI i ładuj dołączony font w
flutter_test_config.dart. - Agent nie widzi działającej aplikacji. Objaw: narzędzia MCP Darta, takie jak
get_runtime_errors, nic nie zwracają. Przyczyna: aplikacja działa w trybie release albo z--no-dds, więc żaden Dart Tooling Daemon nie jest zarejestrowany. Wyjście: uruchomflutter runw trybie debug i poproś agenta, aby połączył się z nią przez narzędziedtd.
Dokąd dalej z Flutterem
Dział zatytułowany „Dokąd dalej z Flutterem”- Przegląd programowania mobilnego, aby zobaczyć, jak strony o Flutterze, Expo i React Native dzielą się pracą
- Przepisy UI dla React Native i Fluttera z przepisami na poziomie widgetów, takimi jak własne biblioteki widgetów i design dopasowany do platformy
- Wzorce rozwoju Expo i wzorce rozwoju React Native, jeśli porównujesz stosy wieloplatformowe
- Przepisy dla natywnego iOS i Androida o kodzie platformowym za pluginem Fluttera
- Test-driven development z agentami, aby napisać test tabelaryczny, zanim agent napisze przekierowanie
Czy ten artykuł Ci pomógł?
Jedno kliknięcie, bez logowania.
Co z tym zrobisz?
Jak się czytało?
Co przeszkadzało? Możesz zaznaczyć kilka
Twoja rola?
Dzięki. Czytam każdą odpowiedź. Michał Jaskólski
Pomógł Ci ten artykuł?
Każde to jedno kliknięcie. Zamknij, kiedy chcesz.
bez logowania