Pull to refresh

Comments 104

Давно хотел перевести эту статья, да все никак руки не доходят. Если будешь переводить доки или еще что-нибудь по амперсанду — готов помочь.
да, спасибо, я очень надеюсь, что получится организовать небольшой цикл, собственно, затем «AmpersandJS, часть 0» в заголовке и написана
Вангую очередной холивар.
Субъективно jsx хорошо продуман и автор не понимает React записав jsx в против, что свойственно всем новичкам. jsx — за! До момента его использования я написал аж 3 минифреймворка для работы с DOM, с навешиванием и обработкой событий аля mvc. Благо хватило ума спохватиться и не пилить очередной велосипед. React вполне себе фреймворк.

В jsx очень мало отличий для валидности, зато много вкусных плюшек ;)

Лично у меня сложности возникли при применении роутера, не столько в его работе, сколько в подходе. Нужна была специфическая реализация.
В jsx очень мало отличий для валидности, зато много вкусных плюшек ;)

Не поясните мысль? Впечатление такое, как будто в предложении опечатка.

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

Это ведь уже не сам React, а сторонняя библиотека.
>>Это ведь уже не сам React, а сторонняя библиотека.
Это то, что приходиться использовать при росте приложения на React, как и Flux, который тоже не React. Это демагогия. Разговор об удобстве и адекватном сравнении, которого в статье нет.
Не нужно сравнивать теплое с мягким. В статье сказано
Стоит заметить, что по правде не совсем честно включать React в этот список. Это не фреймворк, а слой представления.


Правда, остается непонятным, зачем вообще React было включать в этот обзор.
>>Это не фреймворк, а слой представления.
Ваше право использовать React как слой.
Lots of people use React as the V in MVC

Моё право использовать React как фреймворк. Если код используется как каркас, то это фреймворк. React+Flux вполне себе фреймворк. Рассматривать React отдельно от Flux не имеет смысла, как и делить его на более мелкие части.

>>Правда, остается непонятным, зачем вообще React было включать в этот обзор.
Читаете только то, что нравится?
>>В принципе, когда вы добавите к нему фейсбучный flux, он уже может считаться фреймворком.
Ок, React это V, Flux это C, а что тогда использовать как M?
Чем вас не устраивает pure js?
Тем что это pure js. и вообще я извращенец и хочу unit-of-work на js.
Рассматривать React отдельно от Flux не имеет смысла, как и делить его на более мелкие части.

Я полагаю, что React вполне можно использовать отдельно от Flux-подобных библиотек. Это вполне имеет смысл.

Однако сравнивать React даже с Flux и, скажем, Angular я считаю не совсем корректным. Все же предоставляемые возможности не сравнимы. React — это слой представления, а Flux — просто способ представления потока данных в приложении.
>>Все же предоставляемые возможности не сравнимы.
Я так понимаю вы сравниваете методом «у кого больше»? Можно тогда просто сравнить в кб-мб.

>>Ок, React это V, Flux это C, а что тогда использовать как M?
Store не?
Я пытаюсь сравнивать предоставляемые возможности. Связка React + Flux не дает вам как минимум следующих возможностей, которые предоставляются фреймворками:

— Роутинг
— Формы (в т.ч. валидация)
— Нормальные модели данных (datastore — это просто оболочка)
— Шаблонизация (в т.ч. i18n и i10n)
— Удобное Unit-тестирование

Разумеется, все это можно сделать. Однако, в результате у вас получится ваш собственный фреймворк, в котором React будет занимать место View-компонента, а xFlux — системы управления событиями.
Из вышеперечисленного только Роутинг меня беспокоит.

Мне не нужны:
— чужое представление какими должны быть Формы (в т.ч. валидация),
— ваше представление о моделях данных,
— шаблонизация мне совершенно не сдалась т.к. React предоставляет удобное расширение и повторное использование компонентов.
— Интернационализация делается удивительно простым способом.

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

Поделитесь с общественностью, пожалуйста.
Я вовсе не пытаюсь вам что-то навязывать. Помните, с чего вы начали диалог?
Spichka: Я так понимаю вы сравниваете методом «у кого больше»? Можно тогда просто сравнить в кб-мб.
FractalizeR: Я пытаюсь сравнивать предоставляемые возможности.

Я сравниваю возможности, предоставляемые фреймворками / библиотеками безотносительно к тому, что нужно именно вам или мне. Моя аргументация проста: сравнивать велосипед с автомобилем некорректно, пусть даже конкретно кому-то возможностей велосипеда и достаточно.
>>Помните, с чего вы начали диалог?
Субъективно jsx хорошо продуман и автор не понимает React записав jsx в против

а не с
>>Я так понимаю вы сравниваете методом «у кого больше»?

Я не стану продолжать, вы видите только то, что вам нравится.

>>Поделитесь с общественностью, пожалуйста.
Создаются файлы начиная с ru_RU.js, с объектом внутри. В программе лишь ссылки. Далее дело только за переключением на нужный объект по событию. Что может быть сложного в создании файла на язык или переключателе на 2 строки?
Создаются файлы начиная с ru_RU.js, с объектом внутри. В программе лишь ссылки. Далее дело только за переключением на нужный объект по событию. Что может быть сложного в создании файла на язык или переключателе на 2 строки?

Я ничего против ReactJS или вас не имею, так то, это был вопрос для развития, а не для спора.
Вопрос, как внутри react-компонента появляется локализованная строка или время или сумма? Можете пример привести, если не сложно?
Стандартным способом, например:

//language
import lang from '../../lang/init';
var langComment = lang.comment;

далее использование
langComment.firstName содержит 'Имя:'

js хорошо работает с сылками, ссылаемся в init на ru_RU — русский, на en_EN — английский и т.д.
Ну т.е. по сути внедряем зависимость в компонент при помощи ссылки на модуль. При повторном использовании — должны это учитывать, следующая архитектура должна это поддерживать.
Абстрактные кони в вакууме плавают только в эфирных морях.
Ну почему же, мы можем разруливать эту ситуацию уровнем выше, а локализацию передавать как параметры компонента. Тогда наш конь может плавать в большем числе эфирных морей?
Смена локализации происходит в самом высоком, одном, месте. Выше некуда, проще тоже некуда, удобнее тоже вряд ли возможно, но я с удовольствием посмотрю на пример в виде кода.
Если в большое число компонентов добавлять локализацию как параметры и делать при этом проверку, то конь превратится в слона или даже в стадо слонов. Если нет, то получиться именно то, что я описал и способ является универсальным и ненуждающимся в абстрактности.

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

Ну можно передавать как параметр — некий сервис локализации, в компоненте вызывать, например, locale('LocaleString') и не завязываться на конкретные пути '../../lang/init';
>>Ну можно передавать как параметр — некий сервис локализации, в компоненте вызывать, например, locale('LocaleString') и не завязываться на конкретные пути '../../lang/init';

Ну это уж вы сами для себя решите пугает вас относительный путь или нет. Ваше locale('LocaleString') тоже не из воздуха берется.
За это должен отчевать IoC, и тогда все будут счастливы.
Почему бы и да. Сервис который ресолвит зависимости между другими сервисами… где-то я такое видел…
Глобальные сервисы зависимые от других сервисов, которые в свою очередь зависят от других сервисов. Что-то я не ощущаю достоинств в подобном подходе…

Никакой разницы что писать в новом проекте: locale('LocaleString') или локальный путь '../../lang/init'; С точки зрения написания вся сводиться к количеству набираемых символов. Проблема высосана из пальца.
С точки зрения написания вся сводиться к количеству набираемых символов. Проблема высосана из пальца.

Никто и не говорит про написание, речь о:
1. Тестирование, допустим у нас есть файл тестирования в папке spec/unit/Component1Spec.jsx. Как вы подгрузите модуль локализации?
2. Повторное использование компонента. Мы обязаны использовать именно файловую структуру, хотя у нас локализации может быть в localStorage или еще где-то. Т.е. жесткая завязка на конкретную архитектуру.
3. Кэширование — ну то же самое, что и в пункте 2.
1. укажу путь, проблем не возникало.
2. Зачем хранить в localStorage локализацию, когда там можно хранить параметр языка? от 2 до 5 символов.
3. Вы выдумали проблему. И что там с кэшированием? Кэшируется нормально, а у вас?

Я вам ещё раз повторю, что вы выдумываете проблемы и затем их пытаетесь решить, вместо того, чтобы писать проект.

Переусложнение проекта в попытке сделать всё и вся универсальным приводит к завышенным требованиям к кадрам. Сначала придумываем проблемы и решаем, затем это нигде больше не используется или используется редко.

Не знаю как вы, а я ставлю грань разумного. Я уже обжегся на универсальности. Больше не повторится.

Это не библиотека, а проект. Универсальность всего и вся ненужна.
Если вы пишете одинаковые проекты, то безусловно вы пытаетесь оптимизировать код для увеличения скорости разработки. Вы повторно используете компоненты, я целые проекты. Для меня мелочи несущественны.
Вы повторно используете компоненты, я целые проекты.

Это всего лишь значит, что вы изобрели собственную архитектуру (основанную на соглашении о путях, как у Ember) и ReactJS тут не причем.
Моё право использовать React как фреймворк. Если код используется как каркас, то это фреймворк. React+Flux вполне себе фреймворк. Рассматривать React отдельно от Flux не имеет смысла, как и делить его на более мелкие части.

В вашем случае фреймворк это не React + Flux. это ВашаАрхитектура+React+Flux
Что это значит? Что следующий человек, начинающий работать над тем же проектом и знающий React + Flux, не сможет просто сесть и работать. Сначала ему нужно будет изучить документацию вашей архитектуры, ваших соглашений по путям и т.д.
Большинство больших проектов требуют изучения API. Ничего нового я не изобретал.
Субъективно jsx хорошо продуман и автор не понимает React записав jsx в против

Это вы обсуждали не со мной, видимо. Во всяком случае, эту часть вашего поста я никак не комментировал.

Я не стану продолжать, вы видите только то, что вам нравится.

Ответьте, пожалуйста, вы не согласны, что React + Flux и, скажем, Angular находятся в разных весовых категориях по наличию возможностей и если их сравнивать, то это нужно делать с полным пониманием этого факта? Мы сейчас не обсуждаем ваши личные потребности или желания. Мы обсуждаем сам факт возможностей, предоставляемых фреймворками.

Я уже привел свою аргументацию. Можно посмотреть на вашу?
Но в случае Angular вы проводите кучу времени, занимаясь описанием поведения внутри HTML вместо JS.

Ну это опять же проблема разработчика. То что Angular предоставляет такую возможность это бесспорно минус, так как начинающие разработчики пихают буквально все туда. Но это не значит что так делать правильно. Воспринимайте ангуляровские шаблоны как шаблоны, а не как HTML и спать будет лучше. Например используют же люди тот же Jade или Handlebars.

Ну и да, логика приложения и логика представления несколько разные вещи.

Слишком много магии. За магию надо платить.

Опять же соглашусь, но это больше проблема не фреймворка а людей. Скажем мне часто приходится видеть код контроллеров куда пихают просто так deep-watch, на который навешивается какая-то логика и т.д. В тоже время можно явно вызывать колбэк при помощи директивы ng-change, это и дебажить чуть проще, и более явно, и контроллеры становятся чище… но… как говорится.

Я не уверен, что вообще существует некий канонический способ построения одностраничного приложения на Angular.

Есть angular-styleguide, но да, поддерживать приложения написанные людьми без опыта работы с ангуляром это боль. В целом мне больше нравится концепция фреймворка построенного на базе отдельных компонентов, который можно перестраивать под собственные нужды. Этого я жду от Angular2 и этим мне не нравится Angular1.

Еще заметил что людям пришедшим из бэкэнда Angular по культуре ближе. А если еще и на ES2015 писать то вообще ништяк.

я не вижу другого применения Polymer, кроме как в качестве полифила для этой функциональности, простите.

Ну так для этого его и придумали. И продвигают они его для более быстрой адаптации web-компонентов разработчиками.

блин, как-то лень дальше писать…

В целом я не увидел из документации к этому самому амперсанту ничего нового или интересного. Думал было amtersand-model интересная штука (пока только Ember.data заинтересовала из библиотек в контексте фреймворков), но преимуществ по сравнению с тем же js-data вообще не нашел.
Картинки еле подгружаются, habrastorage по ним плачет :-)
UFO just landed and posted this here
Развиваю на работе проект на Angular, а также создал и развиваю проект на Ember. Также есть опыт Backbone.

Разница между Angular и Ember — просто небо и земля, в пользу Ember.

***

У Angular очень низкий порог вхождения, но очень высокая сложность использования. Сложность в том смысле, что крайне сложно сделать по-настоящему качественно. Выбрав Angular, вы наступите на все возможные грабли, подложите себе множество мин замедленного действия. Рефакторинг для вас будет как ремонт в советской квартире — процесс постоянный и мучительный. Нужно пройти огромный (полагаю, многолетний) путь, чтобы достичь такого уровня владения Angular, который позволит написать приложение с действительно качественной кодовой базой с первого раза.

Angular очень низкоуровневый. В нём всё делается на коленке. Радоваться такому подходу могут только те, кто никогда не пробовал добротный высокоуровневый фрэймворк и кому не приходилось поддерживать проекты, писаные несколькими сменами говнокодеров. На самом деле это полная жопа. Чтобы писать качественный, читаемый и поддерживаемый код на Angular, надо иметь строжайшие гайдлайны и соблюдать их. На деле же всё пишется как быстрее, ведь Angular так легко позволяет срезать углы.

Сообщество Angular — это как сообщество PHP. И то, и другое — это губки, которые впитывают всех дилетантов и бесталанных разработчиков. Подчеркиваю, что я не утверждаю, что толковых и талантливых разработчиков там нет. Есть, конечно, но их процентное соотношение — самое низкое среди всех фрэймворков/языков.

Angular — это не MVC-фрэймворк. Они долгое время позиционировали себя как «MV*», потом они убрали эту аббревиатуру с сайта. Ржака в том, что в Angular нет ни View, ни Model, по сути, Angular — это голый контроллер. Вместо слоя модели можно использовать что-то свое, например, JSData, полностью слизанный с Ember Data. Но в 99% поделок на Angular модель как отдельная сущность отсутствует, данные хранятся, как бы это сказать, в ладошке. Со слоем представления всё печально, так как в Angular его нет, но и взять свой нельзя. Вместо вьюх Angular использует DOM нагорячую. То есть Angular берет существующий DOM, проходится по нему и модифицирует на лету. Вам приходится вставлять Angular-разметку прямо в HTML, и вся эта разметка попадает в браузер. HTML-код Angular-приложения в инспекторе браузера выглядит закиданным яйцами и туалетной бумагой, и у подавляющего большинства Angular-приложений HTML-код невалиден.

Логика в HTML! Это просто цирк какой-то. В принципе, Angular не обязывает вас выносить логику в HTML, но вы не найдете ни одного приложения на Angular, которое этим не грешит.

Angular трудно тестировать. Angular заявляет, что написан для удобного тестирования, но на практике вы столкнетесь с трудностями и значительную часть кода оставите непокрытой тестами.

Документация Angular — это что-то с чем-то. В разделе Services приводятся примеры использования `.factory` и нет `.service`, а примеры использования `.service` приводятся на странице Providers. Оглавлений у простыней страниц нет, найти что-то сложно. Если не верите на слово, попробуйте в официальной документации найти, какие аргументы принимает колбэк `link` у директивы (подсказка: все страницы с упоминанием `link` или `directive` в заголовках можете пропускать, там не найдете).

Я уже не говорю про проблемы с производительностью Angular. Это просто курам насмех. 2000 binding'ов — и canvas-анимации начинают подтормаживать. Становится видно, как Angular скрипит шестеренками даже когда пользователь ничего не делает. Чтобы снизить количество binding'ов, приходится прибегать к методам работы, применяемым в Backbone. Это крайне досадный шаг назад.

***

Ember — полная противоположность Angular. Освоить его сложно. Мне потребовалось два месяца, чтобы почувствовать себя в нем комфортно. Но с этого момента пользоваться им стало очень и очень просто, удивительно удобно и продуктивно.

Прежде всего скажу, что Ember очень гибок. Его «предвзятость» ни в чем вас не ограничивает. Не верьте тем, кто говорит, что Ember вас ограничивает в написании вашего приложения (так пишут только те, кто перепробовал фрэймворки для галочки, не задержавшись в каждом дольше чем на день). Всё, буквально всё в Ember расширяется и переопределяется. Более того, фрэймворк изначально построен с расчетом на то, что вы будете его расширять и переопределять.

«Жесткость» Ember проявляется только в структуре вашего проекта. Стандартизованная структура, благодаря подходу «договоренностей вместо конфигурирования» (convention over configuration), избавляет вас от необходимости писать обслуживающий код. Изначально, Ember использует дефолтные сущности для всего, что ему требуется (вьюхи там, контроллеры, шаблоны, маршруты...). Стоит вам сохранить кастомную сущность под соответствующим именем, как Ember начинает использовать ее вместо дефолтной. Таким образом, вы пишете только бизнес-логику: описываете суть вещей, без «воды». Из всего, что я писал на JS, код на Ember получается самым компактным и наиболее экспрессивным. По мере развития вашего проекта его структура не превращается в помойку. Структура, кстати, не такая уж и жесткая: можно группировать файлы по типу сущности (models/user.js, components/user.js), а можно по названию сущности (user/model.js, user/controller.js), выбирать вам.

Ember — это полноценный MVC-фрэймворк. В числе прочего, у него самый лучший в мире роутер и на редкость грамонтный слой модели.

В Ember используется свой сборщик (на основе Broccoli, это конкурент Gulp) и готовая структура проекта. Они очень качественные, очень богаты функционально и очень активно развиваются. Но самое главное, сборщик и структура проекта — стандартны. Все проекты построены на одних и тех же конвенциях, никто не изобретает убогие велосипеды с костылями.

Ember побуждает грамотно структурировать код. В Ember нужно постараться, чтобы напортачить — в отличие от Angular, где приходится постоянно тужиться, чтобы НЕ напортачить. После короткого вводного курса по Ember новобранец способен писать приличный, читаемый и поддерживаемый код.

В Ember из коробки идет поддержка ES6, можно сразу писать современный код. BabelJS обеспечивает обратную совместимость (до IE8 включительно). Используются чистые, лаконичные ES6-модули, которые, пока браузеры не обзаведутся их поддержкой, транспилируются в AMD.

В Ember очень удобная система аддонов. Аддоны можно писать как для самого Ember, так и для сборщика. Аддоны распространяются через npm, который по ряду критериев практичнее Bower'а. Например, npm позволяет лочить версии зависимостей при помощи lock-файла (shrinkwrap), хотя до практичности Ruby Bundler им обоим как до луны.

В Ember очень удобная система классов. Оставаясь интуитивно понятной для JS-кодеров, она обладает многими преимуществами более благородных языков. Классы можно расширять динамически (причем, как инстансы, так и классы), из переопределяющего метода можно вызывать переопределяемый. Есть mixin'ы. В общем-то, значительная часть функционала вынесена в mixin'ы, плюс идет процесс рефакторинга: всё больше базового функционала Ember выносится из встроенных классов в mixin'ы, облегчая переиспользование кода. Например, для типового формирования URL'а раньше надо было require'ить сериализатор, что увеличивает связность приложения, а это не очень хорошо (tight coupling). А теперь можно в любую сущность подключить mixin с методом формироавния URL'а.

Шаблонизатор Handlebars — это просто благословение, особенно после Angular'овского засирания DOM. Возможности шаблонизатора намеренно ограничены (как в Django), чтобы не допустить вынос логики во вьюхи. Движок шаблонизации в Ember активно развивается, недавно он вышел на качественно новый уровень, позаимствовав некоторые приемы из React. Вот тут React прикрутили в качестве view layer в Ember, и можно сравнить скорость рендеринга сложной вьюхи между React и чистым Ember: github.com/ghempton/ember-react На глаз, разница примерно двукратная: где-то 0.2 и 0.4 секунды. А со следующим развития шагом Ember догонит и, возможно даже, перегонит React, см. github.com/emberjs/ember.js/pull/10501. К слову, в инспекторе браузера HTML-код Ember-приложения выглядит почти полностью чистым (добавляются айдишники), и он валиден. А для любителей indendation based синтаксиса есть целых два препроцессора: один с синтаксисом по примеру Jade/Slim, другой по примеру Haml.

Вычисляемые свойства Ember позволяют писать реактивный код. За пару месяцев использования Ember в вашей голове происходит смена парадигмы с императивной на декларативную. Это очень круто и удобно. При том же объеме функионала, код становится короче и яснее. Кроме того, вычисляемые свойства ленивы: они не вычисляются до тех пор, пока не будут запрошены, а результат вычисления запоминается. Повторное вычисление происходит только при изменении свойств, от значений которых зависит значение данного вычисляемого свойства.

И никакого dirty checking, Ember использует observer'ы. Благодаря этому data binding не сказывается на производительности приложения и работают интуитивно понятно. Когда вы меняете значение свойства, Ember синхронно уведомляет все заинтересованные сущности об изменении. «Под капотом» цепочки вычислений группируются в так называемые run loops, в результате обновление DOM происходит пакетно в конце цепочки, а не на каждом шаге.

В Ember очень активное и дружелюбное сообщество. Не находясь в когтях корпорации, Ember развивается в открытую. Все планы обсуждаются сначала в RFC'ах, потом в pull-request'ах. Главные мэйнтейнеры раз в N недель слетаются на встречу, чтобы обсудить проблемы развития в реале. Все мэйнтейнеры Ember — сотрудники различных «продуктовых» компаний, использующих Ember в продакшене.

Ember развивается по принципу «стабильность без стагнации». «Стабильность» здесь означает отсутствие такой жопы, как в Angular, где новая мажорная версия фрэймворка оказывается заведомо несовместимой с предыдущей. «Без стагнации» означает отсутствие такой жопы, как в Node, где развитие проекта заморожено в угоду поддержке корпоративных клиентов и вопреки нуждам сообщества. На практике этот подход означает, что, во-первых, новые фичи вводятся по мере готовности, не откладывая до мажорного релиза. Во-вторых, breaking changes вводятся с длительным deprecation period, давая пользователям возможность без нервотрепки поддерживать кодовую базу в актуальном состоянии. Релиз мажорной версии будет означать по сути просто отключение поддержки ранее deprecate'нутых фич.

В последнее время Ember рекомендует подход, аналогичный React: data up, actions down с использованием односторонних data binding'ов. Это делает структуру приложения более плоской и упрощает отладку. Однако вы можете использовать двусторонние data binding'и там, где считаете уместным (например, для input'ов). Я свое первое приложение построил целиком на двусторонних, и структура приложения получилась очень простой (всё обновляется и пробрасывается само, не надо ничего делать руками), при этом я не столкнулся с проблемами ни в производительности, ни в отладке.

В Ember самый функциональный и удобный инструмент отладки в инспекторе браузера. Angular Batarang стыдливо прячется за спинами.

Ember очень легко тестировать. Полная инфраструктура тестирования идет из коробки: всё преднастроено и готово к использованию. Сборщик создает заготовки тестов для каждой сущности, которую вы используете. Покрыть юнит-тестами можно абсолютно любую сущность, будь то модель, маршрут или даже какой-нибудь initializer. 100%-ное покрытие риальне! Очень легко писать приемочные (acceptance aka integration) тесты благодаря удобным хелперам, позволяющим работать с асинхронными операциями в синхронном стиле. В комплекте идет QUnit, но есть аддон, добавляющий поддержку Mocha, хотя благодаря хелперам особой нужды в Mocha нет. Также есть аддон для Chai. Статус тестов можно смотреть не только в консоли, но и в браузере во время работы dev-сервера. В процессе разработки приложение на Ember компилируется инкрементально, благодаря чему ждать перезапуска тестов приходится не дольше пары секунд. В комплекте идет конфиг для Travis: публичный проект на Github можно бесплатно тестировать на CI-сервере.

Документация у Ember достаточно хорошая. Есть замечательный официальный Guide, способный заменить книгу. Доки по API пишутся прямо в исходниках соответствующих компонентов при помощи специальным образом сформированных комментариев. Благодаря этому документация для каждой версии Ember формируется автоматически и никогда не устаревает.

На builtwithember.io можете посмотреть примеры свободных и проприетарных приложений, выполненных на Ember. Там можно найти всё: разнообразные админкии, дэшборды, чаты, инструменты визуализации и анализа данных, CMS, CRM, соцсети, форумы, таск-менеджеры, трейдинговые площадки, средства рассылок, continuous integration, базы знаний, поисковики, платежные системы… Короче говоря, всё, что можно придумать. Из крупных проектов: Vine (100 млн уников в месяц), ZenDesk (их бэкенд обрабатывает 100 тысяч запросов в минуту), TravisCI, DockYard, Twitch (100 тысяч просмотров в минуту в пиковое время; был куплен Amazon'ом за миллиард долларов).

***

Backbone — это несерьезно. Это просто удобная обертка над jQuery и Underscore. Data-binding'ов нет, MVC нет и много чего нет. Чтобы сделать single-page applicaiton на Backbone, вам придется писать бескрайние простыни обслуживающего кода. Это очень утомительно (для программиста) и дорого (для работодателя). Сложность поддержки Backbone-приложения растет экспоненциально по отношению к размеру кодовой базы.

PS С удовольствием отвечу на вопросы по Ember. Общие вопросы задавайте здесь в комментах, конкретные вопросы по коду пишите на StackOverflow (с примером на JSBin.com) и кидайте ссылку в личку.
Всяк кулик свое болото хвалит.
Гм, вы так говорите, как будто у меня не было выбора. Как будто я был вынужден использовать только Ember и хвалю его из зависти к Angular и React.

Напротив, я тщательно сравнил акутальные на тот момент фрэймворки: Angular, Backbone, Knockout, Ember, Derby (и ряд менее известных: CanJS, BatmanJS и т. п.) и сделал взвешенный выбор.

Derby показался наиболее перспективным. Но вместе с рядом ярких преимуществ: изоморфность, синхронизация и разрешение конфликтов из коробки, шаблонизатор принимает более одного блока при вызове компонента — есть и серьезные недостатки: медленное развитие, полное отсутствие какой-либо документации и справочных материалов за исключением Readme на титульной странице, маленькое сообщество, отстутствие тестирования из коробки, незрелость, выливающая в постоянные breaking changes.

Angular невзлюбил заочно. Когда я ознакомился с приемами ее работы и прошел туториалы, мне стало противно пользоваться им дальше. Уже одних только засранного DOM и отсутствия внятного шаблонизатора мне было достаточно, чтобы вычеркнуть его из списка. Однако когда на работе встал вопрос, на каком фрэймворке переписывать проект, я выбрал Angular. Мне важно было принять решение в пользу компании, а не себя любимого. Angular победил с большим отрывом по распространенности, документированности, количестве доступных специалистов.

Я надеялся, что, познакомившись с Angular ближе и на примере опытных спецов (проект пилили аутсорсеры csssr.ru), я его если не полюблю, то хотя бы приму. Увижу, как принято на нем работать, освою приемы, и перестану испытывать к нему брезгливость. Как бы не так. После глубокого знакомства с Angular я в нем еще больше разочаровался. Сейчас развитие проекта целиком легло на мои плечи, и я проклинаю тот день, когда сел за баранку этого пылесоса.

Админку для нашего бэкенда (с достаточно сложным аналитическим функционалом) я написал на Ember и был поражен разительным отличием. Я давно интересовался Ember, но по одним только туториалам освоить его было сложно, и наконец, появилась возможность применить его на боевом проекте. Освоение Ember — это лучшее, что произошло в моей жизни после рождения сына. :D Мир снова заиграл красками, появился энтузиазм. :)

Так что не надо тут про кулика и болото. Сами-то в каком болоте сидите?

PS Посмотрел предыдущий коммент оратора, понял, что это тролль. Зря распинался, ну ладно.
Забыл упомянуть Meteor. Вычеркнул его из личного списка потому, что это тоталитарная секта. :)
можно подробней?
У Meteor свой пакетный менеджер и свой репозиторий пакетов. Зачем пользоваться экосистемой npm, если можно запилить свою, с блэкджеком и шлюхами?

Потом, Meteor очень монолитный. На нем очень просто делать базовые вещи, но шаг влево-шаг вправо — и становится очень трудно, приходится бороться с фрэймворком. Мотороллер не мой, пересказываю то, что слышал.

Я в этом плане предпочитаю более гибкую структуру. Отдельные бэкенд и фронтенд позволяют разделить ответственность и выработать подходящий задаче API, которым могут пользоваться любые фронтенды. Например, нативные приложения для мобильников, а также сторонние браузерные и любые другие приложения.
Ну зря вы так. Я нисколько не тролль. И мнение ваше ценно наравне с мнениями других людей. Вот только я с завидной регулярностью наблюдаю посты/статьи с подобным же сравнением, в котором победителем выходит, например, Angular. Очевидно, что мнение авторов весьма субъективно и основывается на их опыте и тех задачах, которые им приходится решать. Мне только непонятно одно: откуда столько категоричного восторга? Вы такими дифирамбами вносите хаос в мозги джуниоров, которые начитаются подобного и потом в истерике бегают с вопросом «Что выбрать?».

Мне Ember очень приятен, мне близки идеи, которые в нем заложены, и я слежу за этим фреймворком. Потому оспаривать ваше мнение, я не стану. Вот только лично мне было бы весьма любопытно почитать ваше мнение о недостатках этого фреймворка. Приходилось ли с ним бороться? Про angular и backbone написано достаточно, а вот про Ember — не очень.

ЗЫ: Backbone вообще не стоит ставить в один ряд с Ember или Angular. Это разные вещи, созданные под разный круг задач.
> Мне только непонятно одно: откуда столько категоричного восторга?

Если коротко, то потому что он его заслуживает.

У меня как фронтенд-разработчика сформировалось смутное представление о том, каким должен быть идеальный фрэймворк. Ember на это представление лег практически один-в-один. Я был поражен тем, насколько он продуман и практичен, а главное, насколько он продуманнее и практичнее всех конкурентов.

> Вы такими дифирамбами вносите хаос в мозги джуниоров, которые начитаются подобного и потом в истерике бегают с вопросом «Что выбрать?».

Ну конечно, джуниоры ведь не должны задаваться вопросом «Что выбрать?». Они должны бездумно выбирать то, что пользуется массовой популярностью. Вчера это был Angular от Google, сегодня — React от Facebook, а завтра будет какое-нибудь детище очередной мегакорпорации. Вангую на Amazon, что-то они еще еще ничем не разродились.

Моей целью было не посеять сомнения о выборе, а наоборот, развеять их. Подтолкнуть сомневающихся к выбору фрэймворка, обеспечивающего не только модные фишки, но и качественную структуру проекта, maintainabilty кода, тестирование и т. п.

> Вот только лично мне было бы весьма любопытно почитать ваше мнение о недостатках этого фреймворка. Приходилось ли с ним бороться?

Мне не нравится, что из компонентов запрещено напрямую вызывать actions в контроллерах и маршрутах. Идея в том, что компоненты реюзабельны и не допускают высокой связности. Но я часто пишу компоненты, которые вообще не предполагают использования вне своего контекста. А когда компоненты вложены, пропускать action из самого внутреннего компонента в контроллер — утомительно. Приходится вручную в каждом компоненте цепочки для каждого прокидываемого события писать «когда в тебе вызывается событие А, вызови событие А на родителе». Это пока единственный случай, где в Ember мне пришлось писать обслуживающий код.

Чтобы работали observer'ы, в Ember приходится работать с любыми свойствами только через методы get и set. Само по себе это не утомительно, но трудность в том, что этих методов нет у plain objects. Если структура данных приходит извне, то приходится либо создавать из нее в Ember Object, либо работать с ней как с иммутабельной, то есть создавать копию всей структуры. То же самое касается JSON-подобных структур в свойствах моделей. Для решения этой проблемы придумали аддон model fragments, но от него больше мороки, чем пользы.

Бороться с фрэймворком приходилось пока только один раз. Ради красивой реализации пагинации, мне хотелось, чтобы данные запрашивались с бэкенда в дочернем маршруте, но при этом были доступны в родительском. Разобравшись с тем, как в Ember устроены маршруты, мне удалось решить эту задачу, хотя получилось не очень элегантно.

PS Совсем забыл упомянуть о том, что в Ember из коробки идет mock-бэкенд на базе Express, позволяющий прототипировать API в отсутствие бэкенда.
Приходится вручную в каждом компоненте цепочки для каждого прокидываемого события писать «когда в тебе вызывается событие А, вызови событие А на родителе». Это пока единственный случай, где в Ember мне пришлось писать обслуживающий код.

Т.е. в Ember вообще нет DI — все приходится протаскивать через все слои? Ну вот, а он только мне начал нравится с вашего рассказа. Ведь DI — это самая важная вещь в реюзабельности и слабой связанности.
Вы можете прокинуть, например, контроллер в компонент. Можете передать его вверх по цепочке вложенных компонентов и в самом внутреннем компоненте вызывать метод напрямую на контроллере.

Просто в Ember так делать не принято, так как это увеличивает связность. Вместо этого предлагается спускать в обратном направлении action'ы.

Action'ы в Ember без телодвижений с вашей стороны всплывают по такой цепочке: вьюхи -> контроллер -> маршруты. Но в компонентах сделали ограничение, чтобы action всплыл из компонента, нужно явным образом его отправлять. При этом нужно указывать сопоставление между внутренним названием action'а в компоненте и внешним названием action'а в родительском модуле (компоненте/вьюхе/контроллере/маршруте). Таким образом обеспечивается слабая связность, компоненты не знают ничего лишнего о своем контексте. Но прокидывать action'ы руками — геморройно.
Вы можете прокинуть, например, контроллер в компонент.

Бить по рукам за это.

Речь идет о сервисах.

p.s. Если вести речь о low coupling то Anglar2 вне конкуренции на данный момент. Хотя и там есть куда развиваться дальше.
Для всего.

Вот пример: guides.emberjs.com/v1.11.0/understanding-ember/dependency-injection-and-service-lookup/#toc_dependency-injection-with-code-register-inject-code Говорите что, куда и по какому имени инжектить. В качестве направления можно указать семейство типов — например, route — тогда сервис будет заинжекшен в каждый раут. А можно — конкретный тип: 'component:my-awesome-component' Тогда только конкретный компонент будет иметь доступ к сервису. Это удобно тем, что вы в одном месте контролируете видимость того или иного сервиса и не получите неожиданных зависимостей.

Можно делать и проще: emberjs.com/api/classes/Ember.inject.html#method_service — т.е. DI в стиле Angular — инжектим «на месте». Появился недавно, и я от него не в восторге. Мотивация была в стиле «DI via Initializers» — это слишком сложно для неискушенных в Эмбере.
Но кстати, как выше написал lolmaus, лучше не инжектить сервисы напрямую в компоненты, а пробрасывать данные «вниз» по иерархии компонентов и экшены «вверх». Из-за большого упора Эмбера на раутинг обычно каждый конкретный «экран» вашего приложения — довольно простой, и совсем глубокой иерархии строить не приходится. Поэтому передача «вручную» на практике не является проблемой.

А инжекшен лучше оставить на уровне рутов. Конечно, если ваш компонент — это какая-то вещь в себе, то можно и сервисы напрямую в него подключать, чем заниматься жонглированием атрибутов и экшенов. Но тут как и везде — главное, думать головой.
Не правда ли отличный холивар, коллега? :D
Можно делать и проще: emberjs.com/api/classes/Ember.inject.html#method_service — т.е. DI в стиле Angular — инжектим «на месте». Появился недавно, и я от него не в восторге. Мотивация была в стиле «DI via Initializers» — это слишком сложно для неискушенных в Эмбере.

Но это именно то, что я люблю больше всего. Чтобы отдельный кусок мог использовать внутри себя сервис/объект/поток, объявленный в нем по интерфейсу (в случае angular название переменной совпадает с названием интерфейса — это мне не нравится, но не критично), а конкретное приложение уже решало какой объект туда засунуть. Причем модель прокидывания наверх мне не нравится — слишком много мест, где можно все испортить, на каждом уровне.
Кстати, заодно вопрос — как в Ember локализуются компоненты?
А что такое «засранный DOM» и «внятный шаблонизатор» (в частности слово «внятный» в данном контексте не очень понятно)?

HTML по своей сути декларативен, если вам это не нравится, а также вы не приемлете подхода AngularJS по расширению HTML и созданию своего DSL для приложения, то очень странно, что вы его хоть для чего-то выбрали.
Засранный DOM — это DOM, в котором много лишних атрибутов, которые не предназначены для отображения страницы, а только для внутренней работы приложения. Это все равно что бытовой прибор без корпуса, в котором провода торчат наружу.

Внятный шаблонизатор — это шаблонизатор, обладающий таким синтаксисом, что по беглому взгляду становится понятно, что там происходит и в каком порядке. В Angular же на один элемент навешивается куча директив, и нужно мучительно вглядываться в код, чтобы выцепить структурные директивы типа ng-repeat. Во внятном шаблонизаторе структурные директивы выносятся на один уровень, и четко видно, где там условие, где итерация и т. п.

Как я уже писал выше, шаблонизатор Ember намеренно ограничивает пользователя в возможностях, не позволяя запускать произвольный JS-код из шаблона. При этом в синтаксисе есть все нужные штуки, например, при передаче блока HTML внутрь компонента, в блоке кода будет внешний контекст (не контекст компонента, куда блок передается), но при этом можно в блок кода принять аргументы из компонента и использовать их.

> то очень странно, что вы его хоть для чего-то выбрали.

Да, вот жалею теперь. Но врага нужно знать в лицо, правда? ;)
Ваша позиция понятна, для вас HTML — это нечто нерасширяемое, предназначенное только для отображения страницы. У вас не страница является приложением, а приложение генерирует страницу.
Каждому свое, просто разные подходы. Время покажет, какой выживет :)
Внятный шаблонизатор — это шаблонизатор, обладающий таким синтаксисом, что по беглому взгляду становится понятно, что там происходит и в каком порядке.

Вам понятно что там происходит только потому, что вы уже знаете HTML. Знаете, что href — это аттрибут ссылки, а src — это source для img, script и т.д. Это просто вопрос привычки, а не чего то глобального.
Собственно и в angular никто не мешает вам вынести структурные директивы на один уровень
Создайте директиву «repeat» и «if» и пишите так же, как везде, например:
<repeat for="row in rows">
    <if cond="row.isShow==1">
        {{row.field1}}
    </if>
</repeat>


Замечу также, что и сам HTML позволяет использовать и JS и CSS (и еще кучу всего) внутри себя. Тогда вам лучше отказаться и от него. И тогда будет уж точно странно пользоваться angularjs, основной целью которого является расширение синтаксиса HTML.
Цели, может, у вас и благородные, но на практике получается каша.
Я вас уверяю, мне, как человеку, не знающему handlebars, синтаксис кажется гораздо более уродским,
<div>
{{input value="http://www.facebook.com"}}
</div>

Зачем то еще один декларативный язык внутри декларативного языка, причем оба прекрасно бы справились с задачей представления дерева.
Чтобы было видно, где кончается HTML и начинается Ember.
Так задача шаблона разве не «это шаблонизатор, обладающий таким синтаксисом, что по беглому взгляду становится понятно, что там происходит и в каком порядке.»
А тут мне предлагают разбираться где начинается один язык, кончается другой — парсить в голове и знать оба синтаксиса.
HTML описывается в одном стандарте, Handlebars — совсем в другом.

Синтаксис Handlebars выучивается буквально за 15-20 минут. Если для вас это непреодолимый барьер, оставайтесь на Angular.
Если для вас это непреодолимый барьер, оставайтесь на Angular.

Ну да, это ж настолько level up…
Ну вообще-то человек подробно обосновал, почему ему нравится Ember, а не просто похвалил болото.
очень сбалансированная смесь субъективного опыта и реальных фактов описанных хорошим живым языком, не то что мои переводные идиомы, спасибо за такой комментарий, он сделал пост в полтора раза полезнее, как мне кажется.

ну и восприятие Angular тоже мне близко, хотя мне очень интересно, как это все будет выглядеть в Angular 2.

Ember посмотрю поближе, с наскока он мне не дался, может вы можете порекомендовать какие-нибудь обучалки по нему, помимо доков на оф сайте и курса на Code school?
К сожалению, не подскажу. Я рандомно читал всякие материалы по Ember (включая официальные доки и курс Code School), но фрэймворк мне не давался до тех пор, пока в голове не скопилась достаточная масса знаний и пока эти знания не проболтались там достаточно долго, чтобы сложиться в собранный паззл. Ну и помогло то, что я осваивал фрэймворк посредством написания реального приложения.

Сейчас выходит новая книга по Ember: balinterdi.com/rock-and-roll-with-emberjs Она каких-то ненормальных денег стоит, но тексты доступны на Github в формате Markdown. Также показалась грамотной эта книга: leanpub.com/emberjs_applications Ее я купил, но так и не прочитал. Вот эта также должна быть полезной, про сборщик и аддоны: leanpub.com/ember-cli-101

А официальный гайд — чрезвычайно полезный. Рекомендую прочитать его два раза: один раз в начале обучения и один раз в конце.
Ох как это знакомо. Испытывал подобное с другим стеком технологий. Сначала куча материалов в несколько подходов и только после некоторой накопленной массы знаний очередной подход сделать что-то на практике увенчался успехом и более глубоким познанием стека.
Сообщество Angular — это как сообщество PHP

А вот тут, как это не печально, соглашусь… 90% (если не больше) под Angular это страх и ужас. Скажем я не видел ни одного достойно написанного проекта на Angular доступного на github, что бы черпать вдохновение или учиться. Но опять же, как и в случае с PHP, не все пишут плохо. Вопрос культуры.
Отличный комментарий. Вы бы оформили его отдельным постом :)

Я выбрал Эмбер для проекта на прошлой работе. И на новой стали делать один проект на Эмбере. Я заметил, что если идти «эмберовским путем», то фичи реализуются легко и просто. Но не всегда легко увидеть этот путь, особенно новичкам. В связи с этим хотел бы описать, с какими трудностями сталкивался, и узнать, как бы вы их преодолели.

Чтобы не вдаваться в предметную область, рассмотрим искусственный пример. Пусть у нас есть две сущности: посты в блоге и комментарии. Помимо обычной связи один ко многим, мне нужно добавить еще одну в противоположном направлении. Например, пост может быть написан «по мотивам» какого-нибудь комментария. Технически связь хранится в поле post.inspired_comment_id в виде положительного числа или null.

Теперь я хочу при редактировании поста указывать, был ли он написан по мотивам какого-либо комментария. Предполагается, что сначала я выбираю пост, к которому был написан комментарий (поле ввода названия с автодополнением), потом выбираю сам комментарий (динамически обновляемый select). Такая схема с двумя элементами формы диктуется предметной областью.

Моя трудность в том, что я не понимаю, как проще всего сделать выбор родительского поста. Инпут с автодополнением я вынес в отдельный эмберовский компонент, он используется во многих местах. Но здесь появляется вопрос об источнике данных для автодополнения, потому что внутри компонента нельзя использовать store. Я не хотел делать запросы к API напрямую аяксом. Мне пришлось общаться с компонентом посредством трех величин: filter (строка, которую я ввожу), id (выбранный пост) и массив value-label (список подсказок).

Для автодополнения у нас используется некий контрол (самописный плагин к jQuery). В колбэке контрол сообщает компоненту текущие введенные символы, а компонент возвращает в контрол jQuery.deferred. Компонент передает строку через filter наружу. В контроллере на свойстве filter срабатывает observer с такой конструкцией: store.findQuery(...).then(...). Функция в then(...) заполняет массив value-label, после чего срабатывает observer на этом свойстве в компоненте. Он либо разрешает имеющийся jQuery.deferred (обновляется список подсказок), либо инициализирует компонент (устанавливает выбранный элемент при загрузке страницы).

Это всё как-то работает, но меня не покидает ощущение костыльности происходящего. Я вынес свойства и обсерверы поставки данных для автодополнения в миксины (не только для постов, но и для других сущностей), и подключаю их к разным контроллерам. Но если на странице появятся два одинаковых компонента выбора постов, но с разным смыслом (например, две разных связи с постами), мне придется копипастить миксин App.PostSelect в App.PostSelect2, чтобы появилось два разных свойства postSelect.id и postSelect2.id.

Как бы вы стали делать такую функциональность? Прокидывать store внутрь компонента? Получать подсказки прямым аяксом, минуя store?

У меня есть еще несколько вопросов, но комментарий и так уже стал слишком длинным. Был бы благодарен, если бы вы помогли упростить хотя бы это :)
Прежде всего, я бы задал себе два вопроса.

1) Имеет ли этот компонент смысл вне своего контекста, могу ли я переиспользовать его в другом разделе сайта, в другом проекте?

Если ответ отрицательный, то я считаю допустимым прокидывать store в компонент. Можно его инжектить при помощи `store: this.inject.service()`. То же самое касается и других сущностей. Я не вижу ничего плохого в сильной связности, ведь в данном случае компонент является по сути продолжением контроллера, способом разбить код на несклько файлов.

Если же вы хотите абстрагивать компонент от приложения, то логику работы со store в контроллер страницы.

2) Подходят ли данные, которые должен получать компонент с сервера, под паттерн Модель. Другими словами, нужно ли вам создавать из этит данных записи (инстансы модели), хранить их на клиенте и persist'ить на сервер. Если да, то вы пишете модель, адаптер и сериалайзер. Если нет, то вы создаете сервис, в который абстрагируете Ajax-запросы для взаимодействия с источником данных, и в компоненте работаете с сервисом, а не с Ajax.

Далее. Существует такой компонент: ember-select-2. В нём вопрос подгрузки вариантов выбора решен из коробки, не надо изобретать велосипед.

Ели надо передать команду из компонента в контроллер, используйте action, а не observer. А для обратного направления (из контроллера в компонент) обновляйте данные, которые прокинуты из контроллера в компонент.

Я для себя вывел такой rule of thumb: если вам приходится создавать deferred в одном месте, а ресолвить его в другом, то, скорее всего, структура приложения неоптимальна и нуждается в рефакторинге. Хотя бывают исключения.

Если всё-таки надо делать deferred, то используйте Ember.RSVP.defer, а не jQuery.deferred. Для Ajax используйте ic-ajax, а не jQuery.ajax.

> У меня есть еще несколько вопросов, но комментарий и так уже стал слишком длинным. Был бы благодарен, если бы вы помогли упростить хотя бы это :)

Пиши вопросы на StackOverflow (крайне желательно, сразу с примерами на JSBin/Github) и кидай ссылки в личку.
Да, ember-select-2 смотрится эффектно. В моем случае велосипеды обусловлены «утвержденным дизайном и стилем». Контролы оформлены в виде jQuery-плагинов, чтобы их можно было использовать в разных проектах на разных фреймворках. По этой же причине использую jQuery.deferred.

Я понял, что надо попробовать заменить observer на action, примерно как это сделано в ember-select-2, спасибо.

Меня скорее интересует не разбор конкретных фрагментов кода, а типовые подходы к решению задач. Допустим, у нас есть длинная таблица со списком сущностей, и у нее есть фильтр. Ясно, что значения полей фильтра проще всего привязать к QueryParams, и мы не только закодируем значения параметров в адресной строке, но и сможем автоматом передавать их на сервер.

Но заказчик хочет не живые фильтры, а старомодную кнопку «применить», да еще и «отменить» и «сбросить». Приходится передавать внутрь фильтра не только сами QueryParams, но и свойства в контроллере, хранящие дефолтные значения параметров (для кнопки «сбросить»). А также для компонентов из предыдущего комментария выбранные значения типа postSelect.id. Отдельные поля фильтра я обернул в дочерние подкомпоненты и организовал обмен событиями между ними и родительским компонентом фильтра. При нажатии на кнопки происходит тривиальное копирование одних свойств подкомпонентов в другие.

Подход работает, но мне не нравится его громоздкость, и не нравится, что в контроллере нужно создавать свойства с текущим значением каждого поля фильтра (они привязываются непосредственно и к инпутам, и к дочерним подкомпонентам, в которые обернуты инпуты).
Как всё радужно :-)
Давайте я о проблемах что ли напишу:

1. Нет поддержки статической типизации (TypeScript например). То есть вы не можете при сборке проверить все ли вызовы происходят правильно. Эти проверки приходится не забывать делать в тестах.

2. Следствие предыдущего — проблемы с со статическим анализом в IDE (поиск ошибок, автодополнение, рефакторинг и тп). Частично эта проблема решается JSDoc-аим, от чего доки эти излишне раздуваются и требуют особо внимательного обращения.

3. Имена свойств передаются как строковые константы, что опять же плохо сказывается на автодополнении и скорости работы.

4. Разобраться в исходниках очень сложно — всё раскидано по куче модулей со сложными зависимостями.

5. Похоже свойства реализованы очень неоптимально. Как по скорости, так и по потребляемой памяти.

Я бы рекомендовал использовать атомы, да боюсь это сломает обратную совместимость и потребует какого-нибудь Ember2.0 :-)

1, 2 — этого вам недостаточно? github.com/borisyankov/DefinitelyTyped/tree/master/ember

Вообще, странный аргумент. С тем же успехому можно отругать Angular за то, что он написан не на каком-нибудь Opal.rb и, следвательно, не позволяет на полную катушку использовать Ruby IDE.

3 — вы производительность с Angular сравниваете? Ember хотя бы не завешивает процессор, когда пользователь ничего не делает. :P

4, 5 — вы как в воду глядите. Ember 2 как раз таки переходит на атомарную структуру. Эта «сложная» система модулей как раз позволит импортировать их штучно вместо того, чтобы в каждый свой модуль импортировать весь Ember со всеми зависимостями.

Ember 2 сейчас в бете. После резила документация подтянется, ориентироваться в модулях будет легко и удобно.
Я не знаю насколько надо плохо делать дела с ангуляром что бы он жрал процессор когда пользователь ничего не делает.
Он это делает по определению — гоняет свой digest несколько раз в секунду. Нагрузка на процессор тем больше, чем больше байндингов на странице.

Ситуацию усугубляет то, что в Angular не предусмотрено кэширующихся вычисляемых свойств.

Поэтому мастерство владения Angular заключается в том, чтобы знать все его многочисленные грабли и подводные камни и уметь с ними справляться. Я предпочитаю использовать фрэймворк, главной фичей которого не является нашпигованность граблями.
гоняет свой digest несколько раз в секунду

Если пользователь ничего не делает и в фоне не происходит что-то, то CPU кушаться не будет по определению, некому запустить $digest цикл.

В целом проблемы будут только если у вас больше 1000 активных биндингов на странице, и проблемы будут не с производительностью а с этим лютым говнокодом который требует такого количества биндингов.
Тайпскрипт, например, не поддерживает примеси. Не сможет проверить существование и типы свойств. Короче, всё плохо.

Я сравниваю со своим велосипедом. Я много времени потратил на исследование разных способов задания свойств.

Микромодульность — это классно :-)
> Простой аргумент: я не знаю ни одного значимого приложения от Google, которое бы использовало данный фрэймворк хоть для чего-то.
Это для меня как красный сигнал светофора.

Дальше читать не стал.
мне тоже не очень понравился этот аргумент, особенно учитывая статус текущей версии Polymer, но из перевода слов не выкинешь
Polymer был вообще в состоянии pre-alpha, а сейчас, наконец, с веткой 0.8 он перешел в состояние alpha, при этом у него фантастический рост производительности, очень существенная несовместимость с 0.5 и некоторые фичи 0.5 ещё не портировали. Ясное дело, что Google совсем уж сырой продукт использовать не будет. В этом году обещают стабильную 1.0, тогда и посмотрим. Очень странная статья — смешано всё и в кучу.
Я бы в плюсы Ангуляра записал наличие ngCordova и Ionic.
Указанные минусы бекбона очень легко решаются сторонними фрейворками (например: марионет, риветс и т.д) — в этом его сила. Он не пытается решить все и сразу как ембер, но и не решает слишком мало, как реакт.
Меня тоже удивляет, когда регулярно пишут о минусах Backbone «забывая» про Marionette.js. Само название фрейворка Backbone предполагает что это каркас, предполагающий расширение. Нет надо взять голый Backbone и сокрушаться как там всё плохо с необходимостью писать «простыни шаблонного кода».
Само название фрейворка Backbone

Люди забывают что Backbone это не фреймворк а библиотека, давайте начнем с этого.
Не придирайтесь к словам. Его часто по ошибке называют фреймворком как раз потому, что в статьях его ставят в один ряд с Angular и Ember.
UFO just landed and posted this here
Есть еще Chaplin.js и Thorax.js, не говоря уже о сотне плагинов. Но если говорить о Marionette.js, то марионетка решает только задачи, связанные с представлениями, каких-то решений для работы с данными (computed и nested attributes, например) в ней нет и не появится еще как минимум 2 мажорных релиза. Марионетке еще нужно пройти взросление, которое в свое время прошел Ember. Но то, что делают разработчики марионетки, мне нравится.
А вот тут вы не правы вполне можно использовать epoxy c marionette и будут вам computeds и прочие фишки, вот только проблема что подружить их придется вам :)
Сторонних плагинов для backbone есть приличное количество, но я говорил о функциональности «из коробки». Это совершенно разные вещи.
Все аргументы против Polymer в данной статье — высосаны из пальца. Для меня главным пунктом «против» является статус «developer preview», и, не смотря на это, я использую Polymer в своем проекте (требования позволяют). После работы с ним мысль о том, чтобы использовать что-то другое из списка — кажется невыносимой. Мои главные аргументы «за»: очень органичная поддержка модульной структуры проекта, передача связанных данных по цепочке от родительского компонента к дочерним и возможность писать на «незатуманеном» чистом JS/Dart внутри. Помимо этого, у Polymer есть еще ряд неочевидных и даже неожиданных плюсов, о которых я хочу написать статью.
Было бы очень интересно почитать про опыт реального применения Polymer
Да, про реальное применение polymer было бы очень интересно. По структуре кода, очевидности и чистоте он по-моему вне конкуренции.
Абсолютно согласен. Самый прозрачный фреймворк, полностью разделяющий обязанности HTML, CSS & JS. Мне только показалось, что в 0.8 версии они убили всю простоту и человекоориентированность. Надеюсь, что ошибаюсь.
Недостатки angular 3 и 4 надуманы. Сложно потому что фреймворк комплексный, а не как react или jquery. Стурктуру он как раз предоставляет, нужно просто ее понять и использоваться.

В react в недостатках не указано что это всего лишь рендеринг, в отличии от допустим ангуляра, который самодостаточен. Также дял react разметка хранится вместе с кодом (php style, вполне понятно тк он facebook), это гораздо хуже чем добавление нескольких кастомных angular атрибутов в html.
Будучи сейчас backend разработчиком, часто ощущаю желание отвлечься и сделать что нибудь на javascript. Много работал с angular. И честно говоря уже как-то устал от него. И вот начиная небольшой домашний проектик, который изначально планировался для личного пользования из любого браузера, я задумался — опять брать ангулар? Или изучить что-то новое? Хм… Может сделать без фреймворков?..

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

Начал с вопроса: каким должен быть фреймворк для моего приложения? Поразмыслив, я пришел к такому ответу:

— он должен служить потребностям приложения, а не приложение являлось бы оправданием существования очередного фреймворка, от которого прикольно будет только одному автору.

— он должен быть заточен под архитектуру приложения (в данном случае это что-то вроде консоли)

— он должен следовать современным тенденциям в разработке web приложений. Должен быть дата биндинг, шаблоны, инъекция зависимостей.

— архитектура фреймворка не должна влиять на то, как пишеться код доменной области — домен должен знать как можно меньше о фреймворке. Я должен иметь возможность потом заменить его на другой фреймворк в случае надобности.

— он не должен быть фреймворком. Нужен набор независимых компонентов.

— он должен быть тестируемым.

Результатом попытки вополотить это в жизнь является bitwisecmd.com, которо может быть полезно людям, которые хотят разобраться с битовыми операциями. Много чего там неидеально и некрасиво сделано, но было очень интересно сделать что-то подобное. Получил массу опыта и удовольствия. Кому интересно можно глянуть код на GitHub
Данный обзор очень и очень плохой не потому что тут спор что же лучше angular/react/backbone хотя сравнение backbone и react вообще сложно представить. Всегда есть одно но, никто не заметил явные сходства ampersand с 2 фремворками это marionette и epoxy, вот один в один (это очень грубое сравнение я видел и щупал ampersand) но уж очень идеи похожи.
не очень понял, почему именно плох обзор, было бы классно немного наполнить коммент знаками препинания, возможно, он будет понятнее. Сходство с marionette и epoxy странно замечать и обсуждать в комментариях, ибо оно очевидно — все они построены на базе backbone и должны иметь достаточно много общего между собой.
Sign up to leave a comment.

Articles