Что такое HMPL.js? DevBlog №0

Приветствую всех! В данной статье хотелось бы рассмотреть такой проект как HMPL.js. «Зачем он нужен и как благодаря нему можно сократить размеры javascript файлов с сохранением дизайна сайта?» — на все эти вопросы я постараюсь ответить.

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

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

Пример использования: CodeSandbox

Понятие HMPL

Прежде всего, слово HMPL — это соединение слов HTML и Cample. Слово HTML означает язык гипертекстовой разметки, а слово Cample означает название фреймворка для создания пользовательских интерфейсов (это мой предыдущий проект, который я разрабатывал несколько лет). Работая над синтаксисом, который используется в фреймворке, мне пришла идея вынести те идеи, которые я там реализовал в отдельный язык, который можно было бы использовать в разных проектах не зависимо от того, на чём они сделаны. Пример Cample синтаксиса:

const eachComponent = each(
  "table-rows",
  ({ importedData }) => importedData.rows,
  `
    {{row.id}}
    {{row.label}}
    удалить строку
    
  `,
  {
    valueName: "row",
    functionName: "updateTable",
    stackName: "stack",
    import: {
      value: ["rows", "delete"],
      exportId: "mainExport",
    },
    functions: {
      setSelected: [
        (setData, event, eachStack) => () => {
          const { setStack, clearStack } = eachStack;
          clearStack();
          setStack(() => {
            return { class: "selected" };
          });
        },
        "updateTable",
      ],
    },
  }
);

Ту же интерполяцию строк, либо же «синтаксическое добавление» слушателя событий к DOM узлу, а также вообще применить тот код, который делает cample одним из самых быстрых фреймворков на реактивности без VDOM в интернете, но в рамках языка шаблонов.

Первым проектом, который стал прототипом HMPL, был cample-html (да, вот так неожиданно). Там я реализовал тот синтаксис, про который я поначалу продумывал, но была ещё проблема в том, зачем же он будет нужен. Лучшей идеей для этого была связка с серверным HTML, который может быть запрошен по роуту api. То-есть, идея в этом, что HTML, который будет видеть пользователь, будет храниться изначально не на клиенте, а на сервере. Таким образом, мы можем сократить размеры файлов, что я ниже и покажу в статье с примерами. Пример синтаксиса cample-html:

const templateFn = CampleHTML.createTemplate(
  ``
);

// (After the response arrives from the server) { element = template (HTMLTemplateElement type), status = 200 }
const elementObj = templateFn({
  credentials: "same-origin",
  get: (prop, value) => {
    if (prop === "element") {
      console.log(value);
    }
  },
});

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

Что же такое HMPL?

HMPL — это небольшой язык шаблонов для отображения пользовательского интерфейса от сервера к клиенту. Он основан на запросах, отправляемых на сервер с помощью fetch и преобразуемых в готовый HTML.

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

{ { "src": "http://localhost:8000/api/test", "indicators": [ { "trigger": "pending", "content": "
Loading...
" }, { "trigger": "rejected", "content": "
Error
" } ] } }

Это простые javascript объекты, которые благодаря фигурным скобкам, передаются прямо в HTML. Не нужно теперь писать template каждый раз, теперь достаточно просто передать объект, который описывает настройки запроса и всё. Таким образом, код будет выглядеть так:

import { compile } from "hmpl-js";

const templateFn = compile(
  `{ 
     {
       "src": "http://localhost:8000/api/test",
       "indicators": [
           {
             "trigger": "pending",
             "content": "
Loading...
" }, { "trigger": "rejected", "content": "
Error
" } ] } }` ); const wrapper = document.getElementById("wrapper"); const elementObj = templateFn({ credentials: "same-origin", get: (prop, value) => { if (prop === "response") { if (value) { wrapper.appendChild(value.content); } } }, });

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

Как HMPL сокращает размер файлов

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

Уменьшение размера файла javascript позволит страницам быстрее загружаться на клиенте. Если взять современный SPA, то окажется, что размеры файлов, даже с учетом всех минимизаций, все равно довольно велики. Конечно, после того, как вы загрузите страницу один раз, ориентироваться на ней становится проще, но время первой загрузки может составлять от одной секунды до, скажем, нескольких минут при плохом интернет-соединении. Немногие клиенты захотят ждать так долго.

При использовании большинства фреймворков и библиотек для создания пользовательского интерфейса приходится писать много шаблонного кода. Каждый символ занимает много места в памяти. Давайте рассмотрим Vue.js кликер:

createApp({
  setup() {
    const count = ref(0);
    return {
      count,
    };
  },
  template: `
Clicks: {{ count }}
`, }).mount("#app");

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

1. Размер исходного javascript файла на Vue

1. Размер исходного javascript файла на Vue

Даже без двух запятых там могло бы быть на несколько байт меньше

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

На самом деле, одно из решений этой проблемы было предложено давно и оно до банальности простое — это подготовить пользовательский интерфейс на сервере и просто загрузить его на клиент. Благодаря этому размер файлов приложения может быть значительно уменьшен. Именно эта идея используется в HMPL. И именно с cample-html я хотел подобное создать.

В примере я также попытаюсь создать кликер, но с использованием hmpl.js:

document.querySelector("#app").appendChild(
  hmpl.compile(
    `
Clicks: {{ src: "/api/clicks", after: "click:button" }}
` )().response );

Как вы можете видеть, пользовательский интерфейс будет таким же, но размер файла будет немного меньше.

2. Размер исходного javascript файла на HMPL

2. Размер исходного javascript файла на HMPL

Даже если вы уменьшите файлы и уберете все лишние пробелы из шаблонов, возможно, файлы будут на одном уровне или что-то большее, но это всего лишь предположение на небольших примерах. Если брать большие приложения, то очевидно, что при таком подходе js будет намного меньше.

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

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

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

Документация HMPL

Язык шаблонов имеет документацию, которая располагается по адресу https://hmpl-lang.github.io/#/docs. Там можно посмотреть не только те примеры, которые были указаны в статье, но и другие примеры, включая примеры проектов. Также, там рассказано и про свойства объекта запроса, и про установку, и про многое другое.

Интеграция с Webpack

Модуль имеет свой собственный загрузчик для файлов с расширением .hmpl. Вы можете загрузить hmpl-loader и использовать синтаксис языка шаблонов в отдельных файлах:

main.hmpl

{ { "src": "/api/test" } }

main.js

const templateFn = require("./main.hmpl");

const elementObj = templateFn();

Загрузчик работает с версии 0.0.2 и выше.

Мотивация создания проекта

На самом деле, цикл статей и видеороликов, который будет записываться и писаться, для меня очень важен. За последние 4 года, я старался делать разные проекты, вспомнить ту же 2D игру на canvase, либо же кликер, где вышло больше 10 видеороликов и на самом деле, они были действительно интересны, но в них не хватало той production идеи, которая должна быть в продукте. То-есть, проекты доходили до какого-то более ли менее качественного состояния, а потом просто забрасывались, потому что этим буквально никто не будет пользоваться и в это играть. И, на самом деле это безыдейность меня сильно тревожила и я хотел действительно сделать что-то полезное, что можно использовать в реально больших проектах. Чтобы можно было это подключить и реально взаимодействовать, чекать документацию и просто круто с этим работать!

После того, как я на два года ушёл из ютуба, я изучал много материала по программированию и сделал тот проект, к которому я наверное и стремился это cample.js.

Это фреймворк, который позволяет создавать пользовательские интерфейсы и действительно данный проект был очень интересен для меня. Я на протяжении двух лет каждый день работал и думал о том, как бы его улучшить, сделать новый функционал и добиться той цели, которую я себе поставил. Мне хотелось, чтобы люди могли пользоваться качественным продуктом, но, я также понимал, что сегодняшние фреймворки — это такое количество функционала, что в одиночку сделать его было просто невозможно, поэтому, после определённого момента, главной моей целью была скорость. И, в целом, когда фреймворк стал действительно одним из самых быстрых в интернете, по реализации реактивности без виртуального DOM, я, на самом деле, был счастлив, но в тоже время и опустошён, потому что дальше, смысла реализовывать было всё меньше и меньше, поэтому и этот проект, как и кликер и игра, был в какой-то степени несерьёзным.

Когда ты делаешь проект один, реализуешь крутой там функционал, что-то допиливаешь, ты каждый день сидишь, но на 100% не понимаешь, что вот это нужно, а вот это идея фигня и её реализовывать не стоит, и, вот это понимание оно идёт только от тех, кто пользуется продуктом. И, на самом деле, я понял, что сидеть каждый день в каком-то вакууме, где есть только код и всё — это неправильно, поэтому, для себя, я понял, что надо что-то менять. И, данными видеороликами и статьями, как некими отчётами о проделанном, я постараюсь держать тот уровень ответственности и полнейшей серьёзности, которая должна быть, как если бы я был штатным специалистом, а аудитория неким заказчиком. И, на самом деле, допустим те же новые версии, проекты на языке шаблонов, какие-то созданные смежные модули — всё это действительно должно иметь тот уровень качества, который должен быть. Поэтому, для меня это будет тот проект, который должен быть максимально качественным и полным и он будет крутым, чтобы его использовали люди по всему миру, потому что будущее за серверным HTML и Server-side рендерингом! Проект реально позволит быстрее грузить сайты, потому что файлы будут меньше и это классно!

Видеоверсия статьи

Всем большое спасибо за прочтение статьи!

Социальные сети:

https://habr.com/ru/users/antonmak1

https://github.com/antonmak1

https://dev.to/antonmak1

https://t.me/hmpljsru

Источники:

https://github.com/hmpl-lang/hmpl

https://hmpl-lang.github.io

https://github.com/cample-html/cample-html

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

https://developer.mozilla.org/en-US/docs/Glossary/SPA

https://github.com/hmpl-lang/examples

https://hmpl-lang.github.io/blog/blog/2024/08/09/how-to-reduce-javascript-file-size-on-client.html

© Habrahabr.ru