Сборка клиентских JavaScript шаблонов

Я много пишу на JavaScript, и если вам при работе с шаблонами, как и мне, надоело экранировать окончание строк, следить за именами шаблонов и собирать их перед каждым билдом, это решение для вас, jsttojs — утилита для прекомпиляции клиентских шаблонов в JavaScript.

Первой мыслью было «загуглить», после непродолжительных поисков стало ясно, что ничего подходящего нет. Есть handlebars.js, но количество кода который он генерирует оставляет желать лучшего, выигрыш кажется сомнительным. Конечно же есть замечательный Google Closure Tools, но это законченное решение завязанное на инфраструктуре Closure Tools, что для нас не подходит. Было принято решение написать свою утилиту, в качестве языка для консистентности был выбран JavaScript.

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

Область применения


Это инструмент не привязанный к какому либо конкретному шаблонизатору, вы можете использовать свое любимое решение, например mustache, underscore.js, или ваш собственный, самый лучший фреймворк.

Так как скрипт запускается из консоли, при желании можно интегрироваться в любую систему сборки проекта, а если же вы используете grunt тогда можно воспользоваться плагином grunt-jsttojs.

Использование


Установка производится с помощью стандартного пакетного менеджера npm:

$ npm install -g jsttojs

Доступны следующие параметры:

-h, --help           справка по использованию
-V, --version        версия 
-e, --ext <n>        имя расширения для шаблонов, по умолчанию jst
-n, --name <n>       имя глобальной переменной для хранения шаблонов, по умолчанию JSTmpl
-w, --watch          отслеживать изменения файлов в фоне и собирать шаблоны автоматически
-r, --removebreak    удалить переносы, табуляцию из шаблонов
-a, --amd            оформить шаблоны как AMD модуль для requirejs

$ jsttojs templates compiled/templates/index.js --ext mustache --watch

Самым «вкусным» на мой взгляд является опция --watch, можно просто запустить скрипт и забыть про него, при любом изменении внутри шаблонов, добавлении или удалении файлов, вся сборка будет происходить автоматически, не нарушая ваш привычный рабочий ритм.

Вы можете без особого труда написать обертку для удобной работы с шаблонами, например с hogan.js это будет выглядеть примерно так:

var Template = {
  render: function(name, data) {
    var template = Hogan.compile(MyGlobalVariable[name]);
    return template.render(data);
  },
  compile: function(name) {
    return Hogan.compile(MyGlobalVariable[name]);
  }
}

И использовать

var html = Template.render('video/index', { username: 'World' });

Примеры


Шаблоны:

// tamplates/index.jst
Hello world {{ username }}
second line

// tamplates/video/index.jst
Hello {{ username }} on index video page

Выполняем команду:

$ jsttojs templates compiled/templates/index.js --name MyGlobalVariable

И получаем шаблоны готовые к использованию:

// compiled/templates/index.js
window.MyGlobalVariable = {
  "index" : "Hello world {{ username }}\nsecond line",
  "video/index" : "Hello {{ username }} on index video page"
}


Заключение


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

Код доступен на github

Ссылки


Так же можно посмотреть в сторону


Upd


Если вам нужна «честная» компиляции на сервере, то посмотрите в сторону handlebars, но помните, что размер ваших шаблонов значительно увеличится (подробнее в комментариях). Но в первую очередь jsttojs предназначено для шаблонизаторов не имеющих встроенной серверной перекомпиляции, хоть и не исключает использования вместе с ними.
Share post
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 25

    +2
    хм… и где тут прекомпиляция?
      0
      под прекомпиляцией имелось в виду сжатие шаблонов и сборка их в один файл, решение например в handlebars мне кажется избыточным, хоть мы и получаем выигрыш в размере библиотеки (с 33KB до 3KB), размер скомпилируемых шаблонов растет очень сильно
        +3
        Прекомпиляция вообще говоря подразумевает какие-то специальные инструкции для препроцессора и создание нового уровня абстракций хоть на каком-то уровне, т.е. генерация кода для другого процессора.

        В вашем случае простая сериализация группы файлов в один файл.
          +3
          Суть прекомпиляции — создание из текста шаблона готовой функции для рендринга. Это процедура весьма затратна, если делать ее на клиенте.
          +3
          Поддерживаю. Прекомпиляции не вижу, только конкатенация и быстрый доступ посредством глобальной переменной.
            –2
            возможно выбрал не совсем точный термин, но мне кажется он более точно и емко описывает то, что происходит
          0
          На своих проектах использую brunch + handlebars + live reload plugin. В результате все шаблоны скомпилированы, brunch следит за изменениями, а live reload прямо перегружает браузер. Очень удобно!

          По поводу доступа. Все шаблоны лежат в папке app/templates. В скомпилированом коде это просто javascript функции, которые доступны как CommonJS модули.

          Для примера есть шаблон app/templates/main-layout.hbs. В програмном коде пишем:

          var mainLayoutTmpl = require('templates/main-layout');
          var renderedTmpl   = mainLayoutTmpl({ title: 'Hello world!' });
          


          Простой доступ и никаких глобальных переменных.
            0
            можете поделить, какой размер шаблонов до и после прекомпиляции получается?
              0
              Все шаблоны собираються вместе с кодом приложения в один файл app.js. Но если взять отдельный шаблон, тогда получается так: исходный шаблон — 1.4 КБ, скомпилированный — 3,8 КБ.

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

              Но надо заметить, что часть кода сжимается js минификатором и думаю для одностраничных приложений, где много кода приложения, шаблоны не будут сильно влиять на итоговый размер.
                0
                ясно, спасибо, добавил в статью пример обертки для шаблонизатора, чтобы скрыть работу с глобальными переменными.
                  0
                  Ну и к тому же файл с шаблонами все равно кэшируется браузером, так что некоторое увеличение размера мне кажется непринципиально, а скорость отрисовки страницы будет выше.
                    0
                    Можете расценивать это как оптимизацию первоначальной загрузки страницы, в конечном счете все зависит от проекта, handlebars отличное решение, я не раз о нем упоминаю, но разницу в скорости отрисовки шаблонов не прибегая к тесам заметить очень сложно.
                    • UFO just landed and posted this here
              –3
              Парни, а никто попрекомпилировать не хочет в славном офисе с хорошей з/п и пряниками в районе м. Аэропорт :)? Очень ищу хорошего прекомпилятора JS ;)
                +1
                Вам бы дизайнеров для начала ;)
                0
                просто оставлю ссылку как LinkedIn выбирал шаблонизатор
                engineering.linkedin.com/frontend/client-side-templating-throwdown-mustache-handlebars-dustjs-and-more
                  0
                  Изменил заголовок поста в виду комментариев выше.
                    0
                    А работа с «некомпилированными» шаблонами либа поддерживает? Т.е. я хочу, чтобы в dev режиме шаблоны можно было применять с таким же синтаксисом, но при этом текст шаблона грузился из его source-файла, а вот при подготовке production производилась сборка всех шаблонов в один файл.
                      0
                      Я так понимаю, что это нужно для дебага, или какой юзкейс? Возможно вам подойдет опция --watch, в этом случае вы просто подключаете скомпилированный файл и при любом изменении оригинальных шаблонов он сам пересобирается. Если нужно, могу дописать функционал который будет генерировать файлы с такой же иерархией как оригинальные, только экранировал бы окончание строк и присваивал шаблон какой то переменной, другого варианта не вижу, но не совсем понятна область применения.
                        0
                        Вопрос пока чисто более теоретический, чем практический. У меня, например, сейчас треубемые шаблоны подгружаются посредством AJAX (один из вариантов), т.о. я могу перезагрузить какой-нибудь шаблон в runtime для дебага. Это пример юзкейса. А спрашиваю пока из чистого интереса к проекту и как возможная идея дополнения функциональности, а не то чтобы мне это прям очень надо.
                          0
                          Ясно, спасибо, в ближайшее время сделаю такую возможность.
                    • UFO just landed and posted this here
                        0
                        Hogan сам умеет компилироваться в функции, зачем лишние действия?
                          0
                          У хогана есть готовая утилита? Что то не нашел, или все таки прийдется немного пописать на ноде?
                          0
                          А я вот eco шаблоны собираю stitch-ем — ну получаются шаблоны после прекомпиляции толще, но так на то и gzip, чтоб о размере заботится.

                          Only users with full accounts can post comments. Log in, please.