environment: sdk: ">=2.12.0-0 <3.0.0"
dart create
),
содержащее код, как показано ниже. Затем можете попробовать
запустить приложение до и после изменения ограничения SDK и запуска
dart pub get
и посмотреть, как меняется поведение
программы. (Убедитесь, что dart --version
возвращает
вам именно 2.12)
bin/hello.dart:...void main() { var hello = 'Hello Dart developers'; if (someCondition) {hello = null; } print(hello);} Before changing the SDK constraint:$ dart run null After changing the SDK constraint (and running dart pub get):$ dart run bin/hello.dart:6:13: Error: Null can't be assigned to a variable of type 'String' because 'String' is not nullable. hello = null; ^
dart pub outdated
в режиме
null-safety. Приведенный ниже пример показывает, что приложение
будет готово к миграции, если обновит свои зависимости на
path
, process
и pedantic
до
пред-релизных версий, перечисленных в столбце
Resolvable.pubspec.yaml
, чтобы разрешить эти мажорные версии.
Например, можете поменятьprocess: ^3.0.13
на process:
^4.0.0-nullsafety
.dart
migrate
.
$ dart pub get$ dart analyze
$ flutter pub get$ flutter analyze
2.3.x
до 3.0.0
). Это гарантирует, что
пользователи вашего пакета не обновятся до него, пока не будут
готовы использовать null-safety. Это дает вам свободу рефакторинга
API, чтобы наилучшим образом применить null-safety.3.0.0-nullsafety.0
, а не 3.0.0
.)flutter
вылетали на
определенных конфигурациях машины с ошибкой null: The method
'>=' was called on null
. Основной проблемой был недавний
пулл-реквест на добавление поддержки для обнаружения Android Studio
4.1. Этот пулл-реквест добавил такой код:
final int major = version?.major;final int minor = version?.minor;if (globals.platform.isMacOS) { /// plugin path of Android Studio changed after version 4.1. if (major >= 4 && minor >= 1) { ...
State
вне контекста Widget
. До
null-safety они возвращали null и маскировали ошибку; при
null-safety анализ определил, что эти свойства никогда не могут
быть null, и выдал ошибку анализа.scene
в Window.render()
. Во время
миграции на null-safety они добавили подсказку, чтобы
пометить Scene как не допускающую нулевое значение, а затем
смогли легко предотвратить потенциальные сбои приложения, которые
мог вызвать переданный null.package:flutter
) сократился на 3,9%.TextAlign.start
при null. Эта логика вызывала ошибку в
кеше, когда элементы выглядели так, будто они изменились, даже если
у них все еще было значение по умолчанию. В результате часто
случались нерезультативные обращения в кеш. Добавление геттера
textAlign
, не допускающего значения null, помогло
исправить ошибку кеширования, что привело к увеличению
производительности рендеринга текста в 14 раз в случаях
кешируемого текста.flutter channel beta
, а затем flutter
upgrade
. А если вы не используете Flutter, то можете
получить автономный Dart SDK из
архива Dart SDK.Поезд null safety мчится вперёд, уже почти официально анонсирован Flutter 2.0 (подключайтесь к предстоящему Flutter Engage), экосистема Dart тоже не стоит на месте. Мы перевели на русский язык новость из официального блога Dartlang и настоятельно рекомендуем вам переводить свои пакеты на новые рельсы, если вы этого ещё не сделали!
На днях вышла новая бета версия Dart, которая отличается повышенной стабильностью и наличием надежной null safety системы, над которой мы работали больше года. Обновленная бета (2.12.0259.9.beta) доступна на dart.dev и на бета канале Flutter. До выхода стабильной версии null-safe Dart критических изменений больше не предвидится.
Мы призываем разработчиков публиковать null-safe версии своих пакетов, чтобы пользователи смогли получить полноценную функциональность экосистемы на момент публикации стабильной версии null-safe Dart. Сами мы этот процесс уже запустили опубликовали стабильные версии null-safe пакетов, таких как args, yaml и grpc. Если все ваши зависимости в null-safe состоянии и опубликованы под стабильной версией (например, 1.0.0 вместо 1.0.0-nullsafety.123), вам пора заняться тем же!
На pub.dev мы также добавили новую фичу, которая сама размечает версии пакетов, помечая preview-релизы, если стабильная версия зависимого Dart SDK еще не вышла. Preview-релизы будут автоматически помечены как стабильные версии, как только состоится релиз стабильного Dart SDK.
Cтабильная (1.6.0) и preview (2.0.0) версии пакета args на pub.devВ руководстве по переходу на null safety есть вся последняя информация о том, как организовать миграцию ваших пакетов. Обратите особое внимание на ограничения Dart SDK и версии ваших зависимостей в pubspec. В том числе обратите внимание и на версию SDK, который вы используете для тестирования непрерывной интеграции (CI). Стабильная null-safe версия Dart выйдет уже скоро! Спасибо вам за поддержку!
Данной статьёй мы хотим пролить свет на технический стек Wrike: каким он был раньше и каким мы видим его в будущем. Мы расскажем о том, почему пять лет назад мы выбрали язык Dart основным для frontend-разработки нашего продукта и почему сейчас мы решили посмотреть в сторону других языков и фреймворков.
Для полноценного понимания наших технических решений необходимо рассказать, что такое Wrike как продукт. Wrike это большая SaaS платформа для управления проектами и совместной работы команд. Когда мы говорим большая, имеется в виду не только количество возможностей самого продукта (о которых вы можете почитать здесь), но и кодовая база. За годы своего развития, пока продукт рос и эволюционировал, мы прошли большой путь от:
Wrike, каким он был в 2014До:
Wrike 2021Столь же стремительно эволюционировали технический стек и команда разработки.
Если постараться рассказать на пальцах, что такое Wrike, то стоит отметить, что в мире управления проектами есть довольно много must have фич, без которых трудно себе представить полноценный продукт на этом рынке:
Gantt Chart, календари, таблицы и это далеко не полный набор возможностей WrikeЭто хорошо иллюстрирует сложность и комплексность UI Wrike, что накладывает дополнительную ответственность на инженерную команду с точки зрения требований перформанса, скорости разработки и стоимости поддержки.
Wrike появился в 2006, но так далеко мы копать не будем. Историю frontend-разработки нового времени Райка можно условно поделить на несколько этапов, рассматривая последние шесть лет.
На тот момент (2013-2014) мы уже написали достаточно внушительный объём кода на чистом JS, которому тогда не было альтернатив. В качестве основного движка (или фреймворка, если хотите) мы использовали Ext.js третьей версии. Несмотря на теперешнюю архаичность, вы будете удивлены, но он по-прежнему жив-здоров! На тот момент в нём было достаточно много прорывных возможностей, которые потом, через года, трансформировались в то, к чему мы привыкли сейчас. Например, data stores с некоторой натяжкой можно считать провозвестником привычных нам stores в React.
Однако уже тогда было понятно, что JavaScript не отвечает нашим требованиям. Дело в том, что растущая команда и растущая кодовая база вынуждали нас искать язык, который предлагал бы:
строгую типизацию
большие возможности из коробки
хорошую работу с большими объемами кода (сборка, минимизация и т.д.)
2014-2015 года были сложными с точки зрения принятия инженерных решений. Мы оказались перед выбором: использовать TypeScript, который тогда только-только вышел на стабильную версию или взять Dart, который был более зрелым, но менее распространенным. Подробнее вы можете прочесть тут.
Ключевыми моментами в нашем выборе стали:
Более строгая типизация. Как показало время, и Dart, и TypeScript двинулись в сторону более строгой системы типов. Dart полностью перешёл на sound систему типов, TypeScript по-прежнему имеет с этим некоторые сложности.
Возможности из коробки. Порой third-party libraries могут быть очень полезны, а порой вредны. Одна из проблем современного мира web, и ее TypeScript не решает, это обилие библиотек, которые могут помочь ускорить разработку, но которые при этом нужно выбрать, поддерживать и время от времени обновлять. Шутки про node_modules уже вошли в историю. Dart при этом имеет достаточно богатую встроенную библиотеку, core библиотеки обновляются и поддерживаются самим Google
Агрессивный Tree-Shaking. Так как Wrike имеет огромный набор фичей, которые в итоге превращаются в большой объём кода, язык должен был помогать нам не загружать большое количество кода на клиент (см. Minification is not enough, you need tree shaking by Seth Ladd, a также github).
Эти и некоторые другие особенности убедили нас сделать выбор в пользу Dart. И, оглядываясь назад на почти шестилетнюю историю Dart и Wrike, мы видим, что выбор был правильным. Конечно, мы прошли долгий путь от Dart 1.x с его динамической типизацией и интеграцией с Polymer до AngularDart и Dart 2.x. Dart помогал нам год от года растить продукт с инженерной и бизнесовой точки зрения, продвигая компанию и продукт в лидеры рынка Work Management Platforms (Gartner and Forrester ratings).
Сейчас мы написали на Dart уже 2.5 миллиона строк кода, а кодовая база состоит из 365 репозиториев. Мы создали большое количество решений для сборки и проверки Dart-кода: например, Dart Code Metrics. Без преувеличения отметим, что Wrike один из самых больших потребителей Dart за пределами Google, что касается его web-ипостаси (появление Flutter способствовало взрывному росту популярности Dart, но пока ещё по большей мере в мире мобильной разработки).
Однако реальность такова, что язык сам по себе не может дать все необходимые инструменты для построения большого web-приложения. Экосистема имеет не менее, а, может, и более важное значение. Системы сборки, подсветки синтаксиса, интернационализации, фреймворки для View без этого невозможно себе представить современную разработку.
Мы бы не хотели полностью пересказывать документацию, поэтому сосредоточимся на наиболее важной части фреймворках. Несмотря на то, что теоретически Dart позволяет работать со всеми web-фреймворками через JS interop, на самом деле выбор не очень большой:
OverReact обёртка над React от Workiva.
Flutter for Web популярный кроссплатформенный фреймворк, написанный на Dart, с недавнего времени поддержка web вышла в стабильной версии.
AngularDart де-факто стандарт для разработки web-приложений на Dart.
Другие решения возможны, но неудобны либо трудно реализуемы. Таким образом, выбирая Dart для web-разработки, вы вынуждены взять один из этих трёх фреймворков либо писать что-то своё.
В предыдущей части мы дали краткий обзор на текущее состояние экосистемы языка Dart, касаясь в основном её frontend-части. Пришло время подойти к одной из ключевых проблем, которая на момент написания этой статьи, к сожалению, не решена: при всём желании невозможно выбрать техническое решение на века. Мир frontend-разработки постоянно движется вперёд, развиваясь, порой, даже быстрее, чем того хотелось бы. Веб-браузеры также развиваются, добавляя новые и новые возможности и расширяя API. Веб-фреймворки, которые, казалось бы, по определению созданы для того, чтобы абстрагироваться от нижележащих слоёв, тоже вынуждены реагировать на это.
Вдобавок к этому существуют и модные течения даже в весьма хаотичном мире фронтенда. Какое-то время назад это был прогрессивный рендеринг (React Fiber, Angular Ivy). Сейчас появляется тенденция в виде отказа от глобальных state managers, для примера можно рассмотреть Effector. GraphQL, Server Side Rendering можно найти достаточно много вещей, которые обязательно должны быть поддержаны в современном веб-фреймворке.
Становится очевидно, что для SaaS-продукта, который движется вперёд со скоростью сверхзвукового истребителя, жизненно важно, чтобы техническая основа, фундамент, из которого он состоит, развивалась так же быстро.
И в этом фундаменте есть два составляющих элемента:
Код, который ваши инженеры пишут.
Код, который ваши инженеры НЕ пишут.
Современная разработка (особенно на фронтенде) щедро сдобрена использованием third-party библиотек и инструментов. Да что там, сейчас можно запустить продукт на рынок, вообще не написав ни строчки кода (так называемый no-code подход)! Тем не менее, код, который вы не написали это, с одной стороны, время, которое вы сэкономили, а с другой риск, который вы берёте на себя.
Разработка крупного продукта это всегда сложный баланс между написанием собственных решений / переиспользованием готовых / взаимодействием с разработчиками сторонних фреймворков. И используемые язык и фреймворк как одни из самых обширных и всепроникающих частей разработки становятся её наиболее уязвимым местом. В былые годы, когда продукты распространялись на дисках и концепция Continuous Delivery ещё не появилась, смена языка или фреймворка могла стоить критически дорого. Сейчас же, особенно с появлением концепции micro frontends, это не только не должно быть трагедией, а, наоборот, служит здоровым механизмом эволюционного развития.
Со всем вышесказанным приходится признать, что мы пришли к точке, где нам приходится пересмотреть свой текущий технический стек как не отвечающий нашим требованиям. Несмотря на то, что язык Dart и его экосистема движутся вперёд (в том числе благодаря взрывному росту популярности Flutter), а язык Dart становится всё лучше и лучше (например, с null safety) один ингредиент всё равно отсутствует web-фреймворк. Да, в самом языке уже есть примитивы, которые позволяют работать с DOM напрямую, но такая разработка может подойти для индивидуальных разработчиков, а не для больших команд.
Под отсутствием web-фреймворка мы имеем в виду, что никакое из существующих решений для языка Dart не обладает четырьмя необходимыми для современного web-фреймворка качествами:
Feature richness. Обеспечение работы со всеми (или большинством) возможностей, которые предоставляет современный web.
Performance.
Поддержка сообщества.
Развитие и добавление новых возможностей.
Если более пристально посмотреть на существующие фреймворки для языка Dart, то мы увидим, что:
Де-факто стандарт для веб-приложений. Отвечал почти всем требованиям, но, к сожалению, Google-команда сдвинула приоритет его развития в сторону Flutter. Это следует не только из твиттера Tim Sneath (менеджер Dart & Flutter):
Переписка о судьбе AngularDartНо и из более официальных источников. Также можно прочесть ветку на GitHub. Да, AngularDart по-прежнему на месте, он жив, его можно использовать. Но ему не хватает одного из ключевых элементов: Развитие и добавление новых возможностей.
Портированная версия React для Dart. К сожалению, поддержка комьюнити не очень большая, а сам проект разрабатывается в основном компанией Workiva.
Именно на этот фреймворк делают ставку инженеры Google. И он действительно движется вперёд взрывными темпами! Но то, что подойдёт небольшим компаниям или при портировании мобильного приложения на web, к сожалению, не подходит для наших задач.
В данный момент для нас есть несколько блокеров, связанных с Flutter Web. Основной это то, что невозможно встроить Flutter-приложение внутрь текущего веб-приложения. Ведь, к сожалению, Flutter нельзя обернуть в веб-компонент. Это очень сильно мешает концепции микро-фронтендов, основная идея которой состоит в том, что всю функциональность мы делим на независимые приложения. Эти приложения деплоятся и разрабатываются разными командами и имеют слабую связанность друг с другом. Если вы хотите узнать больше, на это есть соответствующий баг. Выходом было бы заворачивать микро-фронтенды в iframe, но это сопряжено с рядом трудностей технического характера.
Помимо этого, Flutter пока не имеет ряда немаловажных для современного web возможностей, например SSR или SEO.
Немаловажный аспект связан и со скоростью приложения: пока не совсем ясно, насколько Flutter сможет справиться, допустим, с табличным представлением. Мы проведём это исследование, когда появится возможность встраивать Flutter-приложение внутрь другого.
Таким образом, несмотря на нашу любовь к Dart и годы, которые мы прошли вместе, мы приняли решение двигаться в сторону изменения нашего технического стека, так как основная задача компании обеспечить возможность разработки приложения и через 2 года, и дальше, а с AngularDart мы объективно не можем этого гарантировать.
Важно отметить, что мы не прощаемся: Dart по-прежнему будет большой частью нашей разработки. Но для новых проектов мы теперь будем рассматривать другие возможности. Какие?
И, для сохранения интриги, точно по канонам всех сериалов, именно здесь мы поставим многоточие. Каков же будет наш новый стек, из чего и как мы выбирали, вы узнаете из второй части этой статьи. Подписывайтесь на наши социальные сети и следите за новостями!