Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Привет! Меня зовут Дарья, я Flutter-разработчик уровня Junior и это моя первая публикация на Хабре.
Знаете, создавать новый проект всегда приятно — новая кодовая база, отсутствие legacy (пока что), null-safety, свежие версии ваших любимых пакетов и далее, далее, далее.
Однако в начале проекта вы должны принять несколько важных решений: выбрать инструменты и пакеты для приложения, определить решение для управления состоянием, разработать план тестирования. В противном случае проект из красивой кареты превратится в тыкву.
Чтобы такого не произошло, делюсь с вами списком самых важных решений, которые вы должны принять перед началом проекта. Я надеюсь, что это вам поможет, поэтому — приятного чтения!
1. Статический анализ кода
Linter — это инструмент статического анализа. Он идентифицирует и помечает синтаксические ошибки, предупреждения и дефекты стиля в вашем коде. В контексте Flutter это самая простая вещь для реализации и одна из самых полезных для поддержания чистоты вашего кода.
Правила линтера вы можете установить сами, но я рекомендую использовать один из готовых пакетов, который уже следует лучшим практикам и руководству Dart Style Guide:
- lints;
- flutter_lints;
- surf_lint_rules;
- very_good_analysis.
Какой бы пакет вы ни выбрали, вы всегда можете добавить или удалить любое конкретное правило статического анализа в файле analysis_options.yaml.
2. Локализация
Локализация приложения – это его языковая и техническая адаптация для использования в конкретной стране или регионе.
Важно создать приложение, которое покажется естественным для пользователей и будет использовать правильный перевод, форматы валюты или даты, направление текста. Даже если вы создаете моноязычное приложение, я рекомендую вам внедрить локализацию на ранней стадии и отделить ваши тексты от кода пользовательского интерфейса. Следовательно, тексты могут быть повторно использованы, а также скорректированы позже, без влияния на сам код.
Документация Flutter изящно объясняет процесс интернационализации вашего приложения. Если способ по умолчанию кажется вам слишком сложным, используйте сторонние пакеты — например, easy_localization.
3. Контуры
Держу пари, вы слышали хотя бы об одном случае, когда разработчик повредил или удалил данные проекта. Поверьте мне — это не смешно.
Хорошей практикой является создание нескольких контуров для вашего проекта:
- Тестовый контур — используется для того, чтобы вы могли экспериментировать с кодом или изменять данные непосредственно в базе данных. Веселитесь и внедряйте фичи!
- Промежуточный контур (тестирование или подготовка) — помогает вам проверить изменения в коде, протестировать функции и проверить приложение перед его выпуском в продакшн.
- Продакшн-контур — используется реальными пользователями, здесь повреждение данных недопустимо (всегда делайте бэкапы, пожалуйста).
Все эти контуры помогают вам безопасно экспериментировать и проверять фичи до того, как эти изменения попадут в руки пользователей.
Теперь еще одна часть — flavors. Этот термин используется в программировании для описания различных вариантов сборки вашего приложения. Например: вы хотите, чтобы иконка, заголовок, конечная точка API или любая другая конфигурация отличались для каждой конкретной среды. Для этого вы определяете другой flavor, который используется при создании приложения для конкретной среды. Вот здесь больше информации об этом.
4. Continuous Integration и Continuous Delivery (CI/CD, Непрерывная интеграция/непрерывная доставка)
После того, как вы внедрили различные контуры, следующий шаг — автоматизация процесса создания, тестирования и выпуска приложения. CI/CD это довольно сложная тема сама по себе, и я ни в коем случае не эксперт в этой области. Поэтому я рекомендую поискать другие ресурсы о том, как автоматизировать различные этапы разработки приложений.
Тем не менее, есть NoOps решения, которые совместимы с Flutter и помогут вам автоматизировать процесс разработки:
- Appcircle;
- Codemagic;
- Bitrise;
- VS App Center (пока не имеет интеграции с Flutter, но есть некоторые ресурсы, которые могут помочь вам все настроить).
Все эти решения работоспособны — просто выберите тот, который соответствует вашим потребностям или бюджету.
5. Бэкэнд
У вас уже есть бэкэнд, реализованный на каком-нибудь экзотическом или, может быть, не очень модном языке программирования? Отлично, вы можете пропустить этот шаг, но я всё равно рекомендую вам проверить некоторые облачные решения.
Если упростить, есть два варианта бэкэнд-части вашего приложения:
- Реализация пользовательского бэкэнд-решения с использованием любого языка программирования и фреймворка, который вам нравится. Однако нужно учесть последующую работу, которой обычно занимается DevOps-инженер — автоматизацию технологических процессов сборки, настройки и деплоя программного обеспечения.
- Использование любого облачного решения для ускорения процесса разработки. В этом случае работу DevOps-инженера можно оставить на облачного провайдера.
Если второй вариант кажется вам привлекательным, есть парочка отличных облачных платформ, которые поддерживают Flutter:
- Google Firebase;
- AWS Amplify.
Облачные платформы предоставляют аутентификацию, базу данных, хранилище, опции API для вашего приложения и многие другие функции. Любой из них — отличный выбор, когда вам просто нужно проверить идею и быстро построить MVP, не тратя много времени на полномасштабное бэкэнд-решение.
6. Логгирование, данные о сбоях и аналитика
Логгирование недооценивают — всё кажется крутым, пока что-то не пойдет не так, и вам не понадобится узнать, что именно. Обсуждения о том, что следует добавлять в логи, а что нет, вечны. Но одно очевидно — вы должны знать, если ваше приложение выходит из строя и что вызывает проблему. Чем больше данных вы соберете об инциденте, тем легче будет найти и устранить проблему.
Такие сервисы, как Sentry, Firebase Crashlytics, Datadog могут помочь вам отследить наиболее важные данные, отчеты о сбоях или даже настроить уведомления о том, когда ваше приложение или связанные с ним службы не работают.
Другой тип логгинга — сбор пользовательских данных для аналитики. Когда вы создаете новый и, возможно, единственный в своем роде продукт, очень важно понимать потребности ваших пользователей, их поведение и то, как они используют приложение. Для этого в ваше приложение могут быть интегрированы различные инструменты анализа, такие как Firebase Analytics, App Center Analytics и многие другие.
7. Брендинг приложений
Одна из главных целей любого приложения или бренда — быть узнаваемым.
Использование правильной цветовой палитры, логотипа, иконок, элементов дизайна, контента, шрифта, а иногда даже макета выделяет ваш продукт среди других. Это брендинг, и подготовка основных частей в начале сэкономит вам много времени в течение всего проекта.
Если у вас уже есть готовый прототип пользовательского интерфейса или компоненты дизайна, сейчас самое время перенести их в приложение и определить тематику — цвета, шрифты, формы и другие. Чтобы сделать это проще, хороший парень Майк Ридстром создал для этого классный пакет — flex_color_scheme.
8. Структура проекта и управление состоянием
Да, пункт спорный. Просто чтобы прояснить — нет такой вещи, как «лучшее решение для управления состоянием» или «лучшая архитектура приложения» — если кто-то говорит иначе, помните, что это субъективно. Я не могу научить вас лучшему способу — я могу лишь поделиться своими предпочтениями.
Несколько вариантов файловой структуры для Flutter-проекта:
- Чистая архитектура — честно говоря, я не являюсь поклонником этого варианта. Мне кажется, что в этой концепции слишком много абстракции, которая может замедлить процесс разработки.
- Многоуровневая архитектура — основана на идее разделения логики данных, бизнеса и представления на отдельные слои. Такая файловая структура прекрасно работает для небольших и средних проектов, но мне кажется, что эти слои становятся все более и более объёмными, когда проект растет.
- Модульная архитектура — разделение кода на модули для каждой функции, где взаимодействуют разные модули. Это мое любимое решение — оно плавно работает с решением BLoC state-management. Хорошо масштабируется для больших проектов. Однако без проблем не обходится — нужно продумать, где разместить общую логику, как различные модули должны взаимодействовать и так далее.
О стейт-менеджменте во Flutter — я думаю, что мы подошли к тому моменту, когда могли бы посвятить этой теме всю конференцию и всё же не получить окончательного ответа. Просто выберите тот вариант, с которым вы чувствуете себя наиболее комфортно. Вы можете найти полный список вариантов здесь.
9. Генерация кода
Если вы хотите срезать некоторые углы и сэкономить время разработки, вы можете использовать генерацию кода в своем проекте.
Существует целый ряд различных инструментов для использования, будь то работа с локализациями, парсинг JSON, генерация классов моделей, реализация service locator, маршрутизация или работа с неизменяемыми состояниями. Единственное, что нужно сделать — изучить доступные инструменты и пакеты и выбрать лучшие из них для удовлетворения потребностей проекта.
Для быстрого запуска проекта на Flutter я рекомендую посмотреть на Very Good CLI. Это сэкономит вам несколько часов настройки. К сожалению, мне пришлось познать это на собственном горьком опыте.
10. Стратегия тестирования
Покрыть 100% вашего кода тестами — хорошо или плохо? Конечно, само по себе это потрясающе, но какой ценой достигается? Вы можете попасть в ситуацию, где будете тратить больше времени на написание тестов, чем на разработку функций. Чтобы избежать этого, вам нужна стратегия тестирования.
Пожалуйста, не поймите меня неправильно! Покрытие вашего кода тестами — отличная вещь, и чем больше темных мест вашего кода протестировано, тем безопаснее вы можете чувствовать себя при реализации новых функций. Просто, на мой взгляд, вы должны найти баланс, где тесты по-прежнему приносят вам больше пользы по сравнению со временем, потраченным на их написание. Делюсь своей стратегией тестирования:
- Бизнес-логика (сервисы, репозитории, блоки) должна быть покрыта тестами на 85-100% в модульных или интеграционных тестах — это самая важная часть любого приложения, поэтому здесь это оправдано;
- Тесты виджетов должны охватывать все повторно используемые компоненты UI. Когда отдельные компоненты протестированы должным образом, вы можете начать тестировать отдельные экраны, но менее подробно.
- End-to-end тесты охватывают основные потоки приложений и взаимодействия с UI. Никаких deep dark fantasies — просто прохождение некоторых важных рабочих процессов. Чем больше экранов они включают, тем лучше.
- Когда весь пользовательский интерфейс готов и реализован — golden tests гарантируют, что изменения не повлияют на UI в дальнейшем.
Честно говоря, я всё ещё ищу эту золотую середину в тестировании, но с каждом проектом вы становитесь опытнее, поверьте мне.
11. Файл README
Вы не ослышались — документация. Файл README — самый важный документ проекта, особенно при работе в команде.
Вы только что представили новое решение, требующее генерации кода? Вы только что добавили новый полезный скрипт для автоматизации процесса? Вы внедрили глобальное логгирование, которое ДОЛЖНО использоваться везде в проекте? Мы не можем читать ваши мысли — упомяните об этом в файле README!
Нет такого понятия, как слишком много документации (по крайней мере, у меня не было такой ситуации), только отсутствие информации о проекте и коде. Все команды для генерации, тестирования и запуска кода, различные решения файловой структуры, диаграммы, внешние инструменты и сервисы, информация о различных средах (БЕЗ СЕКРЕТНЫХ КЛЮЧЕЙ) должны быть помещены сюда и храниться в одном месте. Это скучная работа, но очень полезная!
В статье чего-то не хватает? Вы готовитесь к новому проекту по-другому? Напишите об этом в комментариях!