Flutter 3.47: что ломается на самом деле и что сделать до ноября
За лето вышел ровно один стабильный релиз Flutter. 3.45 и 3.46 до stable вообще
не добрались, а 3.47 приехал 12 августа с 1358 коммитами поверх 3.44. Главное в
нём — не фича. Это переупаковка: material и cupertino уехали из SDK в
отдельные пакеты.
Звучит тревожно, но по большей части это не так — сегодня. Вот что мы выяснили, мигрируя реальный проект с 3.44.0 на 3.47.2, и одно широко разошедшееся утверждение про этот релиз, которое не выдерживает столкновения с кодом.
Сегодня ничего не горит
Мы взяли живой проект, перевели его с 3.44.0 на 3.47.2 и запустили: flutter analyze чистый, тесты зелёные, библиотеки по-прежнему внутри SDK и не помечены
как deprecated. Депрекация назначена на ноябрьский релиз. Вот тогда часы и
пойдут.
Так что это хороший месяц для миграции и плохой месяц для паники. Окно существует ровно затем, чтобы миграция прошла скучно.
Миграция — одна команда, но с двумя ловушками
dart fix --apply --code=migrate_design_widgets
Ловушка первая: простой dart fix --apply этого не сделает. Фикса нет в
наборе по умолчанию; без --code=migrate_design_widgets команда отработает,
отрапортует об успехе и не изменит ничего по делу. Это тот тип отказа, который
читается как «уже мигрировано».
Ловушка вторая: она пишет material_ui: any в ваш pubspec. any значит,
что следующий ломающий релиз этого пакета приедет к вам в сборку молча. Замените
на каретку с версией сразу, как фикс отработает.
Утверждение, которое неверно: ChangeNotifier никуда не уехал
Самая часто повторяемая фраза про этот релиз — что ChangeNotifier и компанию
вынесли из SDK в package:listen. В 3.47.2 произошло не это.
Классы по-прежнему в SDK и не помечены как deprecated. listen — это вторая,
независимая реализация тех же имён, а не новый дом для старых. Это разные
типы, и компилятор относится к ним именно так:
- передайте
ValueNotifierизlistenво flutter'овскийValueListenableBuilder— и получите ошибку компиляции, а не тонкий баг в рантайме; - то же самое в обратную сторону и для любой другой пары с общим именем.
Где listen действительно к месту — код, в котором нет Flutter: сервер, CLI,
логика, общая для того и другого. Там типов из SDK никогда не было, а теперь есть
эквивалент. Внутри Flutter-приложения переход на него сегодня не даёт ничего и
стоит вам совместимости по типам с каждым виджетом, который ждёт версию из SDK.
Primary constructors сами не включатся
В Dart 3.13 приехали primary constructors, и они за флагом версии языка. Без
sdk: ^3.13.0 в pubspec.yaml вы получите experiment_not_enabled даже на
правильном SDK — тулчейн в порядке, это проект не просит.
Стоит, впрочем, сказать прямо: ценность экономии на бойлерплейте конструкторов сильно падает, когда этот бойлерплейт пишет не человек. Если ваши конструкторы генерируются, это изменение про читаемость, а не про продуктивность.
Остальное
Impeller по умолчанию на десктопе, iOS 15 и macOS 12 как новые нижние границы и работа над Wasm — всё реальное, ничего срочного, и ни на что из ваших дел в этом месяце не влияет.
Что реально сделать до ноября: прогнать миграцию в ветке, нормально
запинить material_ui и не трогать ChangeNotifier.
Проверено миграцией живого проекта с 3.44.0 на 3.47.2 — before/ и after/
собираются и проходят тесты каждый на своём SDK. Видеоразбор —
на YouTube.