Очень субъективный обзор JS фреймворков. AmpersandJS, часть 0

От переводчика: когда я начал разбираться с MVC-фреймворками для фронт-энда, каким-то чудом попалась на глаза эта статья Henrik Joreteg. Сейчас дошли руки перевести ее для Хабра, тем более, что об AmpersandJS на Хабре вообще не слышно. Попробую организовать цикл статей по этому инструменту ребят из &yet, мне кажется, он достоин внимания.

котики и велосипеды

В рамках наших образовательных семинаров я даю краткий обзор JS фреймворков. Я не очень-то хотел публиковать большую часть моих мнений об этих инструментах в Сети, потому что такие вещи, как правило, вызывают бурление масс, обижают людей, и в отличие от разговора с глазу на глаз, в интернет-дискуссиях нет действительно хорошей двунаправленной связи с аудиторией.
Но мне не раз говорили, что мой обзор крайне полезен и помогает получить сжатое и, в то же время, хорошее понимание в вопросе «кто есть кто в JS фреймворках для создания одностраничных приложений». По этому поводу я решил материализовать его и опубликовать как Нечто, но, пожалуйста, помните, что я просто высказываю свое мнение, я не говорю вам, что делать, и вы должны использовать те инструменты, которые лучше подходят вам и вашей команде. Вы можете запросто не согласиться со мной, написать об этом в Твиттере, или, еще лучше, опубликовать отдельный пост, объясняющий вашу позицию.

Angular.js


за

  1. очень легко начать использовать. можно просто вставить тег script, добавить немного ng- атрибутов в ваше приложение, и вы волшебным образом получаете нужное вам поведение
  2. Angular хорошо поддерживается его основной командой разработчиков, многие из которых работают в Гугле на постоянной основе
  3. большая аудитория/сообщество


против

  1. Если вы выбираете Angular, то вы учите Angluar.js вместо того, чтобы узнавать как решать проблемы посредством JavaScript’а. Если бы я перевел нашу команду на написание приложений с использованием Angular, что было бы, когда {здесь название прекрасного нового JS фреймворка} захочет изменить мир фронт-энд разработки? Или если мы выясним, что в конкретных задачах Angular не может делать в точности то, что мы от него хотим и мы хотим сделать эту часть с использованием чего-то еще? Насколько актуальны в этом случае будут навыки разработки под Angular? Вместо JS-разработчиков я бы получил людей, у которых основным навыком является Angular, не обязательно собственно JavaScript.
  2. Нарушает разделение ответственности. Можете сказать, что у меня устаревшие взгляды, но я до сих пор думаю, что CSS нужно использовать для оформления, HTML для структуры, а JavaScript для логики приложения. Но в случае Angular вы проводите кучу времени, занимаясь описанием поведения внутри HTML вместо JS. Лично для меня это самый существенный минус в репутации Angular. Я не хочу описывать логику приложения в HTML, это просто не достаточно выразительное средство для такой задачи, потому что это язык разметки для задания структуры документа, а не для описания логики поведения. Чтобы обойти этот момент, Angular создает, по сути, еще один язык внутри HTML и приправляет это небольшим количеством JS для описания дополнительных подробностей. Опять же, вместо того, чтобы учиться создавать приложения на JavaScript, вы изучаете Angular, и все усложняется. Вот почему книга моего друга Ари по Angular толщиной аж в 600 страниц!
  3. Слишком много магии. За магию надо платить. Когда вы работаете с чем-то на высоком уровне абстракции, становится гораздо сложнее выяснить, что же именно не так, когда что-то начало криво работать. И, конечно, когда вы сходите с проторенного пути, вам уже мало кто сможет помочь. Я могу ошибаться, но я предполагаю, что большинство использующих Angular слабо разбираются в фреймворке до такой степени, чтобы иметь возможность изменить или хотя бы отладить Angular как таковой.
  4. Почти не предоставляет структуры для приложений. Я не уверен, что вообще существует некий канонический способ построения одностраничного приложения на Angular. Не поймите меня неправильно, я думаю что это хорошо, по крайней мере точно нет ничего плохого в инструментах, которые не навязывают какой-то определенный стиль работы, но это также значит, что будет тяжелее разобраться в чужом angular-приложении или кому-то еще разобраться в вашем, потому что стили написания скорее всего будут сильно отличаться.

мой субъективный (и не застрахованный от ошибок) вывод

Слишком много логики описывается с помощью псевдо-языка внутри HTML вместо JS, и все это производит впечатление слишком абстрактного и магического.
Мне бы больше хотелось, чтобы моя команда хорошо разбиралась с DOM и JS вместо того, чтобы изучать высокоуровневую абстракцию.

Ember.js


за

  1. Сильный акцент на том, чтобы делать все «The Ember Way» (обратите внимание на первый пункт в «против»). Это палка о двух концах. Если у вас большая команда, что потенциально может привести к куче неразберихи, наличие жесткой структуры может примирить желание иметь общий базовый код и новых разработчиков, которые хотят выкинуть все написанное ранее куда подальше. Если все они Ember-разрабы, они скорее всего быстро включатся в новый для них проект на Ember.
  2. Отдает большую часть сложных проблем, встречающихся при построении одностраничных приложений, неким невероятно умным людям, которые примут много непростых решений за вас (см. вотрой пункт в «против»).
  3. Большое отзывчивое сообщество.
  4. Хороший сайт с доками.

против

  1. Сильный акцент на том, чтобы делать все «The Ember Way» (это также есть и в «за»). В Ember очень много правил. Несмотря на то, что существует возможность свернуть со стандартного пути, мало кто действительно это делает. Например, вы не обязаны использовать handlebars вместе с Ember, но я буду сильно удивлен, если существует много Ember-приложений в продакшене, которые этого не делают.
  2. Код Ember содержит в себе множество конкретных мнений о том, как решать ту или иную задачу. Если вы не согласны с этими мнениями и решаете заменить отдельные кусочки функциональности на свои собственные, в все равно отсылаете весь неиспользуемый код в браузер. Не то чтобы я люблю считать байты, но концептуально лучше иметь возможность отдавать клиенту только то, что реально используется. К тому же, если вы отдаете только то, что используете, то у вас будет меньше кода, который нужно просмотреть, чтобы обнаружить баг.
  3. Большие аппетиты по отношению к памяти тоже можно считать недостатком, особенно когда Ember запускается на мобильных девайсах.
  4. Ember намеренно не имеет структурной гибкости. Не верите мне? Тогда поверьте Иегуде (один из двух основных разработчиков Ember; остальная дискуссия также достаточно интересна).

мой субъективный вывод

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

React


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

за

  1. Возможность перестраивать DOM, не беспокоясь об его очистке. React сравнивает виртуальный DOM, который вы отрендерили, тем что есть в реальном DOM’е в настоящий момент, и делает минимальные изменения для их синхронизации
  2. Виртуальный DOM также позволяет легко решать проблемы, связанные с обработкой событий в разных браузерах, предоставляя браузеронезависимую и соответствующую стандартам модель появления и «всплытия» событий. В итоге вы получаете совместимую событийную модель в каком угодно браузере.
  3. React — это просто слой представления, не фреймворк как таковой. А значит вы можете использовать любой инструментарий при разработке приложения, который вам по душе. Он хорошо сочетается с Backbone, поскольку Backbone не предоставляет коробочного решения для привязки представления к модели, предлагая рендерить представление заново при изменении модели, и именно под этот процесс и заточен React.

против

  1. Синтаксис шаблонов и метод создания DOM (при помощи JSX) слегка странен для JS-разработчика, просто потому что нужно хранить незакавыченный HTML в Javascript код, как будто это валидно. Да, JSX не обязателен, но альтернатива: React.DOM.div(null, «Hello », this.props.name); — по моему, не сильно лучше.
  2. Если вам нужен действительно полный и явный контроль над изменениями в DOM, React вам его не предоставит. Например, вам нужно четко контролировать то, как происходят изменения в style-атрибутах, для создания интерфейсов с возможностью перетаскивания элементов. Вы не можете с легкостью установить порядок, в котором добавляются классы и так далее (хочу заметить, что я бы назвал это недостатком, но лично у меня проблем из-за этого не возникало; в то же время я общался с разработчиками, которые мучились именно с этой особенностью React; в общем, не сильно полагайтесь на мое мнение в данном вопросе)
  3. Несмотря на то, что существует возможность перестроить сразу всю вьюху React’а, если ее компоненты достаточно сложны, есть сильное подозрение, что в ряде случаев выяснение различий между виртуальным и реальным DOM’ом может стать достаточно трудоемким процессом. Я слышал о том, что некоторые разработчики, использующие React, реализовывали обновление только тех элементов, о которых было известно, что они поменялись, и это, по мне, дискредитирует саму идею невмешательства в процесс рендера модели. Опять же, в данном вопросе опыт у меня небольшой.

мой субъективный вывод

Небольшое замечание по поводу «FLUX» архитектуры. Для меня это не новая информация или идея, просто новое название. И, кажется, я не одинок в этом мнении.
Я понимаю концепцию FLUX как наличие слоя данных с разумно сделанной системой событий в чем-то типа Ampersand или Backbone с превращением всех операций пользователя и обновлений с сервера в изменения состояния этого слоя.
Если вы хотите гарантировать, что действия пользователя никогда не приведут напрямую к обновлению DOM, вы в конечном итоге придете к тому же однонаправленной цепочке передачи событий, как и в FLUX + React. Мы намеренно не включали какого-либо двунаправленного связывания модели и представления в Ampersand по этой причине. По моему, двунаправленное связывание — это потенциальный источник опасности. Мы много лет используем архитектуру, в которой только один слой имеет дело с входящими событиями, не важно, пользовательский ли это ввод или ответ сервера.

Polymer


Этот парень для меня немного странноват. Он построен на основе стандарта, который разрабатывался для возможности определять кастомные элементы (document.registerElement для создания новых HTML тегов со встроенным поведением), делать импорт HTML ( ‹link type='html'› для того, чтобы импортировать эти кастомные элементы в другие документы), и теневой DOM (для изолирования CSS от остального документа)
Все эти штуки замечательны (кроме HTML импорта, по моему мнению).
Но, судя по описанию Polymer, возникает ощущение, что это универсальное средство для того, чтобы сделать всю веб-разработку легкой и прекрасной, и и что этот фреймворк хорош буквально для всего. Вот цитата с официального сайта:
Веб компоненты вступают в новую эру веб-разработки, в основе которой лежат инкапсулированные и взаимосовместимые кастомные элементы, которые расширяют HTML как таковой. Сделанный на базе этих стандартов, Polymer позволяет легче и быстрее создавать что угодно, начиная от простой кнопки и заканчивая целым приложением для десктопа, мобильных девайсов и всего, что вы можете себе представить.

Несмотря на то, что я считаю возможность создания кастомных элементов и инкапсулирования их поведения просто фантастической, я разочарован позиционированием фреймворка. Такое ощущение, что мы теперь должны его использовать буквально для всего.
Простой аргумент: я не знаю ни одного значимого приложения от Google, которое бы использовало polymer хоть для чего-то.
Это для меня как красный сигнал светофора. Не поймите меня неправильно, очевидно это новая штука, а изменения требуют времени. Проблема просто в том, что тескт на сайте, он же обращение от инженеров из Google, работающих над Polymer, не отражает этой новизны.
К тому же, даже если бы вы насоздавали кучу кастомных элементов, покрывающих весь ваш код для слоя представления в одностраничном приложении, должен быть организован и процесс управления создания/удаления этих элементов. Вам все также придется управлять состоянием и выбирать инструменты для построения внутренностей приложения, что приводит нас к тому, что все эти кастомные элементы по правде просто другой способ написания эквивалента Backbone-вьюхи. В мире одностраничных приложений я не вижу большого выигрыша от того, что мы просто перейдем в кодированию этих вещей внутри кастомных элементов.
за

  1. Чудесная возможность создавать такие штуки, как кастомные элементы форм, не дожидаясь их поддержки в браузерах.
  2. Polymer достаточно полифилен, так что вы можете начать использовать и экспериментировать с его функциональностью уже сейчас.
  3. Изоляция стилей про создании виджетов является проблемой веба на протяжении уже многих лет. Новые стандарты решают эту проблему на уровне браузера, что просто замечательно.

против

  1. Лично мне кажется, что одним из главных стимулов создания Гуглом такого инструмента является желание сделать встраивание их сервисов, которые включают в себя поведение, стили и функциональность, внутрь страниц настолько простым, что не потребуется даже знать собственно JS. Я могу быть полностью неправым в этом предположении, но я не могу избавиться от чувства, что маркетинговая мотивация является главной движущей силой для продвижения новых стандартов в данном случае.
  2. HTML-импорт кажется мне плохой идеей. По сути, это те же грабли, что и в случае с CSS import. Если вы импортируете что-то, вам нужно подождать, пока от сервера придет ответ, после чего выясняется, что это что-то импортирует еще один компонент и так далее. Таким образом, если вы реально будете придерживаться компонент-ориентированного подхода для построения страницы, который и преподносится как наилучший, вам придется иметь дело с кучей сетевых запросов. Правда, для есть «vulcanizer» для компоновки зависимостей. Но инлайновая компоновка не видится мне правильным решением. Недавно был написан объемный пост про проблемы с HTML-импортом, где обсуждается этот вопрос и некоторые другие проблемы.
  3. Я просто не понимаю, почему Гугл так агрессивно продвигает Polymer как будто он является панацеей для разработки, при том, что единственный пример гугловского продукта, где они используют его, который мне удалось найти, это собственно сайт Polymer. Сайт утверждает, что «Polymer позволяет легче и быстрее создавать что угодно, начиная от простой кнопки и заканчивая целым приложением для десктопа, мобильных девайсов и всего, что вы можете себе представить». Из моего опыта работы с Polymer скорее очевидно обратное, я чувствую, что меня хотят обмануть.

мой субъективный вывод

Почему-то гугл не ест то, что он сам и готовит. Спецификация на document.registerElement восхищает, я не вижу другого применения Polymer, кроме как в качестве полифила для этой функциональности, простите.

Backbone


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

  1. Это достаточно небольшой и гибкий набор хорошо оттестированных блоков для построения приложений
    • Модели
    • Коллекции
    • Представления (вьюхи)
    • Роутер

  2. Он решает большинство основных проблем
  3. Его сфокусированная функциональность позволяет быстро в нем разобраться. Я всегда даю изучить документацию Backbone.js в качестве первого задания для всех новых фронт-энд разработчиков, приходящих в команду &yet.

против

  1. Backbone не предоставляет решений для всех проблем, с которыми вы столкнетесь при разработке. Поэтому, из моего опыта, каждому, кто использует backbone, приходится создавать свой собственный «фреймворк» поверх Backbone-основы.
  2. Скорее всего при использовании чистого Backbone вам будет не хватать следующих вещей:
    • Способа создания вторичных свойств для моделей
    • Способа связывания свойств, в том числе, вторичных в представлением
    • Способа рендера набора представлений внутрь какого-либо элемента
    • Простого способа работы с «подвьюхами», зависимыми лэйаутами и тому подобное

  3. Несмотря на минималистичность Backbone’а, его компоненты слишком связаны друг с другом. Например, до релиза, включающего мердж моего пулл реквеста, было невозможно использовать какой-нибудь другой тип Модели внутри Backbone’овских Коллекций без локальных изменений внутренних методов. Это может быть некритичным для некоторых приложений, но это необходимо, если, например, я хочу, чтобы модель хранила observable-данные в библиотеке, с которой должен уметь работать другой код, не обязательно зависящий от Backbone. Единственный способ использовать Backbone’овские Модели предполагает включение всего Backbone’а в проект, что кажется мне неправильным и неэффективным.

мой субъективный вывод

Backbone стал первооткрывателем многих замечательных вещей. Я использую его, начиная с версии 0.3 и мне очень импонирует его минималистичная концепция.
Он стимулировал появление нового поколения приложений, которые начали использовать браузер как среду исполнения, а не как движок для рендера документов. Но его узкая специализация приводит к тому, что разработчикам приходится писать свои решения поверх Backbone’а. Несмотря на то, что это как бы не плохо само по себе, просто становится очевидным, что при разработке придется иметь дело с большим числом проблем.

Без фреймворка


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

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

против

  • Большой объем работ по изобретению велосипедов и, как следствие, высокая стоимость разработки
  • Сложнее понять, какие модули использовать и какие лучше подходят в данной ситуации
  • Отсутствие понятной документации и соглашений для новых разработчиков
  • Сложная адаптация и переиспользование кода в новых проектах
  • Вам придется учится на своих ошибках вместо использования преимуществ чужого проверенного кода


ОГРОМНАЯ пропасть


В процессе проведения наших семинаров и подготовки моей книги Human JavaScript, равно как и внутри нашей команды как таковой, мы пришли к пониманию, что есть огромная пропасть между процессом выбора инструмента, фреймворка или библиотеки, и непосредственно разработкой законченного приложения.
Я не говорю о том, что сам вопрос «как создать приложение силами команды так, чтобы не отдавить друг другу ноги и другие части тела?» сталкивает нас с рядом серьезных проблем. Ведь кроме вопроса выбора фреймворка, у нас есть еще куча способов и паттернов, которые мы можем использовать для структурирования, сборки и развертывания приложений.
Об этих вопросах пишет совсем небольшое количество людей, хотя эта кроличья нора кажется не менее глубокой, чем та, в которую мы попадаем в попытках выбора фреймворка.

Что мы на самом деле хотим


  • Чтобы было понятно, с чего начать
  • Понятный, но не единственно возможный, способ решения типовых задач
  • Предельно очевидное разделение ответственности для легкой замены и сочетания различных частей приложения
  • Легкое управление зависимостями
  • Возможность использовать существующие проверенные решения, не изобретая велосипедов
  • Инфраструктура разработки, при которой мы можем переключаться между dev- и prod-режимами простым изменением булевой переменной в конфиге

Что мы предлагаем по этому поводу


Итак, если вы еще не догадались, мы сделали страшную для мира JavaScript вещь. А именно «новый» фреймворк: Ampersand.js. Слегка напоминает облегченный Backbone или его ответвление.
Обратная связь пока что крайне позитивна, мы анонсировали его в середине лета, и ряд замечательных ребят уже подключились к работе по его развитию. Уже появились доклады о нем на конференциях, а Джереми Ашкеназ, создатель Backbone.js, Underscore.js, и CoffeeScript попросил меня сделать кейноут об Ampersand.js на BackboneConf 2014.
Как же мы постарались учесть все те недостатки, которые я перечислил выше по отношению к другим фреймворкам?
  1. Гибкость и расширяемость
    • В Ampersand есть набор модулей «ядра» (см. документацию), которые примерно соответствуют набору компонентов Backbone. Но их все можно устанавливать и использовать по отдельности. Не предполашается, что вы обязательно должны использовать RESTful или вообще Ajax API. Если вам не нужны эти штуки, вы просто используете Ampersand-State, а не его декорированную версию, Ampersand-Model, которая дополняет State RESTful методами.
    • В комплекте нет никакого шаблонизатора. Шаблоны могут быть задаваться элементарными строками с HTML, функциями, которые возвращают такие строки, либо функциями, возвращающими DOM-элементы. В демо-приложении есть примеры использования более сложных templatizer-шаблонов, но реально шаблонизацию можно делать чем угодно. Например, есть замечательный подход в стиле handlebars/htmlbars + Ember с объявлением привязок внутри самого шаблона, реализованный в domthing Филипом Робертсом. Есть разработчики, использующие React в связке с Ampersand-представлениями.
    • В представлениях (вьюхах) можно задавать привязки к данным, не зависимо от шаблонизатора. То есть, если нужно, вы можете использовать просто HTML строки в качестве шаблонов и все равно полностью контролировать процесс связывания данных с их представлением. Отсутствие шаблонизатора в стандартном комплекте дает возможность создавать модульные/многократно используемые представления без необходимости таскать вместе с ними еще и шаблонизатор.

  2. Должна существовать некая очевидная стартовая точка и концептуальная схема задания структуры приложения, но эти вещи не должны превращаться в обязаловку. Мы создали CLI, который вы можете использовать для создания каркаса новых приложений. Он берет за основу ряд подобных соглашений, и может служить как для начального этапа разработки, так и просто как источник полезных знаний. Больше информации можно найти в мануале.
  3. Мы решили, что лучше взять за основу нечто с хорошей репутацией, чем создавать новый фреймворк, просто, чтобы создать новый фреймворк. Поэтому мы взяли за основу Backbone, а не делали все с нуля.
  4. Хотелось также иметь более полный мануал, который устраняет эту пропасть, о которой я говорил выше. В нем должно быть уделено внимание всем окружающим концепциям, инструментам и парадигмам. Для этого мы написали книгу Human JavaScript. Ее можно целиком бесплатно прочесть онлайн, и она также доступна в e-book формате.
  5. Мы хотели сделать легким использование существующих решений распространенных задач для минимизации велосипедостроения в проектах. Поэтому мы используем npm для управления всеми пакетами, и сделали каталог наших любимых clientside модулей с удобным поиском.
  6. Также хотелось иметь возможность безболезненного перехода из dev-окружения в продакшен. Эту проблему мы решаем использованием moonboots, который добавляет такую функциональность в browserify. У moonboots есть плагин для hapi.js и express.js, где все, что вам нужно сделать для изменения режима работы приложения с продакшен варианта (минифицированные, кешируемые статические сборки с уникальными именами) на dev (пересобираем код на каждый новый запрос, не минифицируем и не кешируем что-либо) — это изменить значение одной булевой переменной.
  7. Мы не хотели, чтобы этот проект принадлежал исключительно нашей &yet. У нас уже появилось порядка 40 контрибуторов с момента, когда мы рассказали всем об Ampersand.js и недавно мы добавили первого из, надеюсь, многих не-из-&yet контрибуторов в проект ядра фреймворка. Все части используют крайне лояльную лицензию MIT, а модульная слабо-связная структура фреймворка сама по себе дает возможность заменить или расширить любую его составляющую для соответствия вашим требованиям. Мы также завели отдельную организацию под этот проект на GitHub.
  8. Также хотелось обеспечить дополнительную поддержку и обучение при необходимости. Для этого мы сделали общедоступным IRC-канал #&yet на freenode для вопросов и поддержки. В дополнение к бесплатным ресурсам, мы сделали онлайн-курс «Human JavaScript code-along» и оффлайн-семинары с практическими занятиями и обратной связью.

Итак, вы хотите сказать, что Ampersand это однозначно лучший выбор?


Нет. У него конечно же есть свой список компромиссных решений. Вот те из них, которые мне очевидны, наверное, есть еще:
  • Естественно, что у Ampersand еще несколько незрелая кодовая база по сравнению с некоторыми другими подобными инструментами. Признавая это, мы, однако, используем его во всех одностраничных приложениях, разрабатываемых нами, и все базовые модули имеют хорошее тестовое покрытие. Стоит отметить, что если вы все же столкнулись с проблемой, скорее всего, вы сможете разобраться с ней сами. Его открытая, изменяемая и достраиваемая архитектура отличает его от остальных фреймворков, и вам не придется долго изворачиваться, чтобы поправить или изменить что-то в вашем приложении. Небольшой размер модулей упрощает задачи по изолированию и исправлению багов и позволяет быстро публиковать фиксы. В реальности мы часто публикуем версию с новым патчем в npm как только смерджим пулл-реквест. Мы строго придерживаемся семантического версионирования, что позволяет нам поступать таким образом, сводя к минимуму риск поломки в существующего кода. Я думаю, это основная причина того, что мы получили так много пулл-реквестов к настоящему моменту. При этом, если вы думаете, что какая-то часть фреймворка должна работать по-другому, вы всегда можете использовать свой модуль вместо стандартного. Мы также делаем шаги для увеличения числа основных коммитеров, чтобы быть уверенными в том, что патчи добавляются в проект даже когда другие разработчики заняты.
  • Пока еще вокруг Ampersand не существует развитой инфраструктуры инструментов и большого сообщества. Все это требует времени, но, как я уже говорил, нас очень вдохновляет та обратная связь, которую мы уже получаем. Включайтесь, исправляйте баги, реализовывайте ту функциональность, которую вам хочется видеть в Ampersand.
  • Поддержка старых браузеров это слабое место Ampersand. Мы специально установили границу в этом вопросе, сказав, что мы не будем поддерживать IE8. Мы не одиноки в таком решении, jQuery 2.0 идет по тому же пути, Google оставил в поддерживаемых браузерах только две последние версии IE и недавно отказался от поддержки и IE9 тоже, да и сам Microsoft постепенно отказывается от поддержки старых браузеров. Почему мы так решили? В основном, потому что мы используем геттеры и сеттеры для управления состоянием. Это было непростое решение, но было ощущение, что мы больше выиграем, чем потеряем. К сожалению, поскольку это фича непосредственно языка, ее не просто эмулировать (по крайней мере, я такого метода не знаю). И понятно, что для некоторых компаний отсутствие поддержки IE8 будет решающим моментом. Возможно к этому моменту кто-то уже написал плагин для browserify transform, который может это сделать, но мне о нем пока не известно. Если у вас есть, что предложить по этому поводу, пожалуйста, напишите, я буду очень рад, если мы сможем добавить поддержку IE 7 и 8 в Ampersand-State.

В заключение


Надеюсь, мне удалось донести до вас свои мысли и они оказались для вас полезными. Если у вас есть что сказать по этому поводу или если я что-то упустил или где-то ошибся, со мной можно связаться в Твиттере.
И конечно давайте вместе делать наши инструменты лучше. Нам нравится, когда к таким проектах подключается много людей. Пишите о найденных багах или выберите себе одну из открытых задач по вкусу и помогите нам сделать нужный патч.

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 104

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                                          Я уже привел свою аргументацию. Можно посмотреть на вашу?
                      0
                      Но в случае 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 вообще не нашел.
                        0
                        Картинки еле подгружаются, habrastorage по ним плачет :-)
                          0
                          спасибо, исправил
                        • UFO just landed and posted this here
                            +32
                            Развиваю на работе проект на 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) и кидайте ссылку в личку.
                              +1
                              Всяк кулик свое болото хвалит.
                                +7
                                Гм, вы так говорите, как будто у меня не было выбора. Как будто я был вынужден использовать только 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 Посмотрел предыдущий коммент оратора, понял, что это тролль. Зря распинался, ну ладно.
                                  +1
                                  Забыл упомянуть Meteor. Вычеркнул его из личного списка потому, что это тоталитарная секта. :)
                                    0
                                    можно подробней?
                                      +1
                                      У Meteor свой пакетный менеджер и свой репозиторий пакетов. Зачем пользоваться экосистемой npm, если можно запилить свою, с блэкджеком и шлюхами?

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

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

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

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

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

                                      У меня как фронтенд-разработчика сформировалось смутное представление о том, каким должен быть идеальный фрэймворк. 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 в отсутствие бэкенда.
                                        +1
                                        Приходится вручную в каждом компоненте цепочки для каждого прокидываемого события писать «когда в тебе вызывается событие А, вызови событие А на родителе». Это пока единственный случай, где в Ember мне пришлось писать обслуживающий код.

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

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

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

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

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

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

                                                Вот пример: 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» — это слишком сложно для неискушенных в Эмбере.
                                                  0
                                                  Но кстати, как выше написал lolmaus, лучше не инжектить сервисы напрямую в компоненты, а пробрасывать данные «вниз» по иерархии компонентов и экшены «вверх». Из-за большого упора Эмбера на раутинг обычно каждый конкретный «экран» вашего приложения — довольно простой, и совсем глубокой иерархии строить не приходится. Поэтому передача «вручную» на практике не является проблемой.

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

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

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

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

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

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

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

                                                  Вам понятно что там происходит только потому, что вы уже знаете 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.
                                                    –1
                                                    Цели, может, у вас и благородные, но на практике получается каша.
                                                      +2
                                                      Я вас уверяю, мне, как человеку, не знающему handlebars, синтаксис кажется гораздо более уродским,
                                                      <div>
                                                      {{input value="http://www.facebook.com"}}
                                                      </div>
                                                      

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

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

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

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

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

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

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

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

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

                                                  Чтобы не вдаваться в предметную область, рассмотрим искусственный пример. Пусть у нас есть две сущности: посты в блоге и комментарии. Помимо обычной связи один ко многим, мне нужно добавить еще одну в противоположном направлении. Например, пост может быть написан «по мотивам» какого-нибудь комментария. Технически связь хранится в поле 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?

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

                                                    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) и кидай ссылки в личку.
                                                      0
                                                      Да, ember-select-2 смотрится эффектно. В моем случае велосипеды обусловлены «утвержденным дизайном и стилем». Контролы оформлены в виде jQuery-плагинов, чтобы их можно было использовать в разных проектах на разных фреймворках. По этой же причине использую jQuery.deferred.

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

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

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

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

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

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

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

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

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

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

                                                      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 сейчас в бете. После резила документация подтянется, ориентироваться в модулях будет легко и удобно.
                                                        +2
                                                        Я не знаю насколько надо плохо делать дела с ангуляром что бы он жрал процессор когда пользователь ничего не делает.
                                                          –3
                                                          Он это делает по определению — гоняет свой digest несколько раз в секунду. Нагрузка на процессор тем больше, чем больше байндингов на странице.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                                                                        Only users with full accounts can post comments. Log in, please.