Веселый стейт менеджмент фреймворк Huex

    image

    Введение


    Меня всегда удивляло, как много действий надо делать для стейт менеджмент фреймворков — сразу описывать схему, писать мутации, комитать их… Почему бы не сделать всё минимально просто?)

    Зачем писать код, когда его можно не писать?

    (updated)
    Представляю вашему вниманию мою получасовую поделку — Huex!

    Пока что решение доступно только на платформе NodeJS, но для презентации думаю будет достаточно.

    Дисклеймер: Huex написан мной всего лишь в развлекательно-образовательных целях и не претендует на место полноценного фреймворка. А может и претендует. А теперь поехали.

    Для чего он нужен?


    Иметь единое удобное хранилище данных. Иметь возможность следить за их изменениями. Избавится он непонятных слов вроде «getters», «mutators», «actions», «commit», etc.

    Как его установить?


    Пока только скопировав этот репозиторий.
    После того, как репозиторий скопирован, его нужно подключить через package.json вашего проекта где-то в таком виде:

    "dependencies": {
        "huex": "file:../huex/"
      }

    После этого он будет доступен как модуль «huex».

    Или сделать еще проще, как верно заметил dpr:
    npm i -S https://github.com/vssenko/huex.git

    Как им пользоваться?


    Максимально естественно и просто. Начнем сразу с кода:

    // Подключаем huex.
    const Huex = require('huex');
    
    // Создаем хранилище.
    const storage = Huex();
    
    // Добавляем обработчики на изменение какой-либо переменной.
    storage.on('change:a', (e) => console.log(`Property "a" was changed: ${e.value}`));
    
    // Меняем значение переменной самым натуральным образом.
    storage.a = 5;
    

    И это всё. При любом изменении\установки поля нашего хранилища будут создаваться два события: change с данными { key, value } и change:key с данными { value }.
    (updated)
    А для вложенных объектов и массивов, события будут созданы как у вложенного объекта, так и у родителя.
    Достаточно для создания проектов любой сложности.

    Может что-то еще?


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

    const Huex = require('huex');
    
    const storage = Huex();
    
    storage.a.b.c.d.e = 5;
    

    И разумеется на все вложенные объекты так же можно навесить обработчики событий.

    (updated)

    Может еще что-то еще?


    Да! Теперь Huex работает не только с простыми данными, но и с объектами и массивами, на ходу переделывая их в Huex-хранилища!
        sut.subSut = {
          a: 5
        };
    
        sut.on('change:subSut', (e) => {
          console.log(e.key); // subSut
          console.log(e.value.a) // 10
          console.log(e.nested); // { key: 'a', value: 10 }
        });
    
        sut.subSut.a = 10;
    


    Еще больше примеров доступно в тестах проекта.

    А в чем подвох?


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

    (update)

    Заключение


    За два цикла (вечера) разработки у JS-сообщества появился еще один интересный фреймворк.
    Что Huex умеет:
    • Инициализироваться из объекта\массива
    • Сохранять значения путем простого присваивания
    • Триггерить события при изменения себя как объекта или как массива
    • На ходу переделывать записанные в него объекты\массивы в Huex-хранилища
    • Триггерить события при изменения поля-объекта или поля-массива
    • На ходу генерировать пустые хранилища при обращении к несуществующему полю (спорная фича, но очень прикольная)

    Что Huex не умеет:
    • Быть быстрым :-). Хотя, как заметил Drag13, прогресс в сторону скорости работы Proxy всё же есть, поэтому вдруг такой подход станет популярным.
    Поделиться публикацией

    Похожие публикации

    Комментарии 22
      +1
      В V8 прошлым летом прокси немного оптимизировали так что стало получше. Ну и VueJs собираются его использовать (собирались когда я последний раз смотрел)

      И да, название замечательное :)
        0
        MobX c 5 версии тоже на него перешел.
        +5
        Huex, Huex и в продакшен ))
          0

          «Я поглядела, Huex у него торчит!» ©

          0
          Как вы яхту назовёте… :)
            0

            Не совсем понятен вот этот момент:


            if (value instanceof Object) {
              value = huex(value);
            }

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


            const storage = huex();
            storage.on('change', console.log);
            storage.a = {prop: 1}; // разве тут не потеряется {prop: 1}
            storage.b = 10

            Вот что node показывает
            image

              0
              А, это я пытался сделать так, чтобы можно было присваивать объекты и они точно так же становились Huexами, но потом на это забил, т.к. пришлось бы анализировать и вложенные объекты и т.д… Короче, есть вот такое небольшое ограничение, которое в целом можно исправить, но не нужно. Спасибо, что обратили внимание, чуть-чуть подчищу код.
                +1

                А вы действительно считаете, что эта статья нужна на Хабре? Просто, сами признаете, что "проект-однодневка", "делали по фану", зачем тогда статью вообще делать? Написали бы лучше про Proxy, и как бы их можно использовать, чем делать "недо-библиотеку"

                  +1
                  Да, действительно так считаю. Как раз подход через использование Proxy заслуживает того, чтобы быть здесь. Статья не только «однодневка», «по фану», но еще и в какой-то степени образовательная (вот люди некоторые узнают про Proxy, посмотрят код). В конце концов, я специально написал дисклеймер, чтобы вы могли пропустить её и не тратить своё драгоценное время.
                    0
                    Не останавливайтесь на достигнутом! Вы написали Backbone.Model, но как же Backbone.View и все-все-все?

                    Я о том, что каждые полгода в мире появляется по новому клону Backbone, но с использованием новых стандартов ECMAScript, самый примечательный, наверно — backbone-es6 трёхлетней давности. А ваш шуточный проект вполне может занять свою нишу в мире, если вы полностью завершите порт Backbone на новые подходы.
                      0

                      Спасибо) сейчас скорее допишу для Huex возможность четкой работы с объектами и массивами)

                    0

                    Пятница же, самое время для таких проектов и статей (пардон, это у нас на Дальнем Востоке уже пятница).

                  0
                  Не думаю, что вас очень это заботит, но теперь Huex умеет отслеживать установку значений-объектов и значений-массивов :-)
                  0

                  "стейт менеджмент фреймворк" — это на каком языке? :)

                    0

                    На языке человека со скудным словарным запасом. Руслиш :-(

                      0

                      Хмм, а расскажите пожалуйста, как это выразить на исконно-русском? Вот без всех этих тюркских, греческих, финно-угорских, французских заимствований?

                        0

                        Не стоит бросаться из крайности в крайность и пытаться выразить всё исключительно на исконно русском. Почему бы не сформулировать как "фреймворк управления состоянием"? Или, если вам кажется, что state management лучше оставлять транслитерированным, то "фреймворк для стейт-менеджмента" будет грамматически правильнее.

                          0
                          Тем не менее часть словосочетания при любом варианте останется непереведённой, так что — по большому счёту — какая разница? Особенно в пятничной статье написанной за 30 минут (предположение)

                          Собственно в своём комментарии я ставил цель проиллюстрировать, что ваша претензия выше является крайностью, как вы сами и подтвердили
                      +1
                      Пока только скопировав этот репозиторий. Я не хотел засорять npm полубессмысленными пакетами.

                      Зачем же вручную копировать:
                      npm i -S https://github.com/vssenko/huex.git
                        0

                        Точно, забыл про это, спасибо!

                          0
                          JFYI: флаг -S не нужОн начиная с NPM версии 5. Его вообще в документации нет.
                            0
                            Спасибо, не знал.

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

                        Самое читаемое