image



Краткий обзор простого фреймворка для создания одностраничных приложений Matreshka.js. В посте используется ECMAScript 2017, который можно переписать на ECMAScript 5.


Основные функции


Функция bindNode связывает свойство и элемент.


const object = { name: 'Brendan' };
const node = document.querySelector('.name');
Matreshka.bindNode(object, 'name', node);
object.name = 'Doug';


Если свойство меняется, меняется и элемент, если элемент меняется (например, пользователь вводит текст), меняется и свойство. Из коробки Matreshka.js умеет обрабатывать любые элементы форм. Можно объявить байндинг для произвольных элементов см. документацию.


Функция calc связывает одно свойство с другими.


Matreshka.calc(object, 'fullName', ['firstName', 'lastName'], (firstName, lastName) => {
    return `${firstName} ${lastName}`
});
object.firstName = 'Brendan';
object.lastName = 'Eich';
// ...
console.log(object.fullName); // "Brendan Eich"

Когда меняется свойство-источник (firstName или lastName), меняется и свойство-цель (fullName).


Вместе с функцией bindNode можно объявлять длинные цепочки зависимостей: свойство a зависит от состояния элемента e1, свойство b зависит от свойства a, свойство c зависит от элементов e2 и e3 и от свойства b, изменение которого, как следствие, меняет e1, e2 и e3...



Такие зависимости можно представить как таблицу в табличном процессоре (например, Excel): в каждый момент времени вы думаете об одной формуле, а не о многочисленных связях все ячеек. Как следствие, получаете меньше багов, так как нужно думать об атомарных сущностях, а не обо всей "таблице" (приложении). Больше информации в документации.


Функция on ловит, а trigger генерирует события.


Matreshka.on(object, 'something', () => alert('something is happened'));
Matreshka.trigger(object, 'something');

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


Matreshka.on(object, 'change:fullName', async () => {
   await fetch('/api/name', { method: 'post', body: this.fullName });
   // ...
})


События в Matreshka.js — это отдельная тема. Можно объявлять делегированные события объекта (слушать изменения в глубине дерева объектов), DOM события, делегированные DOM события и пр. Читайте подробную статью на эту тему.


Функция mediate добавляет рантайм валидацию и конвертацию значений свойств. Например, можно объявить свойство определенного типа, можно ограничить свойство указанным диапазоном, можно генерировать исключение, если необходимо.


Matreshka.mediate(object, 'x', x => String(x));
object.x = 42;
console.log(object.x, typeof object.x); // "42", "string"

Классы


Экземпляры класса Matreshka содержат те же методы, работающие с объектом, с тем отличием, что не нужно передавать объект первым аргументом: им становится this.


class User extends Matreshka {
  constructor() {
    super();
    this.bindNode('fullName', '.full-name');
    this.calc('fullName', ['firstName', 'lastName'], (firstName, lastName) => {
        return `${firstName} ${lastName}`
    });
    // chained call can be used there:  super().bindNode(...).calc(...);
  }
}

Этот класс объединяет описанные ниже классы Matreshka.Array и Matreshka.Object, объявляя общие для всех классов методы.


Класс Matreshka.Object отвечает за данные, типа "ключ-значение". Это данные, которые разработчик желает отделить от всех остальных свойств и, скажем, отправить на сервер или сохранить в локальном хранилище. Для этого фреймворку нужно указать на то, какие свойства отвечают за бизнес логику (например, имя пользователя), какие за временное состояние приложения (например, виден ли DOM элемент). За это отвечает метод addDataKeys.


class User extends Matreshka.Object {
  constructor() {
    super();
    this.firstName = 'Brendan';
    this.lastName = 'Eich';
    this.language = 'JavaScript';
    this.addDataKeys(['firstName', 'lastName']);
    console.log(JSON.stringify(this)); // '{"firstName": "Brendan", "lastName": "Eich"}'
  }
}

Matreshka.Array — отвечает за массивоподобные коллекции во фреймворке. Экземпляры, помимо методов унаследованных у Matreshka, содержит методы из нативного Array (push, splice, map, reduce...).


Для коллекций, подобно Backbone.Collection, можно указать "модель" (свойство Model) с тем отличием, что ею может высупать любой класс.


class Users extends Matreshka.Array {
  get Model() { return User; }
  constructor() {
    super();
    this.push({ firstName: 'Brendan', lastName: 'Eich' });
    console.log(this[0] instanceof User); // true
  }
}

Коллекция может автоматически рендериться при изменени содержимого. Для этого нужно указать куда вставлять новосозданные DOM элементы и как их рендерить. Для указания места рендеринга, нужно привязать свойству sandbox, либо свойству container (разницу см. в документации) DOM узел. Для указания того, как рендерить элемент, нужно восмользоваться виртуальным методом itemRenderer (либо определить renderer для модели).


class Foo extends Matreshka.Array {
  itemRenderer() {
     return '<div>Hello, world!</div>';
  }
  constructor() {
    super();
    this.bindNode('sandbox', '.sandbox-node');
    this.push({}); // inserts <div>Hello, world!</div> to .sandbox-node
  }
}

Подробнее о классах в посте "От простого к простому".


Всё указанное выше можно импортировать в качестве CJS/ES2015 модуля:


import calc from 'matreshka/calc';
import MatreshkaArray from 'matreshka/array';

Роутинг


За роутинг отвечает отдельная библиотека matreshka-router. Она связвает части адреса со свойствами:


Matreshka.initRouter(object, '/a/b/c/');
object.a = 'foo';
object.b = 'bar';
object.c = 'baz';

// makes location.hash to be #!/foo/bar/baz/

Подробно описано в статье.


Вместо вывода


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

Всем спасибо.

Поделиться с друзьями
-->

Комментарии (21)


  1. neoxack
    03.04.2017 10:17
    -1

    Matreshka.js заполняет пропасть между джуном и сеньором

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


    1. Finom
      03.04.2017 10:18
      -1

      Цитирую с сайта:


      Для кого этот фреймворк?


      • Для новичков в веб программировании, желающих освоить разработку одностраничных приложений
      • Для full-stack разработчиков, для которых front-end разработка стоит на втором месте после back-end
      • Для всех тех, кого не устраивает текущий порядок вещей во Вселенной веб разработки


      1. justboris
        03.04.2017 11:18
        +2

        Позволю себе не согласиться с вашим позиционированием:


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

        Новички скорее всего будут смотреть на React, обучающих видео и статей по нему немало


        Для full-stack разработчиков, для которых front-end разработка стоит на втором месте после back-end

        Бекендщики с большей вероятностью посмотрят на Angular2, потому что там есть DI, MVC и типизация


        Для всех тех, кого не устраивает текущий порядок вещей во Вселенной веб разработки

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


        1. Finom
          03.04.2017 11:50

          Новички скорее всего будут смотреть на React, обучающих видео и статей по нему немало

          Есть такое понятие, как JavaScript усталость. Слишком много всего нужно знать помимо, собственно Реакта: сборка, стор, оптимизация рендеринга (чем, к сожалению, часто пренебрегают).


          Бекендщики с большей вероятностью посмотрят на Angular2, потому что там есть DI, MVC и типизация

          Смотря кто. По моему опыту общения с разработчиками, бек-ендщики (например, PHP-шники), как правило, не уделяют много внимания фронт-енду и обходятся неструктурированным кодом на jQuery. React/Angular/Vue — это то, что их не интересует (это не касается людей, пишуих под NodeJS).


          1. Razaz
            03.04.2017 12:20
            -1

            Как бэкенд разработчик, который интересуется React/Angular/Vue, не соглашусь :) Тут проблема не в разработчиках, а в требованиях. Я на своих проектах достаточно трепетно отношусь к выбору запчастей к frontend и сейчас потихоньку переезжаем на React с первого Angular. Еще и codestyle стараемся поддерживать. То, что front не основной приоритет, не означает, что там можно болт забивать.


            1. Finom
              03.04.2017 12:29

              В общем, всё вышесказанное, можно свести к "Я умею что-то на jQuery, но хочу делать лучше" и таких разработчиков немало. Причем, остальное (сборка, пакеты, ECMAScript Stage X) можно учить постепенно, по-прежнему используя Matreshka.js.


              1. Razaz
                03.04.2017 12:51

                Ну мы как-то осилили и сборку, и тестирование. Вынесли фронт в отдельный репо, собираем на TFS и закидываем в локальный NPM. На том же Egghead столько материала по теме, что грех не разобраться. Думаю основной фактор это лень и фу фу фу относительно JS ?\_(?)_/?
                Тот же React + TSX вот отлично зашел ;)


                1. Finom
                  03.04.2017 12:55

                  Ну такое. Не только выучить, но и заюзать это всё не так просто. У многих возникает шок от того, что веб разработчик, оказывается. должен знать NodeJS, даже если пишет только под фронт. Это я не говорю об остальном инструментарии. Если вы осилили (изучили и смогли использовать) все необходимые технологии за пару месяцев, примите моё уважение.


                  1. Razaz
                    03.04.2017 13:09

                    Ну ноду вообще полезно знать и юзать. Вот пример: утилита на .Net ставится через npm и позволяет генерить клиетов к OpenApi(мы через gulp делаем). ИМХО если можешь в инженера, то пофиг на чем. Общее чувство прекрасного не даст делать каку ни в фронте ни в бэке :D


          1. justboris
            03.04.2017 12:36
            +1

            Есть такое понятие, как JavaScript усталость. Слишком много всего нужно знать помимо, собственно Реакта: сборка, стор, оптимизация рендеринга (чем, к сожалению, часто пренебрегают).

            И чем же ваша библиотека здесь больше подходит? Лучше оптимизирует рендеринг?
            А про усталость и сложные инструменты уже давно неправда и не надо поддерживать этот миф. Вот, например, недавний пост о там как быстро начать разрабатывать на React


            1. Finom
              03.04.2017 12:42

              Лучше оптимизирует рендеринг?

              Если вы хорошо разбираетесь в React можем подискутировать (так как я и сам в нем неплохо разбираюсь). Если нет, я бы не хотел в этом посте описывать принципы рендеринга в Реакте, есть масса статей на эту тему.


              уже давно неправда и не надо поддерживать этот миф.

              Поговорите с любым начинающим разработчиком, для начала. Немало людей забивают на веб разработку, узнав о том, сколько вего им нужно знать, чтоб написать грамотный Hello World, используя один из мейнстримных фреймворком.


              1. justboris
                03.04.2017 12:54

                Открываем документацию React, ищем раздел "Installation", читаем


                You don't need to install anything; you can just modify the code and see if it works.

                То есть берем React с CDN, подключаем на страницу и начинаем писать.


                Для более сложных вариантов есть CLI, о котором там тоже рассказывается.


                Что из этого кажется сложным и отпугивает людей?


                1. Finom
                  03.04.2017 12:57
                  +1

                  Вы на полном серьезе вырываете из контектста раздела "Trying Out React" эту фразу?


                  1. justboris
                    03.04.2017 13:00

                    Не вырываю из контекста, а выборочно цитирую. Не превращать же этот тред в копипасту документации React.


                    Вы пишете


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

                    Я привожу пример минимального Hello World из документации. Что здесь не так?


                    1. Finom
                      03.04.2017 13:05

                      Это не просто Hello World, это — quick and dirty Hello World. Такой код никогда не должен попасть в продакшн, уж лучше на jQuery намакаронить.


                      Я так понимаю, у вас достаточно мало знаний относительно React. Тогда, давайте прекратим эту беседу.


      1. Singaporian
        04.04.2017 12:54

        Спросили «для ЧЕГО», а не «для КОГО».
        Это многое меняет. Вопрос для кого не отвечает, что с ней надо делать.


  1. justboris
    03.04.2017 11:18

    del


  1. grossws
    03.04.2017 21:27

    Уберите простыню под кат.


  1. shimanskybiz
    04.04.2017 00:06

    Мое мнение:
    1) Невнятное описание либы (на гитхабе и на .io), если это для SPA, так и напишите, посмотрите, как кричат реакт (will efficiently update and render just the right components when your data changes) и вю (тоже невнятно, но глаз цепляется за Virtual DOM, и уже знаешь зачем).
    2) В последнее время, нетолько усталость от JS, но и от фреймворков. Мне устраивает microjs подход — копилка микролибов, выполняющих одну задачу, и жонглируешь ими в зависимости от задач.
    3) Согласен, что в последнее время оверинджениринг в вебразработке доставляет.


    1. Finom
      04.04.2017 00:06

      Обновил описание в репозитории, спасибо.


      1. vlasenkofedor
        06.04.2017 11:52
        +2

        Спасибо за новый реализ.
        В свободное время стараюсь глянуть на реализацию (исходный код)

        Мне устраивает microjs подход — копилка микролибов, выполняющих одну задачу

        У Finom там-же лежит микролиба Balalaika, реализация которой достойна для ознакомления Js программистов