Site icon AppTractor

Что не так с Flutter?

Я пишу приложения на Flutter с 2019 года. И вначале я был настроен очень оптимистично. Только представьте — мне не нужно было писать два приложения на двух разных языках, чтобы сделать один продукт! Раньше я пробовал React Native и Xamarin, но они не удовлетворили мои потребности. Flutter удовлетворил.

Что мне больше всего понравилось во Flutter, так это то, что вы можете интегрировать нативный код в свои проекты. Любое количество нативного кода. У некоторых библиотек нет Flutter-версий, так что это действительно полезная функция. В большинстве моих проектов были функции, написанные на Swift и Kotlin. Это дает потенциально безграничные возможности разработчикам Flutter. С другой стороны, существует множество (действительно много) библиотек, как уникальных библиотек для Flutter, так и оболочек для нативных iOS, Android и веб-библиотек.

Что пошло не так?

Все вышеперечисленное прекрасно, когда вы делаете небольшой проект с 5–10 зависимостями. Не без проблем, но все же можно поддерживать проект с 10–15 зависимостями. Когда больше 15, становится очень сложно.

Библиотеки зависят друг от друга. И от самой версии Flutter. В большинстве проектов используется некоторое количество основных библиотек — например http, intl, sprintf, provider и другие.

Но разные другие библиотеки зависят от некоторых конкретных версий этих библиотек или, чаще, от диапазонов версий. Скажем, библиотека A зависит от версии 0.17.0 библиотеки intl (или выше), библиотека B зависит от версий 0.16.0, 0.16.1 и любой другой совместимой с ней версии до 0.17.0, но не включая ее. Это типичная проблема зависимостей.

Есть несколько возможных решений.

Корректировка версии библиотеки

Версии имеют не только зависимости, но и библиотеки. Если библиотека A версии 1.2.3 зависит от intl версии 0.17.0, существует вероятность, что библиотека A версии 1.2.1 (или 1.1.0) зависит от более ранней версии intl, что позволяет разрешить зависимость и получить компилируемый проект. Наличие более 10 зависимостей делает этот вариант не очень реалистичным.

Замена библиотек

Если библиотека B не получает регулярных обновлений, возможно, вы найдете библиотеку C, которая более современная и зависит от intl версии 0.17.0, как и библиотека A. Или она может вообще не зависеть от нее. Flutter обычно предлагает множество решений для каждой проблемы, так что на самом деле может быть решение и для этого.

Принудительное разрешение версии

Если версия библиотеки не может быть определена (см. ситуацию выше), мы можем заставить Flutter использовать определенную версию. Обычно библиотеки не сильно меняются от версии к версии. И если ваши зависимости используют их, они могут использовать одну или две функции, которые изначально никогда не менялись. В этом случае вы можете добавить раздел dependency_overrides в свой pubspec.yaml. Например:

dependency_overrides:
 path_provider: '2.0.0'
 http: '0.13.0'

Это гарантирует разрешение зависимостей, но ваше приложение может упасть при выполнении или вообще не собраться. Если библиотека A зависит от некоторой функции из библиотеки B, и эта функция была удалена из новой версии, библиотека A не будет работать должным образом.

Форк библиотеки

Более сложный способ решить проблему — создать форк библиотеки для вашего собственного аккаунта GitHub. Как это работает:

  1. Сделайте форк библиотеки, которая содержит зависимость от старой библиотеки.
  2. Внесите необходимые изменения. Обновите зависимости и исправьте ошибки в исходном коде.
  3. Измените pubspec.yaml, чтобы он ссылался на вашу собственную версию библиотеки. Вот так:
    flutter_qr_bar_scanner: git: url: git://github.com/Sadoge/flutter_qr_bar_scanner.git ref: master

Прежде чем делать это, проверьте, не сделали ли это уже за вас другие люди. Пример выше — один из таких случаев.

Есть простое решение?

Нет, простого решения нет. И еще одна проблема возникла недавно из-за самого Flutter. После обновления до версии 2 они изменили некоторые внутренние функции.

Например, некоторые библиотеки не могут скомпилироваться, потому что им нужна функция под названием ancestorWidgetOfExactType, но ее нет в новой версии Flutter. Вам нужно изменить его на findAncestorWidgetOfExactType. На вид нет большой разницы, но ваш проект не скомпилируется. Вам нужно изменить библиотеку, которая заблокирована (и не может быть изменена). Вы можете разблокировать ее, но в любой момент Flutter может обновить код, и вам нужно будет снова вносить эти изменения.

Что тогда делать?

Как я сказал ранее, нет хорошего и простого решения. Но есть несколько советов, которые помогут избежать подобных ситуаций.

  1. Не создавайте действительно больших проектов на Flutter. Или, по крайней мере, не делайте их полностью на Flutter. Если вы видите, что количество ваших зависимостей достигает 15–20, подумайте о том, чтобы что-то изменить.
  2. Используйте только библиотеки с регулярными обновлениями и хорошим рейтингом на pub.dev. Это гарантирует вам, что они будут обновляться синхронно с Flutter и друг с другом.
  3. Если вы видите только одну библиотеку на pub.dev, которая делает то, что вам нужно, постарайтесь не использовать ее. Вы будете слишком сильно зависеть от этой библиотеки, и если что-то пойдет не так, вам потребуются большие изменения в вашем проекте.
  4. Используйте популярные библиотеки и библиотеки, рекомендованные командой Flutter. Например, intl, provider, cupertino_icons и другие. Они всегда будут в актуальном состоянии.

Все так плохо?

Нет. Если вы планируете использовать Flutter и, прочитав о проблеме с зависимостями, собираетесь передумать, не спешите. На мой взгляд, Flutter по-прежнему остается лучшим кроссплатформенным фреймворком. В нем огромное количество библиотек, и со временем вы научитесь правильно им пользоваться.

P.S. Я получил много комментариев, в которых говорилось, что на всех платформах есть похожие проблемы, и это не конкретная проблема Flutter. Согласен, но лишь отчасти.

Я в основном нативный разработчик, и я столкнулся с аналогичными проблемами с Cocoapods и Gradle. Библиотеки iOS, использующие Swift 2 или 3, не компилируются с новым Xcode, поэтому их нельзя использовать. Google пришлось перейти с библиотек поддержки Android на AndroidX, чтобы избежать множественных конфликтов. Так что да, это проблема всех платформ.

Но Flutter развивается очень быстро, и недавний переход на версию 2.0 разделил все библиотеки на две группы: null-safe и не null-safe. Это повысило уровень несовместимости между зависимостями.

Кроме того, Flutter требует внешних зависимостей почти для всего. Такие библиотеки, как intl, sprintf или provider, обычно являются частью SDK стандартной платформы, но во Flutter они являются внешними и также вызывают конфликты версий. Как я уже говорил, в большинстве случаев это решаемо.

Я хотел бы закончить это цитатой из комментария Florian DUHEN:

Я следую двум простым правилам для своих рабочих приложений:

  • Использую только важные библиотеки (например, не внедряю библиотеку, полную модных диалогов, если использую только одну из многих реализаций).
  • Обращаю внимание на Pub Points и популярность.

Надеюсь, это поможет 😉

Источник

Exit mobile version