Репозиторий на Github
Всем привет! Спешу сообщить радостную новость. Наконец, вышла первая (1.0) версия фреймворка Матрешка. В этом посте я расскажу о самых важных изменениях во фреймфорке, о новом сайте и русскоязычной документации.
Напомню, Матрешка — JavaScript фреймворк для создания одностраничных приложений, соблюдающий несколько важных принципов:
- Никакой логики в HTML
- Минимум сущностей
- Произвольная архитектура
Матрешка реализует простой синтаксис двустороннего связывания данных и активно использует акцессоры (геттеры и сеттеры).
this.bindNode( 'x', 'input.my-node' );
this.on( 'change:x', function() {
alert( this.x );
});
this.x = 'Wow!';
В первую очередь, о важных изменениях во фреймворке
Последняя волна переименований. Самое важное из них:
bindElement
из-за длинного имени (11 символов) был переименован в bindNode (8 символов).Поддержка всех без исключения полей ввода, включая элементы из спецификации HTML5. bindNode больше не нуждается в третьем аргументе, в случае, если программист желает связать значение свойства объекта с каким-нибудь
<input type="datetime-local" class="my-input">
. this.bindNode( 'x', '.my-input' );
Поддержка цикла
for..of
для Matreshka.Array и Matreshka.Object. Если ваше приложение не нуждается в поддержке Internet Explorer либо если вы используете транспилер (например, Babel), можно смело пробовать новый, крутой синтаксис циклов из ECMAScript 6.for(let item of this) {
...
}
__this__
переименован в sandbox
. Теперь ключ, отвечающий за привязку песочницы, так и называется “песочница”.this.bindNode( 'sandbox', '.app' );
Появился новый кастомный селектор
‘:sandbox’.
Раньше нужно было использовать не самый удобный синтаксис, если требовалось выбрать песочницу или элемент внутри песочницы.this.bindNode( 'x', this.select( '.my-x-node' ) );
Теперь это можно сделать намного элегантнее:
this.bindNode( 'x', ':sandbox .my-x-node' );
Появился новый селектор
‘:bound(KEY)’
. В приложениях часто нужно привязывать элементы внутри других привязанных элементов, дабы не дублировать селекторы. Вот так это делалось раньше:// Vanilla
this.bindNode( 'y', this.bound( 'x' ).querySelector( '.my-y-node' ) );
Или так:
// jQuery
this.bindNode( 'y', this.$bound( 'x' ).find( '.my-y-node' ) );
Теперь то же самое можно сделать так:
this.bindNode( 'y', ':bound(x) .my-y-node' );
Полное совпадение методов Matreshka.Array со встроенными методами
Array
. По многочисленным просьбам push
и unshift
теперь возвращают длину массива, вместо ссылки на массив, как и в оригинальном Array.prototype
. Единственный метод, который до сих пор отличается от встроенного — это forEach
. Он возвращает “себя” вместо undefined
.Новые методы
Matreshka.Array
. При разработке приложений на базе Матрешки иногда требуется передать какие-нибудь данные в обработчик события изменения массива. Так как все методы встроенного
Array
работают аналогично встроенным, у нас нет возможности передать еще один аргумент при вызове этих методов.// каждый аргумент метода вставляется в массив
this.push( 1, 2, 3 );
Теперь каждый метод, изменяющий массив и позаимствованный из оригинального
Array.prototype
имеет двойника с именем МЕТОД_. Нижнее подчеркивание указывает на то, что последним аргументом являются произвольные данные для обработчика события или служебные флаги.this.on( 'modify', function( evt ) {
console.log( evt.customData );
});
this.push_( 1, 2, 3, {
customData: 42
});
Если требуется вставить элемент, не вызывая обработчик, нужно передать специальный флаг
silent: true
в объект события.this.push_( 1, 2, 3, {
silent: true
});
Как следствие, методы
silentPush, silentPop, silentSplice
… были удалены из фреймворка из-за отсутствия в них необходимости.Поддержка Babel. После исправления единственного бага, связанного со строгим режимом, Матрешка стала доступна для использования вместе с компилятором Babel. Кроме общих синтаксических сладостей, Матрешка поддерживает циклы
for..of
, о которых писалось выше, и наследование с помощью классов из ECMAScript 6 (благодаря прототипному наследованию, используемого Матрешкой с первого коммита на Github), вместо наследования функцией Class, которая входит в комплект Матрешки.Обратите внимание. Если приложение нуждается в поддержке Internet Explorer 8, использование функции
Class
обязательно. Функция использует специальные хаки, которые включают геттеры и сеттеры для объектов-экземпляров Матрешки.Как видите, было решено не отказываться от поддержки IE8. Код, отвечающий за работу фреймворка в восьмом “осле” не требует много места и слабо влияет на производительность.
Об остальных изменениях можно узнать на сайте.
Обновленная документация
Как показывает практика, камнем преткновения для любой библиотеки или фреймворка является документация. Скажем честно, документация, на момент выходя нулевых версий, была далеко не идеальной. Вещи, типа itemRenderer, не были описаны вовсе (был приведен малопонятный пример и более ничего).
Теперь в документации описаны все без исключения свойства и методы, а текст, кроме английского, доступен и на на русском языке.
С чего начинать?
Пытаясь изучить новый инструмент, включающий в себя много деталей, часто не понимаешь, с чего начать своё обучение. Этим грешит большинство фреймворков: огромное количество свойств, методов, функций, директив… может расстроить или вовсе отпугнуть новичка.
Эта проблема была решена очень просто: самые важные методы и свойства помечены красным флажком . Те свойства и методы, которые не имеют такого флажка — необязятельны к изучению. Например, крутой метод linkProps, добавляющий зависимость одного свойства от других, можно вовсе не использовать, ограничившись прописанным вручную обработчиком события.
Адаптивная верстка и чтение оффлайн
Документацию теперь удобно использовать не только с настольных компьютеров и ноутбуков, но и с мобильных телефонов и планшетов. Сайт работает оффлайн, благодаря использованию HTML5 cache. Эта страница теперь может стать полезным чтивом, в том числе, в дороге или при отсутствии интернета.
Репорт об опечатках
Сообщить об опечатке или ошибке можно было и раньше, но теперь у окна опечатки появился дизайн :) Можно выбрать сомнительный текст на сайте и нажать Ctrl+Enter. После этого откроется модальное окно с формой.
Подробнее о том, как сделать окно опечаток и ошибок на сайте, используя Google Forms, можно прочесть здесь.
Комментарии прямо в документации
У каждого элемента документации (класс, метод, свойство) есть кнопка “задать вопрос”, которая вызывает Muut Comments (почему, расскажу ниже). Вам не нужно искать соответствующий форум или создавать тикет на Github, можно задать вопрос по части документации прямо из самой документации.
В первых двух версиях использовался Disqus, а, затем, Facebook Comments. Обе системы, к сожалению, не оправдали возложенных на них ожиданий.
Disqus постоянно путает идентификаторы и адреса страниц, комментарии появляются не там, где нужно. Админпанель не позволяет удалять обсуждения, а изменение ссылок вручную не помогает. Это старая проблема Disquss, которую решить пока нельзя (разработчики рекомендуют убедиться в правильности объявленных переменных, которые часто просто-напросто игнорируются системой). Причина, скорее всего, кроется в том, что обсуждения находятся на одной странице, а Disquss с этим испытывает огромные проблемы. Как следствие, было решено перейти на другое бесплатное решение, от которого тоже пришлось отказаться.
Facebook Comments, на первый взгляд, показался неплохим решением задачи. Разработчик — многомиллиардная компания; многие зарегистрированы в этой соцсети; не нужно логиниться, чтобы написать комментарий; идентификаторы не путаются… Проблема одна: уведомления. Facebook Comments не умеет сообщать о новых комментариях модераторам (!). Для обхода был написан костыль, использующий Google Forms в качестве системы уведомлений. Но это полбеды. Самое неприятное — уведомления об ответах на комментарий совершенно неинформативны.
Упомянул в комментарии… В каком? Где?
В общем, пришлось покопаться еще…
IntenseDebate
- Саппорт не отвечает на вопросы.
- Сам виджет выглядит устаревшим.
- Создается впечатление, что проект больше не поддерживается.
Cackle
- Комментарии для каждого сайта стоят 500 рублей/год. Так как документации две, прийдется раскошелиться на два пакета. Если появится еще одна версия документации прийдется снова достать кошелек.
- Название. Очень тяжело себя убедить пользоваться чем-то с названием “какл”.
SolidOpinion
- Саппорт не отвечает на вопросы.
- Проект выглядит заброшенным.
В итоге, самым адекватным (но не идальным) решением оказался неизвестный мне ранее Muut. У них есть бесплатная подписка, хороший саппорт, нет проблем с идентификаторами (опять я о них). Единственный минус — всё те же уведомления об ответах. Они приходят только тогда, когда у подписавшегося пользователя не открыто ни одной вкладки с Muut. Кроме этого, уведомления для админа отсутствуют (хотя заявлены, даже флажок есть в настройках). Приходится подписываться на все комментарии вручную и, на всякий случай, следить за новыми комментариям, заходя в админку. Посмотрим, что из этого выйдет. Пока что, пытаюсь бороться с саппортом, чтоб исправили некоторые неприятные баги.
Всё подряд или по одному? *
* Классу, методу, свойству
Новый сайт Матрешки был создан после взвешивания всех плюсов и минусов документаций к другим популярным и не очень популярным фреймворкам. Первым вопросом, который требовалось решить был выбор между двумя подходами в структурировании документации: размещение всех материалов на одной странице, либо же разбиение статей на отдельные страницы. Решением стал переключатель режимов (в верхней части меню есть кнопки “Все подряд” и “По одному”), оставляющий выбор на усмотрение посетителя.
«Материальный» дизайн
На сайте используется CSS фреймворк Materialize. К сожалению, все анимации в этом фреймворке основывались на манипуляциях с DOM, которые не благотворно влияют на производительность страницы (особенно на мобильных устройствах), поэтому, был использован только CSS и только необходимые части. Код, отвечающий за анимации (например, за выезжающее меню) пришлось переписать. В следующих версиях Materialize, надеюсь, исправят большинство подобных недоразумений.
Другие новости
- Вся документация была вынесена из js файлов в отдельный репозиторий. Теперь .jsdoc файлы можно подключить в IDE отдельно.
- Обновлен код TodoMVC и создана русскоязычная версия документации к коду, а исходник обрел собственный репозиторий.
- Исходник к сайту и и генератору документации поменял своё местоположение.
- Матрешка теперь размещена на двух CDN: cdnjs и jsdelivr (очень рекомендую этот CDN разработчикам библиотек и других скриптов, и спасибо jimaek, за помощь и быструю реакцию на вопросы).
Отдельное спасибо designiac который разработал новый логотип и принимал участие в создании сайта и Rendol, который помогает развивать проект, внося свои идеи и сообщая о неочевидных проблемах.
Следите за новостями в блоге. В среду на Хабре выйдет краткий туториал к Матрешке.
Спасибо за внимание. Всем добра.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
getId
Ура! Ещё один js framework.
yurash
хоть и опечатка, но забавно получилось. Раз Matreshka, значит нужен не materialize а matreialize
xxxTy3uKxxx
Заголовки для TypeScript есть в планах?
Finom Автор
Пока нет, но Матрешка всегда открыта для пулл-риквестов.
xxxTy3uKxxx
Отлично, есть чем себя занять. Спасибо за хороший фреймворк
lega
В одном из предыдущих постов спрашивал и не получил ответа — есть ли возможность работать со вложенными объектами, например:
Не могли бы вы добавить Matreshka.js в «местный» бенчмарк.
Finom Автор
Я бы лучше создал новый объект:
Вопрос по вашему бенчмарку добавил в список дел.
Результат не самый лучший. Матрешка обгоняет Реакт только в ИЕ.
Вставка 100 элементов
Матрешка либо обгоняет либо стоит на ровне с другими фреймворками, кроме Ember. Странно, что самый быстрый (по слухам) React отстает местами от Angular.
Вставка 1000 элементов
Все фреймворки позади (они даже не видны на графике из-за значений < 1 операций в секунду), кроме Ember. React еще больше удивил.
Вывод можно сделать такой: при небольшом количестве элементов Матрешка немного отстает от других фреймворков но разница в скорости, как правило, не заметна при таком объеме данных. Начиная со ста элементов, Матрешка часто быстрее Реакта, «самого быстрого фрефмворка».
Интересно, что, Матрешка выигрывает у всех в IE (извините, так получилось). Ember оказался самым быстрым из этого списка почти при любом раскладе.
lega
Knockout.js нужно тестировать асинхронно, т.к. у него рендер идет через setTimeout.
Ember не может быть самым быстрым т.к. он перерисовывает весь DOM, когда другие делают это «точечно».
Все тесты влияют друг на друга, т.к. при запуске перед ними разное кол-во DOM. Тесты провоцируют разный рендеринг — где-то есть перенос, где-то нет, какие-то тесты «двигают» всю страницу — это бъет по производительности.
Он не самый быстрый, если перефразировать слова его разработчиков — React быстрее чем Ангуляр если тест для Ангуляра сделать не правильно.
Finom Автор
Если нужно использовать объект, то у Матрешки есть метод set (он может принимать объект).
lega
Я просто хочу найти эквивалентный код, в ангуляре мне через ajax прилетают данные, я их просто помещаю в модель — все работает, например такой код:
Полученный JSON:
Получаем данные и помещаем в scope.
И на например «прибиндино» 2 поля:
Я так понял что матрешка не рассчитана на работу с «иерархическими данными» (речь про данные, не про рендеринг), и в данном случае нужно за ранее создавать все возможные объекты, делать к ним биндинг, а для присвоения нужен врапер который будет копировать все значения.
Хотя можно перенести все значения в один объект (в «корень»), но все равно это заставляет меня перемещать данные туда-обратно.
Finom Автор
Понял проблему. Как раз недавно возникла идея статичного метода
toMatreshka
(или простоto
), которая конвертирует объект и его внутренности в экземпляры Матрешки. А для расширения такого объекта можно было бы воспользоваться аналогом merge из underscore.Установим дефольные значения объекту
Как идея?
Но подход вызывает вопросы:
— Eсли внутри объекта содержится массив, заменять все элементы или добавлять?
— Если в дереве объекта найден необъявленный ранее объект, конвертировать ли его в Матрешку или оставить обычным объектом?
В общем, нужно подумать. Спасибо за то, что прояснили ситуацию. Такой возможности действительно сейчас нет.
palkan
В TodoMVC баг, однако: добавил два пункта, затем на одном кликнул на крестик – пишет, что «1 items left», а показывает два (Chrome, MacOS).
Finom Автор
Уже исправлено. Баг был связан с небольшим упущением при большом рефакторинге Matreshka.Array.
palkan
А может стоит покрыть код тестами, а уже потом выпускать версию 1.0?
Вот все круто, но глупый баг в демо приложении и отсутстие тестов – это повод перестать рассматривать Матрешку для production целей.
Finom Автор
Автоматическое тестирование, конечно, будет. Но, в целом, Матрешка достаточно стабильна, а фичи обкатываются в продакшне по несколько месяцев перед выходом релиза. Спешка с рефакторингом — результат спешки со статьями, дабы удовлетворить условия оферты Хабра по блогу компании. Прошу прощения за неприятное недоразумение.
StreetStrider
Две вещи вызывают некоторое опасание:
1. Использование собственных коллекций. Я понимаю, это нужно для более прямолинейной реализации биндинга через аксессоры, но множество других библиотек подобного типа умудряются делать такие вещи подкапотно (дельты / dirty-checking), так что модели пользователя (программиста) не трогаются. Я лично считаю, что очень важно уровень данных оставлять максимально независимым от библиотек. Это намного более лучшая интеграция и меньше отторжения у пользователя. Мне лично не нравится, что каждая либа считает вправе указывать мне какие модели использовать и как строить архитектуру.
2. Вызывает опасение этот код:
this.on( 'change:x', function() {
, а именно строковой литерал. Каждый раз, как архитектура становится достаточно сложной, приходится конструировать эти строки, соединять все эти change/пространства имён/идентификаторы и тому подобное. Строковой литерал должен быть строковым литералом и лучше в строках важные детали архитектуры не хранить. То есть здесь явно две сущности: change — имя события, x — конкретное имя биндинга. Минимальное что можно сделать, это разбить их на два аргумента, тем более, я уверен, под капотом это всё равно делается.Да, не считайте это негативной критикой. Это просто мнение. Проект интересный, развивайте его дальше и желаю вам успехов.
lega
Поддерживаю, а то уже есть фреймворки у которых не только данные «в обертках», но «свой» DOM, свой ajax, свой сборщик и т.д.
Finom Автор
Тогда пропадет возможность использования всяких плюшек, типа делегированных событий, зависимостей свойств друг от друга и пр.