Всем привет! В данной статье я бы хотел рассказать о таком фреймворке как Cample.js.

На сегодняшний момент (версия 3.0.1), фреймворк является активно поддерживаемым в разработке нового функционала. Есть поддержка работы с данными, которые благодаря реактивности без виртуального DOM отображаются крайне быстро:

Тесты быстродействия фреймворка(js-framework-benchmark)
Тесты быстродействия фреймворка
(js-framework-benchmark)

Это не самый быстрый результат из всех, которые существуют на данный момент среди фреймворков. Но, поэтому речь идёт о перспективности.

К примеру, у Vue скорость создания 1000 строк составляет 42 секунды, а у Svelte 48.4 секунды (на момент написания статьи).

Конечно, эти фреймворки во много раз превосходят Cample.js по функционалу и сравнение недостаточно полное. Но, в данном сравнении берётся лишь такой пункт как скорость.

Сама разработка фреймворка началась около года назад. Тогда, была выбрана модель создания компонентов через экземпляры классов. То-есть, компоненты создаются следующим путём:

const component = new Component("new-component", 
`<div class="component">
    {{component_text}}
</div>`)

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

const newComponent = component("new-component", 
`<div class="component">
    {{component_text}}
</div>`)

Также, была выбрана модель обработки данных через функцию, возвращающую объект с данными. Сами данные отображаются в HTML template благодаря интерполяции строк.

const newComponent = component("new-component", 
`<div class="component">
    {{component_text}}
</div>`),
  {
    data: () => {
      return {
        component_text: "Text",
      };
    },
  })

Эта конструкция позволяет обрабатывать данные гораздо лучше, чем если бы просто передавался объект.

Также, для изменения данных используются функции, которые передаются через свойство script. Сами функции объявляются в объекте functions.

const newComponent = component("new-component", 
`<div class="component" id="el">
    {{component_text}}
</div>`),
  {
    data: () => {
      return {
        component_text: "Text",
      };
    },
    script: [
      ({ elements, functions }) => {
        const setText = (e) => {
          functions?.setText((data) => {
            return "NewText";
          });
        };
        elements?.el?.addEventListener("click", setText);
      },
      {
        start: "afterLoad",
        el: [{ el: "#el" }],
      },
    ],
    functions: {
      setText: "component_text",
    },
  })

Также, у фреймворка присутствует объект each, который повторяет HTML разметку в зависимости от данных.

const newEach = each("new-each",
()=>["val"], 
"<div>{{data}}</div>",
{
  valueName:"data"
}
);

Все эти компоненты обрабатываются через экземпляр объекта Cample следующим способом.

cample("#example", {
  trimHTML: true,
}).render(
  `
            <div class="example_page">
                {{newComponent}}
                {{newEach}}
            </div>
        `,
  {
    newComponent,
    newEach
  }
);

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

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

Если у вас есть мнение по данному фреймворку, будет очень интересно почитать о нём в комментариях! Спасибо большое за прочтение статьи.

Ссылки:

Github

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


  1. SWATOPLUS
    06.07.2023 17:29
    -8

    Без jsx, это не имеет смысла.


    1. antonmak1 Автор
      06.07.2023 17:29

      jsx конечно удобен, но он всё таки не панацея


  1. nin-jin
    06.07.2023 17:29
    +6

    1. flancer
      06.07.2023 17:29
      +1

      mol слишком революционен для масс. Я, например, так и не понял, как мне с помощью mol подключить реактивность на HTML-страницу. Вот пример, как подключается vue-реактивность:

      <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
      
      <div id="app">{{ message }}</div>
      
      <script>
        const { createApp, ref } = Vue
      
        createApp({
          setup() {
            const message = ref('Hello vue!')
            return {
              message
            }
          }
        }).mount('#app')
      </script>

      У Cample.js та же самая проблема - я не вижу, как его подключить к существующей HTML-странице и использовать в качестве внешней библиотеки (как тот же jQuery).

      Это одна из причин, почему я у себя использую vue. Web-приложение - это прежде всего HTML/CSS/JS (WebAssembly пока и близко не стоит к). Всё остальное в веб-разработке лишь инструментарий для сведения к этой триаде чего угодно (включая TypeScript, и включая Tree).

      Притягивая за уши аналогии с церковью: зачем мне говорить со священником, если я могу говорить напрямую с Богом?


      1. nin-jin
        06.07.2023 17:29

        Тут есть пример: https://page.hyoo.ru/#!=o510xj_6e9jo1


        1. flancer
          06.07.2023 17:29
          +5

          В нем нет объяснения, где я возьму исходник для этого импорта:

          import { $mol_wire_dom, $mol_wire_patch } from "mol_wire_dom";

          Это не работающий пример. Рабтающий пример вот: https://jsfiddle.net/05hm6Lkt/

          <div id="root">
          
            <div id="form">
            
              <input id="nickname" value="Jin" />
              <button id="clear">Clear</button>
              
              <label>
                <input id="greet" type="checkbox" /> Greet
              </label>
              
            </div>
          
            <p id="greeting">...</p>
          
          </div>
          
          <script src="https://unpkg.com/mol_wire_dom/web.js"></script>
          
          <script>
          // Make DOM reactive
          $mol_wire_dom( document.body )
          
          // Take references to elements
          const root = document.getElementById( 'root' )
          const form = document.getElementById( 'form' )
          const nickname = document.getElementById( 'nickname' )
          const greet = document.getElementById( 'greet' )
          const greeting = document.getElementById( 'greeting' )
          const clear = document.getElementById( 'clear' )
          
          // Set up reactive formulas
          greeting.__defineGetter__( 'textContent', ()=> 'Hello ' + nickname.value + '!' )
          root.__defineGetter__( 'childNodes', ()=> greet.checked ? [ form, greeting ] : [ form ] )
          
          // Set up handlers
          clear.onclick = ()=> nickname.value = ''
          </script>

          Вот этот код мне удалось запустить на простой HTML-странице. И он даже работает!

          Теперь такой вопрос - что такое textContent и что такое childNodes ? На сайте https://mol.hyoo.ru/ мне не удалось ничего найти про первое даже с использованием полей поиска. Поиск на гугле по ключу "textContent site:mol.hyoo.ru" также дал ничего.

          Допустим, я хочу подключить вашу реактивность взамен vue-реактивности в своём новом проекте (HTML/CSS/JS) - где мне искать информацию по доступному функционалу?

          Вот честно, я туповат для того, чтобы разобраться с вашим фреймворком самостоятельно. В этот раз я дошёл до работающего кода на HTML-странице, но вау-эффекта не получилось :( Я вижу, что вы вешаете какой-то дополнительный функционал на элементы DOM'а и что есть какой-то magic в $mol_wire_dom, который этот функционал использует (и ещё свой добавляет, скорее всего). При этом вы не трогаете исходный DOM. И у меня возникает вопрос за таблицы/гриды - а как вы не трогая исходный DOM, выводите списки - функциональю? Как бы HTML декларативный язык. Я именно поэтому и использую vue, что он, по сути, просто добавляет свои компоненты, как новые тэги в HTML, а свой функционал - как новые атрибуты:

          <li v-for="item in items">
            {{ item.message }}
          </li>

          Для меня, как для разработчика, это офигенно удобно. Я с радостью плачу за это скоростью рендеринга - современные мощности это позволяют. А как сделать аналогичный список на mol?


          1. nin-jin
            06.07.2023 17:29

            Теперь такой вопрос - что такое textContent и что такое childNodes

            Это DOM API.

            как вы не трогая исходный DOM, выводите списки - функциональю?

            В chidNodes возвращаете список дом элементов.

            А как сделать аналогичный список на mol?

            Кажется эта шутка зашла слишком далеко. Не надо так делать, на $mol так не пишут. На $mol интерфейс собирают из компонент, а не верстают html. Тут есть краткое введение.


            1. flancer
              06.07.2023 17:29

              Я хотел примерно посчитать кол-во символов в вашем "кратком введении", но... у меня не получилось. Казалось бы, чего проще - выделить текст (мышкой или с клавиатуры), скопировать его в текстовый файл и посмотреть размер в байтах (поделив на два для юникода). Даже Ctrl + A не сработало. Даже Save as...

              Получилось только распечатать страницу в PDF-файл по Ctrl + P и уже после этого смог перенести содержимое из pdf в текстовый файл. 32715 байтов, т.е. порядка 16К символов. Ну, такое себе краткое объяснение построения списков через mol.

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

              А по поводу, что в mol интерфейс собирают из компонент, а не верстают HTML. Смотрите, внутри всё та же триада - HTML/CSS/JS:

              Только теперь к ней нужно продираться не только через TS, но ещё и через Tree.


              1. nin-jin
                06.07.2023 17:29
                -3

                Это у нас защита от копирования такая. Надо бы запретить печать, чтобы вы перестали воровать мои статьи.


                1. mayorovp
                  06.07.2023 17:29
                  +3

                  Документация с защитой от копирования? Это ж насколько вам не хочется популярности своего фреймворка...


                  1. nin-jin
                    06.07.2023 17:29
                    -1

                    Так это BDSM фреймворк, сначала больно, неприятно, а потом за уши не оттащишь.


          1. SuperCat911
            06.07.2023 17:29
            +1

            Я не из секты @nin-jin но мне в принципе понятно, как работает этот код. С root по clear - Это ссылки на DOM-элементы, а textContent и childNodes это нативные свойства элементов. И геттеры также работали бы, даже если бы не было вызова $mol_wire_dom. Очевидно, что реактивность над DOM можно получить за счет на подписок события модификации элементов.

            Заглянул в $mol_wire_dom, так оно и оказалось.

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


      1. Andy_Francev
        06.07.2023 17:29

        Для подключения реактивности к готовому HTML я использую микрофреймворк Sinous (2.2Kb Gzip)

        https://sinuous.netlify.app/docs/hydrate/ – документация, где описывается, как это сделать.

        Из всех подходов, которые я видел, этот, на мой взгляд, самый удобный. Что касается версии 0.3.2 – меня это не беспокоит, фреймворк уже более года трудится на проде, ошибок и замечаний нет.


  1. ovalsky
    06.07.2023 17:29
    +14

    Ещё не понедельник, а уже новый js-фреймворк)))


    1. antonmak1 Автор
      06.07.2023 17:29

      Да, ещё один :)


    1. cijic
      06.07.2023 17:29

      И вновь реактивный)


      1. antonmak1 Автор
        06.07.2023 17:29

        Зато, без VDOM!


        1. ovalsky
          06.07.2023 17:29

          отлично, теперь у нас будет плодиться параллельно ветка "безVDOMовых" фреймворков


  1. Dismal
    06.07.2023 17:29
    +5

    Кто разбирается в версионировании, объясните мне, пожалуйста:

    Это не самый быстрый результат из всех, которые существуют на данный момент среди фреймворков

    основан на реактивности без виртуального DOM, которая в теории может быть гораздо быстрее

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

    А версия уже 3.0.1


    1. blood_develop
      06.07.2023 17:29

      Может, альфа третьей версии?)


    1. Peter1010
      06.07.2023 17:29

      Сейчас стало модно ставить большие версии. Ну типа смотри он уже 3й версии!!!
      Значит это не какая-то альфа шляпа, а над ним работали огого сколько, реди ту прод!
      Кароче чисто маркетинг.

      Версии к 50й будет юзабельным.


      1. shasoftX
        06.07.2023 17:29

        Возможно это особенность semver-схемы версионирования. Тот же Laravel как на неё перешёл, как начал версии на гора выдавать с огромной скоростью.


      1. Fodin
        06.07.2023 17:29

        Сейчас? DBase III не имела второй и первой версии. Можно сказать, что "ставить большие версии не вышло из моды".


      1. antonmak1 Автор
        06.07.2023 17:29

        Дело не в маркетинге. Но, насчёт 50 версии - вы полностью правы


    1. antonmak1 Автор
      06.07.2023 17:29

      Так, пока фреймворк делался, надо было версии делать. Я ставил версию 1, 2 и 3 только тогда, когда понимал, что там действительно много всего нового и что фреймворк отличается конкретно от прошлой. Там можно посмотреть по коду это


      1. mayorovp
        06.07.2023 17:29
        +1

        Версии до первого релиза обычно нумеруют как 0.1, 0.2, 0.3...


        1. antonmak1 Автор
          06.07.2023 17:29

          Да, обычно так и нумеруется. Я. наверное, больше на node.js ориентировался, как там 18 версия и т.д


          1. Dismal
            06.07.2023 17:29
            +3

            Хорошо, что на виндоус не ориентировались, а ты следующую версию уже 95 надо было бы выпускать :)


            1. antonmak1 Автор
              06.07.2023 17:29

              Там у них свои версии. Там то windows 95, то windows 2000, то после 8 версии 10 сразу


  1. mafia8
    06.07.2023 17:29
    +3

    Игра на выпивание.
    Каждый по очереди берет английский словарь и выбирает случайное слово. После чего он гуглит <слово>.js, и пьет, если есть такая библиотека или фреймворк для javascript. Выигрывает тот, кого последнего госпитализируют с алкогольным отравлением.
    (с) интернет.