Примечание от переводчика: перевести эту статью меня побудила запись в соц сети от автора, запись была следующего содержания: "#Angular2 для #dartlang 11.7 KB меньше чем JS версия. Я выжал что мог из обоих.". Меня это ошеломило, как так, транслируемый язык, который тянет хаки для собственной работы, кроссбраузерность и еще кучу библиотек помимо Angular, и после уродования и минификации обоих вариантов побеждает не JS. Это же так естественно, что за удобство языка приходится платить размером и скоростью работы результата. В синтетических тестах результат трансляции опережает по производительности чистый JS, в реальной работе разница в производительности незаметна. Итого получается, размер собранного Dart-проекта будет примерно равен JS-проекту, скорость работы примерно одинакова. Последнее обновление Dart позволяет в несколько строк подключить любую JS-библиотеку. А писать на Dart это одно удовольствие. Последнее утверждение частично раскрывается переведённой статьёй, приятного чтения.
За последние пол года мне удалось поработать над JavaScript и TypeScript проектами. Перед этим около года я работал с Dart. С апреля 2015 года я и мой соавтор работаем над книгой об Angular 2, этот фреймворк официально поддерживается тремя языками JS, TS и Dart. В основном я использую TS, но периодически проверяю состояние Angular 2 для Dart.
Неделю назад Angular 2 перешёл в стадию беты. Пионеры и энтузиасты Angular 2 знают, что перед этим вышло целых 7 альфа-версий. Этому сопутствовало несколько критических изменений, обновление из-за которых было весьма болезненным(не для этого ли существуют альфы). И после того как мы закончили обновление всех примеров в книге для версии beta.0, я решил взглянуть как дела у Angular 2 с Dart.
Я взял маленькое приложение, которое не менялось с версии alpha.35, и решил его обновить до beta.0. Мой опыт обновления на Dart радикально отличается от TS, чем я и хочу с вами поделиться.
Обновление Dart приложения
Заранее могу сказать, что процесс обновления тривиален и включает в себя обычные шаги обновления для любого другого Dart проекта. Несмотря на это я хочу поделиться своим опытом с теми, у кого нет опыта работы с Dart.
Тестовое приложение довольно минималистично, вы можете здесь найти исходный код: тыц. Оно состоит из Dart-файла:
И pubspec.yaml(эквивалент package.json):
Для обновления с alpha.35 до betta.0 нужно сделать две вещи:
1) В pubspec.yaml изменить версию angular2:
2) Запустить pub upgrade чтобы получить новую версию и все зависимости.
Вот и всё. Вы можете тестировать работающее приложение.
Если до этого вы обновляли Angular 2 проекты для TS или JS до beta.0, то наверняка удивлены тому как невероятно просто это делается в Dart. А для тех, кто такого опыта не имеет, позвольте обрисовать ситуацию в общих чертах.
Я не стану перечислять все изменения между alpha.35 и beta.0, но вот основные:
JS и TS Angular2 приложения имеют зависимости от сторонних библиотек(zone.js, rxjs и т. д.), которые так же находятся в стадии альфы. И они тоже обновлялись по мере перехода к beta.0, что вызвало некоторые проблемы. Dart разработчиков это обошло стороной, т. к. их Angular2 не имеет никаких сторонних зависимостей.
Некоторые из самых используемых в Angular классов, аннотаций и директив были перемещены в иные модули с целью лучше организовать публичный API. Отчасти причиной тому незрелость модульной экосистемы ES6 и нехватка лучших практик. В контраст к этому Dart-библиотеки(аналог модулей в ES6) существуют с самого создания языка. Есть определённые соглашения о том в каком виде библиотеки должны выставлять публичные API. Angular следует этим соглашениям и последние изменения не оказали сильного влияния на Dart-приложения. В сущности для нашего минимального приложения не изменилось вообще ничего.
Zone.js, который помогает Angular2 реализовать связывание стал частью angular2-polyfills.js. Этот код должен быть исполнен и добавлен на страницу самым первым. Это изменение вызвало путаницу и ряд проблем в JS приложениях. Зоны, произошедшие из Dart'а и как часть платформы, работают прямо из коробки.
Reflect-metadata.js это библиотека, реализующая API отражений, предложена в качестве части ES2016. Теперь она так же является частью angular-polyfills.js, что тянет за собой соответствующие изменения в коде. В то же время в Dart pub transformer заменяет код отражений на его статичный эквивалент во время сборки и reflect-metadata.js просто не нужен.
Observable объекты в Angular2 являются основой в API. Тип Observable так же предложен в качестве части стандарта ES2016. Однако, в настоящий момент, RxJS заполняет этот пробел. Angular использует полностью переписанный RxJS 5. Он находится в стадии активной разработки на уровне beta-версий. Beta-версия RxJS ввела кардинальные изменения, требующие соответствующих изменений в JS и TS проектах. А в Dart Streams(частный случай Observables) являются частью SDK и нет необходимости в RxJS. Если вы сомневаетесь, что streams из Dart способны заменить observables из RxJS, то вот что я скажу:
Angular 2 написан на TS и опирается на возможности ES2015, следовательно для работы требует такие прослойки как es6-promise.js и es6-shim.js. Версионные ограничения этих библиотек так же вызвали серьёзные проблемы в ходе обновления. И угадайте что? Dart приложениям эти прослойки так же не нужны. Dart2js компилятор заботится обо всех кросс-браузерных проблемах совместимости
С новой структурой Angular пакетов надо соблюдать определённый порядок загрузки скриптов. Например zone.js должен быть загружен первым, затем system.js, затем Rx.js, es6-shim.js, es6-promise и только потом можно загружать код Angular. При использовании UMD порядок может измениться(UMD это другой формат JS-модулей, который может быть выбран целевым для сборки Angular проекта). Это такая штука, о которой даже и вспоминать не надо, когда работаешь с Dart, по той причине, что единственный скрипт, который надо добавить — это файл с функцией main().
Заключение
Возможно вездесущая мантра «В Dart всё включено» вас раздражает, но взгляните на написанное выше, это не какая-то абстрактная презентация или «Hello world». Angular это один из самых популярных веб-фреймворков в мире. Миллионы строк кода написаны на AngularJS, и я ожидаю увидеть еще больше написанных на Angular2. Так что не надо недооценивать эту мантру.
Я не принуждаю вас бросить TS или JS и немедленно перейти на сторону с печеньками(Dart). Dart имеет свои недостатки. Однако, удобство разработки и ощущения от разработки в Dart это то, чего мне очень не хватало в мире JS. Надеюсь, со временем JS экосистема сократит разрыв и разработка станет более продуктивной.
За последние пол года мне удалось поработать над JavaScript и TypeScript проектами. Перед этим около года я работал с Dart. С апреля 2015 года я и мой соавтор работаем над книгой об Angular 2, этот фреймворк официально поддерживается тремя языками JS, TS и Dart. В основном я использую TS, но периодически проверяю состояние Angular 2 для Dart.
Неделю назад Angular 2 перешёл в стадию беты. Пионеры и энтузиасты Angular 2 знают, что перед этим вышло целых 7 альфа-версий. Этому сопутствовало несколько критических изменений, обновление из-за которых было весьма болезненным(не для этого ли существуют альфы). И после того как мы закончили обновление всех примеров в книге для версии beta.0, я решил взглянуть как дела у Angular 2 с Dart.
Я взял маленькое приложение, которое не менялось с версии alpha.35, и решил его обновить до beta.0. Мой опыт обновления на Dart радикально отличается от TS, чем я и хочу с вами поделиться.
Обновление Dart приложения
Заранее могу сказать, что процесс обновления тривиален и включает в себя обычные шаги обновления для любого другого Dart проекта. Несмотря на это я хочу поделиться своим опытом с теми, у кого нет опыта работы с Dart.
Тестовое приложение довольно минималистично, вы можете здесь найти исходный код: тыц. Оно состоит из Dart-файла:
import 'package:angular2/angular2.dart';
import 'package:angular2/bootstrap.dart';
@Component(selector: 'my-app')
@View(template: '<h1>Hello from Angular 2!</h1>')
class AppComponent {}
main() => bootstrap(AppComponent);
И pubspec.yaml(эквивалент package.json):
name: ng2_dart_upgrade
dependencies:
angular2: 2.0.0-alpha.35
browser: any
transformers:
- angular2:
entry_points: web/main.dart
Для обновления с alpha.35 до betta.0 нужно сделать две вещи:
1) В pubspec.yaml изменить версию angular2:
angular2: 2.0.0-beta.0
2) Запустить pub upgrade чтобы получить новую версию и все зависимости.
Вот и всё. Вы можете тестировать работающее приложение.
Если до этого вы обновляли Angular 2 проекты для TS или JS до beta.0, то наверняка удивлены тому как невероятно просто это делается в Dart. А для тех, кто такого опыта не имеет, позвольте обрисовать ситуацию в общих чертах.
Я не стану перечислять все изменения между alpha.35 и beta.0, но вот основные:
JS и TS Angular2 приложения имеют зависимости от сторонних библиотек(zone.js, rxjs и т. д.), которые так же находятся в стадии альфы. И они тоже обновлялись по мере перехода к beta.0, что вызвало некоторые проблемы. Dart разработчиков это обошло стороной, т. к. их Angular2 не имеет никаких сторонних зависимостей.
Некоторые из самых используемых в Angular классов, аннотаций и директив были перемещены в иные модули с целью лучше организовать публичный API. Отчасти причиной тому незрелость модульной экосистемы ES6 и нехватка лучших практик. В контраст к этому Dart-библиотеки(аналог модулей в ES6) существуют с самого создания языка. Есть определённые соглашения о том в каком виде библиотеки должны выставлять публичные API. Angular следует этим соглашениям и последние изменения не оказали сильного влияния на Dart-приложения. В сущности для нашего минимального приложения не изменилось вообще ничего.
Zone.js, который помогает Angular2 реализовать связывание стал частью angular2-polyfills.js. Этот код должен быть исполнен и добавлен на страницу самым первым. Это изменение вызвало путаницу и ряд проблем в JS приложениях. Зоны, произошедшие из Dart'а и как часть платформы, работают прямо из коробки.
Reflect-metadata.js это библиотека, реализующая API отражений, предложена в качестве части ES2016. Теперь она так же является частью angular-polyfills.js, что тянет за собой соответствующие изменения в коде. В то же время в Dart pub transformer заменяет код отражений на его статичный эквивалент во время сборки и reflect-metadata.js просто не нужен.
Observable объекты в Angular2 являются основой в API. Тип Observable так же предложен в качестве части стандарта ES2016. Однако, в настоящий момент, RxJS заполняет этот пробел. Angular использует полностью переписанный RxJS 5. Он находится в стадии активной разработки на уровне beta-версий. Beta-версия RxJS ввела кардинальные изменения, требующие соответствующих изменений в JS и TS проектах. А в Dart Streams(частный случай Observables) являются частью SDK и нет необходимости в RxJS. Если вы сомневаетесь, что streams из Dart способны заменить observables из RxJS, то вот что я скажу:
Angular 2 написан на TS и опирается на возможности ES2015, следовательно для работы требует такие прослойки как es6-promise.js и es6-shim.js. Версионные ограничения этих библиотек так же вызвали серьёзные проблемы в ходе обновления. И угадайте что? Dart приложениям эти прослойки так же не нужны. Dart2js компилятор заботится обо всех кросс-браузерных проблемах совместимости
С новой структурой Angular пакетов надо соблюдать определённый порядок загрузки скриптов. Например zone.js должен быть загружен первым, затем system.js, затем Rx.js, es6-shim.js, es6-promise и только потом можно загружать код Angular. При использовании UMD порядок может измениться(UMD это другой формат JS-модулей, который может быть выбран целевым для сборки Angular проекта). Это такая штука, о которой даже и вспоминать не надо, когда работаешь с Dart, по той причине, что единственный скрипт, который надо добавить — это файл с функцией main().
Заключение
Возможно вездесущая мантра «В Dart всё включено» вас раздражает, но взгляните на написанное выше, это не какая-то абстрактная презентация или «Hello world». Angular это один из самых популярных веб-фреймворков в мире. Миллионы строк кода написаны на AngularJS, и я ожидаю увидеть еще больше написанных на Angular2. Так что не надо недооценивать эту мантру.
Я не принуждаю вас бросить TS или JS и немедленно перейти на сторону с печеньками(Dart). Dart имеет свои недостатки. Однако, удобство разработки и ощущения от разработки в Dart это то, чего мне очень не хватало в мире JS. Надеюсь, со временем JS экосистема сократит разрыв и разработка станет более продуктивной.
Комментарии (24)
romangoward
08.01.2016 05:59Вот и всё. Вы можете тестировать работающее приложение.
Тема апдейтов в pubspec.yaml и работа dart pub не раскрыта, ибо отсутствуют:
— хладные басни про настройку PUB_HOSTED_URL, когда основная репа дарта, висящая на одном (!) заокеанском сервере, упала;
— хладные басни про pub get vs pub upgrade при работе с git, когда непонятно с какой версией собирается и почему нужная версия не выкачивается;
— хладные басни про PUB_CACHE, когда pub upgrade говорит: «ок», но ничего не выкачивает вообще.
stalkerg
Жду когда появится гений и создаст фреймворк где без лишних абстракций получится писать чистый и ясный код, решающий задачу, а не очередную проблему совместимости библиотеки А с языком B…
Vilyx
Возможно, через 10 лет нынешние фреймворки будут напоминать каменные топоры, но, как мне показалось, самый удобный каменный топор это Dart+Angular2. Только что читал про React и про то как круто, что расширяется JS, а не HTML, и что теперь html внутри JS, может чего-то и не понял, но всё же, думаю, что котлетки надо класть отдельно, а супчик отдельно. А задачку надо решать тем, что есть, на крайний случай создавать самому, мечтать лучше на отдыхе. Первый Angular действительно сложноват и местами запутан, Angular2 решает эту проблему, остальное дело вкуса, мне нравится сесть в машину и ехать, другим нравится тюнинг и собственные колёса. Почему Angular2 — потому, что он даёт почти всё, что нужно для фронтенда, что один проект на этой библиотеке будет похож на любой другой и прочитать код будет проще и втянуться в разработку тоже. Почему Dart — ответ в статье, настолько всё в нём просто делается, от создания проекта и до его релиза и если приходится с чем-то бороться, то это собственные ошибки, а не упущенная строчка в документации на пару томов.
stalkerg
В той теме я то же отписался… мне кажется вы во мне разбудили бунтаря.
Интересны были бы рекомендации при каком размере приложения имеет смысл связываться с каким либо фреймворком? А то для меня всё это выглядит как огромный блоатваре почти на пол мегабайта одного кода!!!
т.е. все эти фреймворки явно излишни для ToDoMVC примера (хотя я видел и гораздо проще примеры куда вкорчивали Angular).
Надеюсь понятно моё недоумение…
ЗЫ Dart конечно по приятнее чем JS но вся эта возня с трансляцией конечно отпугивает так же как и от TypeScript.
ko11ega
В отличие от TS, в процессе разработки на Dart ничего транслировать не надо. Dart код нативно исполняется и отлаживается в Dartium. Транслируем в JS только перед выкладыванием клиентской части в продакшен.
И при современной веб-разработке скорость разработки, в подавляющем количестве приложений(>95% по моим ощущениям), намного важнее чем +-3..4 сотни килобайт. Т.е. большинство «бунтарей» которые пекутся за размер и планируют участвовать в разработках сложнее чем ToDoMVC никогда не столкнутся с проектами в которых это будет критически важно. Скорость доступа она как бы растет…
stalkerg
1. Задержка особо не уменьшается, а CDN не всегда получается использовать.
2. Не надо забывать, что это 3-4 сотни килобайт ещё надо распарсить браузером… возьмём мобильный веб к примеру. :) (у меня там от jQuery были проблемы то)
И я правильно вас понял: вы предлагаете даже для приложений уровня ToDoMVC всегда использовать фреймворки?
ko11ega
Я предлагаю понять, что на текущий момент есть возможность разработки и хорошо оплачиваемый спрос на разработку полноценных/полнофункциональных приложений на веб технологиях. А куча людей умеющих решать задачи только уровня ToDoMVC на jQuery для этих разработок не особенно пригодны. Приоритеты у них при разработке не те.
Vilyx
При публикации в веб Dart отпиливает вообще всё, что не нужно, именно поэтому я процитировал автора поста "#Angular2 для #dartlang 11.7 KB меньше чем JS версия. Я выжал что мог из обоих."
Не знаю что именно сделал автор, но результат на лицо, любой может повторить, ToDoMVC будет чуть больше, но не думаю, что уйдёт за 100кб.
Рекомендации не по размеру приложения, а по сути его работы, если нужно сделать игру, то Angular не подходит, если нужно сделать сайт со множеством страниц, то очень даже. Одностраничники вроде ToDoMVC писать только в качестве тренировки и для понимания основ работы.
hanovruslan
В кругу коллег и в беседах просто на тему фреймворки\не_фреймворки сформировалась очень простая мысль. В текущем виде фреймворки нужны по сути только для проброса зависимостей + бутстрап. Всё остальное (даже событийная шина, кстати) — это задача приложения и\или его компонентов. Причем это справедливо и для фронта и для бэка.
Сам пишу давно на symfony (1*, 2* версии) + ангуляр 1 последние полгода.
Отсюда ответ на вопрос «при каком размере приложения имеет смысл связываться с каким либо фреймворком» — как только самостоятельная поддержка и бутстрап начинают вызывать проблемы — надо использовать фреймворк. Конечно же, желательно это «как только» предсказать, чтобы не выполнять мартышкин труд — не переписывать инфраструктурный код.
ko11ega
Если Dart+Angular2 это каменный топор, то Redstone.dart и Polymer это наверно будут просто камни )) Но они по степени простоты освоения и удобству использования в сравнении Angular2 как небо и земля. И при помощи этих камушков можно сложить full-stack вплоть до enterprise очень легко.
janitor
Не сказал бы, что Angular2 намного сложнее Polymer. по удобству использования — в течение пары часов приввыкаешь при переходе с Polymer на Angular2. Ну, мне так кажется. Polymer — хорошая штука, но очень уж тормозная. Angular2 вроде как побыстрее.
ko11ega
Вы точно сверяли Polymer 1.0 c Angular2 на схожих задачах?
Вот, например, в первом видео декларируется, что выбрали Polymer потому что он быстрее Angular 1.0. Наверняка они это про некоторую ситуацию в прошлом когда и Polymer был потормозней.
janitor
Что понимать под схожимим задачами?
Например, я разрабатывал 2 достаточо больших приложения, на Polymer 0.5.x и Polymer 1.0.x. И в обоих случаях производительность была приемлемая только в Chrome. В остальных браузерах, тк используются полифиллы — жесть просто. Ради интереса делал такое же приложение на последнем Angular 1.4 — все гораздо быстрее и стабильнее. И предсказуемо. Хотя я Angular 1 вообще не люблю.
И что еще не понравилось очень — Polymer 1.0.x очень уж сильно отличается от 0.5.x, причем в худшую сторону — столько они там всего переделали, убрали (а потом добавили все-таки по запросам пользователей). Так что переход с 0.5 на 1.0 — не такое уж и простое дело. Да и столько глюков и багов в нем, что диву даешься — они его хоть сами-то тестируют?
А ребят с этого видео знаю, работаю там же. Сейчас планируется переход на Angular 2, т.к. Polymer очень тормозной.
Vilyx
Angular2 это фреймворк, когда Polymer это библиотека для создания компонентов и не более того, т.е. в Angular2 приложении можно использовать Polymer компоненты, ничего плохого не произойдёт. Angular создан так чтобы подгружать контент не перезагружая всю страницу, и сайт превращается из набора html страничек в приложение, где можно обеспечить плавный переход и экраны загрузки если захочется. А какой у вас опыт создания серверной части? Я фронтендер и сделал себе на сайте сервер на Dart, запихнул туда Redstone и еще Shelf для статики, через пару недель после запуска это чудо убивается системой из-за нехватки памяти, сервер самый дешевый, который только смог найти. Вот не пойму что сделал не так.
ko11ega
В Polymer компонент нельзя подгружать контент не перезагружая всю страницу?
На проблемы с вашей серверной частью могу взглянуть и поделится своими соображениями. Можете прислать ссылку на репозитарий в личку.
Vilyx
Ангуляр имеет встроенные сервисы, роутинг и функции для общения с сервером, полимер же для таких вещей использует сторонние библиотеки.
А сервер примитивный: codeshare.io/ubI9Y
janitor
Ну так в этом и суть полимера и веб-компонентов — строй приложение из разных независимых кирпичников, какие больше подходят для твоей задачи.
В Polymer это тоже возможно.
Vilyx
Вы так говорите, будто я это отрицаю.
janitor
Просто из Вашего комментария у мння сложилось впечатление, что это единственное, для чего его создавали :)
Vilyx
Простите, но где тут сказано про то, что в полимере невозможна подгрузка контента?
janitor
Я про предыдущий комментарий. Там вы это преподносили прямо как одно из основных достоинств.
CJay
Привет, Миш. Про котлетки и супчик хотел написать.
Jsx в React описывает компоненты, шаблоны которых небольшие (иначе стоит подумать о декомпозиции). Так что, иметь html внутри js реально удобно и уместно. И, думаю, React полюбили не за то, что у него есть виртуальный Dom, а как раз за jsx, то есть, за супчик с котлетами в одной тарелке. И ни дай Бог их разделить.
Vilyx
Я просто не понимаю зачем html пихать внутрь js. Давай лучше в скайпе обсудим, ты объяснишь мне в чем я не прав.