Два года с Dart: о том, как мы пишем на языке, который ежегодно «хоронят» (часть 1)

Habrahabr
«А он еще не умер?»,- спрашивают нас про Dart на каждой фронтенд-конференции. «А как Google поддерживает язык?», «как вы нанимаете разработчиков в команду?», «а почему не TypeScript, если вам нужна типизация?»

Мы решили объединить наиболее частые вопросы и задать их в интервью Игорю Демьянову, менеджеру по разработке Wrike.

Поговорим с ним о том, почему Wrike, с 2 млн строчками кода за спиной больше двух лет назад не побоялся перейти с JavaScript на Dart, как проходила миграция, как рос продукт и увеличивалась команда разработчиков, как развивается язык сегодня, несмотря на разговоры о его стагнации или даже смерти. Игорь, продукту уже больше 10 лет, а что было до того момента, как вы начали использовать Dart для разработки фронтенда Wrike?

До Dart мы писали на ExtJS 3 и частично на ExtJS 4. Плюс у нас был небольшой самодельный фреймворк, который написал один из бывших сотрудников. Этот «велосипед» нам сейчас скорее мешает, и мы от него потихоньку избавляемся. На данный момент в проекте более 2,5 млн строк клиентского кода, новый функционал мы уже года два пишем на дарте и потихоньку избавляемся от легаси на ExtJS.

В какой момент и почему пришло понимание, что надо переставать писать на JS?

Оно пришло, когда Wrike начал активно расти. Когда у нас в команде было 11 человек — мы еще как-то могли использовать JavaScript, более-менее понимать, кто какой код пишет, помнить все нюансы старого кода. Но сейчас в команде фронтенда у нас около 50 человек, разработчики распределены более чем по 10 scrum-командам, и правило личных договоренностей уже не работает. Задач много, разработчиков много, кода много.

Много кода — это сколько?

На клиент мы в данный момент грузим около 10 мегабайт сжатого кода, раньше было 5 или 6. И раньше эта цифра выглядела страшно, сейчас и подавно. Но мы тут ничего не можем сделать -продукт активно растет функционально. Разумеется, мы стремимся, чтобы отдельные куски кода грузились по требованию, но в каких-то случаях приходится подгружать весь код сразу, чтобы весь функционал Wrike был доступен клиенту мгновенно.

Так а почему Dart?

Dart выгодно отличается от всего остального тем, что он может выкидывать неиспользуемые части кода, это и позволяет нам жить с таким огромным легаси. Когда проект большой и разработчиков много, очень сложно контролировать, что ты используешь, а что нет. Есть код, который лежит в кодовой базе — может быть, его просто кто-то забыл выкинуть из общей сборки — и он все еще живет с нами. И если бы мы использовали JS с его сборщиками, этот код точно приходил бы на клиент. А Dart позволяет оптимизировать и выпилить ненужный код. Плюс мы не зависим ни от каких стандартов JS, которые постоянно меняются и обновляются. Кода ты делаешь enterprise-продукт, очень сложно выбить у бизнеса время на перевод с одного стандарта на другой.

Выбрав Dart, мы пошли по пути медленной миграции: вначале переписали корную часть, затем — остальной функционал. Сейчас у нас уже грузится нового кода больше, чем старого. При этом продукт активно развивается и новые фичи приходится делать очень быстро. С точки зрения команды, процесс тоже поменялся — разработчики меньше времени тратят на разбирательства, какие параметры куда передаются.

Да, сейчас примерно эти же возможности есть у Typescript или JS+Flow, но нам нравится Dart. У языка простой и понятный синтаксис, а главное — он позволяет нам концентрироваться на идеях, экономить время, которое бы мы тратили на рефакторинг или, скажем, на переход с ES5 на ES6, фреймворки и т.п.

Сейчас ведется какая-то разработка компонентов продукта на JS?

В отдельных исключительных случаях мы можем вносить изменения в легаси-код на JS, если видим какой-то critical bug. В остальных случаях пишется новый код на Dart — он либо заменяет старый код, либо добавляет новый функционал.

Какой фреймворк вы используете?

Примерно год назад мы перешли с Polymer на Angular2. Сейчас планируем переход на Angular3, а к концу года — на Angular4. Во многих компаниях бизнес в этом отношении довольно тяжело идет навстречу R'n'D — такие миграции сопровождаются долгими спорами и убеждениями. То, что мы используем самые новые инструменты — не только заслуга фронтенд-разработчиков, но и наших тестировщиков-автоматизаторов, которые хорошо помогают нам с регрессионными тестами и QA Manual. Когда мы переходили на Dart, то получили поддержку всех технических команд Wrike, поэтому этот переход нам дался относительно безболезненно. Так же и с Angular — прогнозируем, что переход между версиями затянется на 1-2 месяца, вряд ли больше.

Сейчас мало знают о языке Dart, но 2 года назад информации же вообще не было. Как вообще вам удалось по живому в работающем проекте все переделать? Трудно представить, что бизнес на это вообще пошел.

Я сам начал использовать Dart с версии 0.8, когда он был еще только в бете. На момент внедрения в Wrike Dart уже был официально зарелижен, появилась спецификация, стандарты и т.п., то есть мы были уверены, что принципиально в языке ничего не будет меняться. Мы знали, с каким языком будем иметь дело, все проанализировали и получили первые результаты, которыми смогли аргументированно доказать необходимость изменений. Главным доводом в пользу дарта был Tree Shaking — умение дарта выпиливать неиспользуемый код вплоть до методов. А это при нашем объеме legacy критично.

Почему не TypeScript?

Если бы мы, допустим, портировали Wrike на TypeScript, это было бы, наверное, «дешевле». С другой стороны, у нас столько кода, что портирование на TS, нам скорее всего ничего бы не дало — остался бы тот же объем подгружаемого легаси, только на TypeScript. Dart же заставляет нас писать лаконично и правильно, и не дает допустить простых ошибок в проектировании, это его плюс, но в этом, конечно, и его строгость.

Если вернуться к бизнесу, то да, здесь мы получили поддержку. Наш CEO Андрей Филев — сам в прошлом разработчик, и разговор с ним можно вести на одном языке. Плюс, репутация Google как разработчика языка о многом говорит. В конце концов, эти изменения были необходимы и самому бизнесу, чтобы максимально быстро разрабатывать и выпускать фичи, позволяющие нам оставаться одними из лидеров рынка. В общем, бизнес поддержал, и сейчас мы очень быстро движемся, а бизнес доволен нашей скоростью.

Но вот те 11 человек, которые писали на JS и вынуждены были переходить на Dart, наверно, не так радостно восприняли эту новость?

Ребята, которые поработали с каким-то другим языком, кроме JavaScript, очень легко переходили на Dart. Они, наоборот, были довольны, что дарт решает их проблемы с чужим кодом и упрощает коммуникацию. Конечно, были и те, кто знал только лишь один JavaScript, и, как и любой «старовер», в штыки воспринимал изменения.

Сейчас в JavaScript-мир довольно низкий порог вхождения, очень много в сообществе новичков, которые осваивают язык, но едва ли понимают, как проектируются большие продукты. У моего коллеги Евгения Гусева есть доклад на эту тему, который не так давно вызвал немалую полемику среди JS-разработчиков.

Любой язык можно рассматривать только в контексте его применения, поэтому тут споры и холивары бессмысленны. Например, JavaScript всем хорош для прототипирования — как бы вы ни написали код на JS, вы его скорее всего запустите. Нет понятия “плохой JavaScript” — либо он работает, как вам нужно, либо он работает не так, как вам нужно, и все.

С Dart сложнее. У вас, как в Java и как в .net, есть анализатор, который вам говорит: «Знаешь, дружок, как бы не так. Так нельзя делать. Нельзя создавать динамические классы и т.п.». То есть язык просто не позволит самому себе выстрелить в ногу, как бы вы ни хотели.

Если вы посмотрите, многие создатели Dart, работали с серьезными объекто-ориентированными языкам, V8 делали, даже кто-то из Java у них есть. Они подошли к проектированию языка с точки зрения больших приложений, поэтому Dart – это язык для средних, больших, и очень больших приложений. Он по дефолту предлагает одно, но самое эффективное решение, и оно идет «из коробки». Вы в один клик можете сделать отложенную загрузку/загрузку по требованию, язык сам будет «выпиливать», оптимизировать код – это те бонусы, которые нужны большим приложениям. На маленьких приложениях вы практически никакого заметного эффекта по сравнению с JS не увидите.

О том, как развивается язык, что нового в нем ждать в ближайший год, насколько охотно разработчики языка из Google участвуют в жизни сообщества и решают возникающие проблемы, читайте во второй части интервью примерно через неделю.

Мы будем благодарны за вопросы в комментариях и, если потребуется, напишем более подробные технические статьи о работе с Dart на их основе.