Flutter — Создание идеального проекта Boilerplate с нуля

Предоставлено: Нгуен Тхань Минь (разработчик Android)
Мы все были в этом — я имею в виду, что мы все пытались создать шаблонный проект либо для работы, либо в качестве личного проекта. Хороший шаблонный проект сэкономит нам много времени, решив общие проблемы, такие как вызов API, обработка данных из баз данных и, возможно, самое главное — сделает наш код организованным и согласованным, чтобы людям было легче пытаться понять наш код. Эта серия предназначена для того, чтобы поделиться шаблонным проектом, который я создал, использовал и поддерживал в течение последних двух лет. Мало того, я поделюсь своим подходом к кодированию, а также решениями общих проблем, которые могут возникнуть. С учетом сказанного, это часть 1: Изучение проекта.
Посмотреть на Гитхабе

1. Особенности
Особенности, встроенные в этот проект:
- Архитектура: чистая архитектура
- Управление состоянием: flutter_bloc
- Навигация: auto_route
- DI: get_it , инъекционный
- REST API: дио
- GraphQL: артемида , graphql_flutter
- База данных: объектбокс
- Общие настройки: protected_shared_preferences
- Класс данных: заморожен
- Линт: dart_code_metrics , flutter_lints
- CI/CD: действия Github, конвейеры Bitbucket
- Модульный тест: mocktail , block_test
- Пейджинг: бесконечный_scroll_pagination
- Утилиты: rxdart , dartx , асинхронный
- Генератор ассетов: flutter_gen_runner , flutter_launcher_icons , flutter_native_splash
- Другие функции: автоматический повтор неудачных запросов API, токен обновления,…
Чтобы запустить этот проект по назначению, ваша версия Flutter должна быть (точно) 3.3.9, а версия Melos 2.8.0 должна быть установлена. Если вы хотите организовать Git Convention для своей команды, вы также можете установить lefthook . Я расскажу о Мелосе и Лефтхуке в более поздних частях серии. На данный момент, вот как запустить проект.
Примечание. Я использовал VSCode и macOS, поэтому не могу гарантировать, что он будет работать на Android Studio или Windows.
2.1. Установка Мелос
Чистая архитектура требует от нас разделения проекта на несколько модулей (пакетов), поэтому нам нужен инструмент для управления пакетами — Melos. Чтобы установить Мелос:
dart pub global activate melos 2.8.0
export PATH="$PATH:<path to flutter>/flutter/bin"
export PATH="$PATH:<path to flutter>/flutter/bin/cache/dart-sdk/bin"
export PATH="$PATH:~/.pub-cache/bin"
После установки Melos вам нужно будет запустить команду make gen_env
или dart run tools/gen_env.dart
. Это инструмент, который я создал сам, чтобы создать env
папку, чтобы мы могли объявлять секреты, такие как Google API_KEY, основные учетные данные аутентификации и т. д. Этот инструмент будет считывать значения в .env
файле, а затем помещать их в dart-define
флаг, когда приложение Flutter запустить или построить.

2.3. Создание файлов
Когда у нас есть env
папка, нам нужно только запустить команду make sync
. Это сокращение для трех команд:
melos bootstrap
melos run l10n
melos run force_build_all
Далее команда melos run l10n
помогает сгенерировать класс S
из .arb
файлов в resources
модулях.

Наконец, команда melos run force_build_all
помогает генерировать файлы .g.dart
, .freezed.dart
и т. д. для всех пакетов, содержащих библиотеку build_runner
.
Теперь бегите, make run_dev
чтобы запустить приложение и наслаждайтесь!
3. Архитектура проекта
Всего у нас 6 модулей (пакетов)
- Приложение
- Домен
- Данные
- Ресурсы
- Общий
- Инициализатор
3.1. Модуль приложения
Здесь мы будем кодировать наш пользовательский интерфейс и блок. Кроме того, здесь мы будем хранить наши ресурсы, такие как цвета, размеры и стили текста. Здесь мы также объявим нашу функцию main() в качестве точки входа для запуска нашего приложения.

Обе папки app_icon
и splash
содержат файлы, app-icon.yaml
поэтому splash.yaml
мы можем настроить значок приложения и заставку в соответствии с инструкциями библиотек flutter_launcher_icons и flutter_native_splash .
Папка app
содержит AppBloc
, который является блоком, представленным в MaterialApp
, место, откуда все экраны в приложении могут получать данные, другими словами; это похоже на блок, доступный для всех экранов. Вы можете использовать AppBloc
для задач, требующих обновления пользовательского интерфейса всех экранов, таких как настройка языка, переключение темного/светлого режима.
В этой base
папке мы будем кодировать базовые классы, такие как BasePageState
, BaseBloc
и BaseEvent
.BaseState
В этой папке shared_view
я буду кодировать пользовательский интерфейс, общий для многих экранов, и затем его можно будет использовать для других проектов. Например: app_text_field
, circle_image
— это общие групповые представления, отображаемые на экранах входа и регистрации.
В этой папке common_view
я буду кодировать пользовательский интерфейс, общий для многих экранов, и затем его можно будет использовать для других проектов. Например, common_dialog
, common_app_bar
, common_scaffold
можно повторно использовать во многих проектах, хотя мы можем немного изменить их для соответствия стилю.
В этой папке config
я буду вызывать функции конфигурации для модуля приложения, напримерFirebase.initializeApp()
Папка di
предназначена для настройки DI для модуля приложения.
Папка exception_handler
позаботится обо всех исключениях в проекте.
Папка helper
содержит вспомогательные классы, используемые исключительно для модуля приложения.
В этой папке navigation
мы будем объявлять экраны, а также диалоги и нижние листы, используемые в приложении.
В этой папке resource
мы объявим ресурсы для пользовательского интерфейса, такие как цвета, размеры и стили текста.
В папке ui
я буду кодировать пользовательский интерфейс и блок для каждого экрана.
В этой папке utils
я буду кодировать функции utils, используемые исключительно для модуля приложения.
3.2. Модуль домена

Подобно модулю приложения, папки config
и di
служат для аналогичных целей в модуле домена.
Папка entity
содержит объекты класса, такие как Пользователь и Бронирование.
В папке navigation
есть AppNavigator
класс, отвечающий за push
, replace
, и pop
экраны.
В этой папке repository
мы будем объявлять классы Abstract Repository в проекте.
В этой папке usecase
мы будем объявлять варианты использования в проекте.
3.3. Модуль данных

Точно так же папки config
и di
служат здесь той же цели.
Папка graphql
содержит .graphql
и schema.graphql
если ваш проект использует GraphQL. Файл build.yaml
используется для настройки сгенерированных файлов, связанных с GraphQL.
Папка repository
содержит классы реализации репозитория. Он также содержит несколько папок:
converter
: для кодирования классов Convertermapper
: для кодирования классов Mapper, которые затем используются для сопоставления моделей данных с объектами.model
: для кодирования классов модели данныхsource
: для кодирования базовых классов, таких как RestApiClient, GraphQlApiClient, а также для предоставления источников данных в проекте, таких как AppApiService, AppDatabase, AppSharedPreferences, LocationDataSource.

Это простой модуль, он содержит только .arb
файлы, которые предоставляют строки для локализации. Этот модуль внедряется в два других модуля, app
поэтому domain
его могут использовать классы UI, Bloc, Entity и Use Case.
3.5. Общий модуль

Как следует из названия, этот модуль предоставляет константы, настраиваемые классы исключений, вспомогательные классы, примеси и служебные функции для использования другими модулями.
3.6. Модуль инициализатора

Этот модуль содержит только класс AppInitializer. Этот класс отвечает за сбор всех конфигов из других модулей в init()
функцию; Функция main()
должна вызвать эту init()
функцию только для получения всех конфигураций из всех модулей.
3.7. Другие папки и файлы
Папка .github
предназначена для настройки CI/CD, если ваш проект использует Github Actions.
Папка .lefthook
и файл lefthook.yml
предназначены для настройки соглашения Git с использованием библиотеки lefthook.
Папка .vscode
предназначена для объявления настроек VSCode, используемых для этого проекта.
Папка .env
предназначена для объявления секретов для каждой среды.
Папка tools
содержит инструменты, которые я создал.
Файл analysis_options.yaml
предназначен для объявления правил линтера двух библиотек flutter_lints и dart_code_metrics .
Файл bitbucket-pipelines.yml
предназначен для настройки CI, если ваш проект использует конвейеры Bitbucket.
Файл makefile
отслеживает все команды, используемые в проекте. Например, команда make format
помогает отформатировать весь код с .dart
расширением файла в проекте. Есть еще много команд, например make test
, запускающих Unit Test на всех модулях.
Файл melos.yaml
предназначен для настройки Melos.
Вывод
Зачем нам нужно создавать еще один модуль только для конфигурации инициализации? Что такое классы сопоставления, сущностей и вариантов использования? Я расскажу об этом во второй части этой серии — «Чистая архитектура».