1/52

JS шаблонизаторы (Mustache/Handlebars, EJS, Jade etc.)

1.

JS шаблонизаторы (Mustache/Handlebars, EJS, Jade etc.)

2. Шаблонизаторы

Шаблон (web template engines)— это заготовка, которая
путём подстановки значений (текст сообщения, цена и
т.п.) превращается в DOM/HTML.
Шаблонизация — удобный способ генерации HTMLструктуры.
Число JS-библиотек растёт с каждым днём.
Шаблоны лучше, чем полноценные библиотеки: более
чистый базовый код.
Верстальщику нужно сверстать повторяющиеся блоки, которые
выглядят немного по-разному, приходится “копипастить” куски
верстки с блоками, а при изменении верстки делать изменения
сразу во всех местах.
Сложные проекты, с насыщенной клиентской стороной,
трудоемки в разработке.
шаблонные системы, выигрыш: скорость разработки и простота
изменения в дальнейшем.

3.

Mustache — шаблонизатор
для JavaScript

4. Шаблонизаторы

Ранее:
1. новые узлы HTML кода в DHTML - создать
строку HTML, после использовать innerHTML
свойство или
2. html(). jQuery метод для вставки кода в шаблон.
пример такой техники:
var dynamic_html =
"<div><span>Highlighted</span><span>Author</sp
an></div>";
document.getElementByID("container").innerHTML =
dynamic_html;

5. Шаблонизаторы

3. способ, создать DOM элементы средствами JS и вставить их
индивидуально:
var title = document.createElement('div');
var highlight = document.createElement('span');
var highlight_text = document.createTextNode("Highlight");
var author = document.createElement('span');
var author_text = document.createTextNode("Author");
var container = document.getElementById('container');
highlight.appendChild(highlight_text);
title.appendChild(highlight);
author.appendChild(author_text);
title.appendChild(author);
container.appendChild(title);
Если надо использовать красивый список в дизайне трёх разных
страниц. надо повторять HTML код в трёх разных местах.
Это не продуктивно.

6. Шаблонизаторы

Ещё пример:
<h1>{{header}}</h1>
<p>{{content}}</p>
<ul>
{{#authors}}
<li>{{#accent}} {{.}} {{/accent}}</li>
{{/authors}}
{{^authors}}
<li>anonymous</li>
{{/authors}}
</ul>
Данные, с которыми работает шаблон, называются контекстом. Имя тега указывает, к
какому полю контекста необходимо обратиться.
Пример данных - контекст для шаблона:
var data = {
header : "Новый пост",
content: "Первая строка<br />Вторая",
authors: ["alex", "daemon", "john"],
accent : function () {
return function (text, render) {
text = render(text);
return '<strong>' + text + '</strong>';
} }};

7. Шаблонизаторы

Всего в Mustache четыре основных типа тегов:
1.
переменная,
2.
секция,
3.
комментарий
4.
и подключение дополнительного шаблона.
Переменная выводит данные
с экранированием HTML-сущностей {{header}}
и без экранирования {{{content}}}.
Отличаются они количеством скобок. В примере вместо {{header}}
подставится строчка «Новый пост».
Секция - парный тег, зависит от типа данных. Для поля со списком
шаблонизатор проходит по его элементам - текст внутри парного тега
обрабатывается по одному разу для каждого элемента списка. Элемент
списка подставляется вместо тега-точки.
Так, например, секция {{#authors}}<li>{{.}}</li>{{/authors}} превратится в
<li>alex</li><li>daemon</li><li>john</li>.
Если список пуст, то обрабатывается содержимое «тега с крышечкой», в
нашем случае — это {{^authors}} … {{/authors}}.

8. Шаблонизаторы

Полный пример 1 работы с шаблонизатором:
<!doctype html>
<html lang="en">
<head>
<title>Mustache.js Inline Method</title>
<script type="text/javascript" src="mustache.js" ></script>
<script>
var view = {
name : "Vasya",
occupation : "Student"
};
function loadtemp(){
var output = Mustache.render("{{name}} is a {{occupation}}", view);
document.getElementById('person').innerHTML = output;
}
</script>
</head>
<body onload="loadtemp()" >
<p id="person"></p>
</body>
</html>

9. Шаблонизаторы

Пример 2: создать шаблон подсчета суммы при заданных значениях:
<!doctype html><html lang="en"> <head>
<script type="text/javascript" src="mustache.js" ></script>
<script type="text/javascript" src="jquery-1.2.6.js"></script>
<script>
var product = {
name: "FooBar",
price: 100,
salesTax: 0.05,
totalPrice: function() {
return this.price + this.price * this.salesTax; }};
function loadtemp() {
var template = "<p>Product Name: {{name}}</p>Price: {{totalPrice}}";
var html = Mustache.to_html(template, product);
$('#sampleArea').html(html);}
</script>
</head>
<body onload="loadtemp() " >
<p id="sampleArea"></p>
</body>
</html>

10. Шаблонизаторы

Пример 3: создать шаблон вывода информации о работниках кажого
департамента:
<!doctype html>
<head>
<script type="text/javascript" src="mustache.js" ></script>
<script type="text/javascript" src="jquery-1.2.6.js"></script>
<script>
var data = { depts: [
{ name: "Engineering",
employees: [
{firstName: "Christophe", lastName: "Coenraets"},
{firstName: "John", lastName: "Smith"}]
},
{ name: "Sales",
employees: [
{firstName: "Paula", lastName: "Taylor"},
{firstName: "Lisa", lastName: "Jones"}]
}]
};

11. Шаблонизаторы

function loadtemp(){
var tpl = "{{#depts}}<h1>{{name}}</h1>" +
"<ul>{{#employees}}{{>employee}}{{/employees}}</ul>{{/depts}}";
var partials = {employee: "<li>{{firstName}} {{lastName}}</li>"};
var html = Mustache.to_html(tpl, data, partials);
$('#sampleArea').html(html);
}
</script>
</head>
<body onload="loadtemp()" >
<p id="sampleArea"></p>
</body>
</html>

12. Шаблонизаторы

Шаблонизаторов на сегодняшний день достаточно много:
dōmo
HyperScript
Marco
Handlebars.js
Nunjucks.js
Template7
Pug (ex Jade)
Haml
Mustache
Transparency
doT.js
Шаблонизаторы и фреймверки важны при управлении сложных систем с
динамическими презентационными видами. Mustache.js является одним из
лучших в своем роде.
Теперь вы имеете решение на случай создания сложных проектов.

13.

Jade (PUG) —
шаблонизатор

14. Шаблонизаторы

Jade - это высокопроизводительный шаблонизатор,
источником вдохновенья для создания которого
послужил Haml.
Jade — препроцессор HTML и шаблонизатор;
переименован в "Pug"
Jade реализован на JavaScript для node.
Jade —средство написания разметки совершенно по
новому, с целым рядом преимуществ по сравнению с
обычным HTML.
Полезные функции
JavaScript;
Циклы;
Интерполирование;
Миксины.

15. Шаблонизаторы

Пример:
Реализация списка на Jade
- var x = 5;// Начав строку с дефиса, мы указали компилятору Jade использовать JavaScript
div
ul
- for (var i=1; i<=x; i++) {
li Hello
-}
скомпилировано в HTML:
<div>
<ul>
<li>Hello</li>
<li>Hello</li>
<li>Hello</li>
<li>Hello</li>
<li>Hello</li>
</ul>
</div>

16. Шаблонизаторы

Пример:
пройдёмся по элементам массива в цикле:
- var droids = ["R2D2", "C3PO", "BB8"];
div
h1 Famous Droids from Star Wars
for name in droids
div.card
h2= name
скомпилировано в HTML:
<div>
<h1>Famous Droids from Star Wars</h1>
<div class="card">
<h2>R2D2</h2>
</div>
<div class="card">
<h2>C3PO</h2>
</div>
<div class="card">
<h2>BB8</h2>
</div>
</div>

17.

Примеси (Mixin) конвертируются в обычные JavaScript функции внутри шаблона, могут
принимать аргументы, принимают параметры в качестве входных данных и генерируют
соответствующую разметку, оглашаются с помощью ключевого слова mixin.
mixin thum(imageName, caption)
div.thum
img(src="/img/#{imageName}.jpg")
h4.image-caption= caption
После оглашёния вызвается с помощью символа +.
+thum("oceans-eleven", "Danny Ocean makes an elevator pitch.")
+thum("pirates", "Introducing Captain Jack Sparrow!")
скомпилировано в HTML:
<div class="thum">
<img src="/img/oceans-eleven.jpg">
<h4 class="image-caption">
Danny Ocean makes an elevator pitch.
</h4>
</div>
<div class="thum">
<img src="/img/pirates.jpg">
<h4 class="image-caption">
Introducing Captain Jack Sparrow!
</h4>
</div>

18.

Модули и модульные
зависимости
Управление зависимостями.

19.

AMD
Asynchronous module definition

20. AMD

Модули - назначение
1. - ограничить область видимости,
2. - вновь использовать части приложения,
3. -приложение более структурированное,
4. отделяют ресурсы от шума и делают код
нагляднее.
В JavaScript нет официальных модулей, все
файлы лежат удаленно.
-дорабатывать различные эмуляторы
модульности.
Инкапсуляция - использование модулей,
пространства имен, + наличие своих
собственных систем зависимостей при
создании больших приложений.

21. AMD

не обойтись без системы зависимостей, непрактично
отслеживать зависимости самостоятельно, вручную
добавляя script-теги на страницу.
Пример:
<script src="jquery.js" type="text/javascript" charset="utf8"></script>
<script src="jquery.ui.js" type="text/javascript"
charset="utf8"></script>
<script src="application.utils.js" type="text/javascript"
charset="utf-8"></script>
<script src="application.js" type="text/javascript"
charset="ut
f-8"></script>
<script src="models/asset.js" type="text/javascript"
charset="utf-8"></script>
<script src="models/activity.js" type="text/javascript"
charset="ut….

22. AMD

В большом проекте –
проблемы с загрузкой,
двойными стандартами,
нужно хитро паковать модули в один файлы для ускорения
загрузки,
адаптация модулей другого формата.
где используется много JS-логики весь JS-код разбивается на
отдельные модули,
зависимости между модулями проследить сложно.
Пример: зависимости и последовательности между файлами:

23. AMD

Что такое модуль?
Модуль — это переиспользуемая часть кода, с
деталями реализации и открытым API, что
позволяет легко загрузить её и использовать в
другом коде. Модулем считается файл с кодом.
Зачем нужны модули?
позволяют:
абстрагировать код - не придётся разбираться в
сложностях реализации сторонних библиотек;
инкапсулировать код,;
переиспользовать код,
управлять зависимостями, легко изменяя
зависимости.

24. AMD

форматы определения модульной
системы в современном JS.
1. асинхронное определение модуля
(Asynchronous Module Definition или AMD);
2. CommonJS;
3. универсальное определение модуля
(Universal Module Definition или UMD);
4. System.register;
5. ES6.

25. AMD

AMD – (древняя система организации
модулей), требует лишь наличия клиентской
библиотеки, - require.js, поддерживается и
серверными средствами.
CommonJS – система модулей, встроенная
в сервер Node.JS. Требует поддержки на
клиентской и серверной стороне.
UMD – универсальная система модулей,
UMD-модули будут работать и в системе
AMD и в CommonJS.
Все они требуют библиотек или систем
сборки.

26. AMD

проблемы приложений с модульной
структурой:
1. описание и удовлетворение
зависимостей частей приложения на
клиентской
2. и на серверной стороне;
3. экспорт переменных в глобальную
область видимости
4. их коллизия.

27.

AMD и Require.js

28. AMD

AMD— это JavaScript API, для создания
модулей, при этом они и их зависимости
могут быть загружены асинхронно.
Асинхронная загрузка модулей улучшает
скорость загрузки веб страницы, так как
модули загружаются одновременно с
остальным контентом сайта.
AMD нужен для разбиения JavaScript кода
по разным файлам.
сводится к описанию модулей функцией
define
и подключению их с помощью require.

29. Require.js

Установка: Скачать его можно по адресу:
http://requirejs.org/docs/download.html#requ
irejs
Подключается RequireJS так:
<script data-main="js/main" src="js/libs/require.js"></script>

30. Require.js

Синтаксис:
1. define()для определения именованных
или безымянных модулей
2. require() для импорта зависимостей.
define-объявить модуль, от которого будут
зависеть другие части приложения.
require()-запустить функцию, которая
зависит от модулей, объявленных отдельно.
В require() не объявляют новые модули.
RequireJS загружает, выполняет модули в
заданном порядке.

31. Require.js

описание модулей.
define:
Структура модуля:
define("name", "dependencies", "callback");
moduleName - имя модуля (необязательный
параметр)
dependencies - Зависимости (библиотеки или
объекты, которые будут использоваться в
коде блока)
callback - Функция (выполняется после
загрузки всех зависимостей) - тело модуля, в
которое передаются dependencies
define("<module_name>", ["dependency1",
"dependency2],
function(dependency1, dependency2) { } );

32. Require.js

Пример: //файл person.js объявляем там sayHello
define(function(){
return {
name: 'David',
sayHello: function() {
console.log( 'Hi there, ' + this.name ); } }});
//файл app.js обращаемся к файлу person.js как к объекту:
define(['person'], function(person){
person.sayHello(); // вызываем sayHello
}); //Hi there, David
Пример: функция: // файл sum.js
define(function(){
return function(a, b) {
console.log(a + b); }})
// app.js
define(['sum'], function(sum){
sum(10, 4) // 14
});

33. Require.js

Можно использовать модуль для хранения и передачи набора
констант, можно не объявлять функцию, а просто передать
объект с данными Пример:
// contsants.js
define({
pi: 3.14142,
e: 2.7182818});
// app.js
define(['constants'], function(constants){
console.log(constants.pi); // 3.14142});
Пример: сокращение кода за счёт самоопределяющейся функции:
define(function(){
var privateValue = 0;
return {
increment: function(){
privateValue++;
},
decrement: function(){
privateValue--;
},
getValue: function(){
return privateValue;
} };});

34. Require.js

Пример: динамически импортировать
зависимости ['foo', 'bar'], в модуль:
define(function(require) {
var foobar;
require(['foo', 'bar'], function (foo, bar) {
foobar = foo() + bar();
});
// возвращаем модуль
// обратите внимание на другой шаблон определения
модуля
return {
foobar: foobar
};
});

35.

Конфигурация

36. AMD

Для правильной работы приложения (правильном
подключении библиотек) нужно указать правильные пути:
то есть создать конфигурацию для RequireJS.
Можно добавить перед вызовом оператора require в
файле init.js
requirejs.config({
baseUrl: "js/library",
paths: {
jquery: 'jquery.min',
backbone: 'backbone.min',
underscore: 'underscore.min',
storage: 'jstorage',
json: 'json2',
appControllers: '../Controllers',
appModels: '../Models',
appViews: '../Views'
}

37. AMD

baseUrl —путь к библиотекам. Все пути в
RequireJS берутся относительно этого базового
пути. Если не указать baseUrl, то за базовый будет
взят путь из атрибута data-main при подключении.
paths —синонимы для определенных путей или
файлов (относительный путь "../”)
!!!не нужно указывать расширение .js для файлов
shim —описание библиотек, в тело которых мы
нельзя добавить блок define,.

38. AMD

shim
require.config используется, если необходимо подключить модуль,
который не оформлен в виде AMD и экспортирует переменную в
глобальную область видимости.
jQuery плагины не содержат define блоков и не могут быть использованы пока
jQuery не будет загружена
вручную указать его зависимости и экспортируемую переменную, и он
станет частью приложения наравне с другими AMD-модулями:
mymodule:
require.config = {
shim: {
'oldmodule' : {
deps: [],
exports: 'OldModule'
}
waitSeconds: 15
}};
Теперь можно указывать его в качестве зависимости:
require(
['mymodule', 'jquery', 'oldmodule'],
function(){}
);

39. AMD

файл main
Метод require фактически должен вызываться только
один раз в главном файле main
в config.js можно определить основной файл вашего
приложения – main.js:
requirejs.config({
baseUrl: './assets/js',
deps: ['app/main'],
paths: {
'bootstrap': 'vendor/bootstrap'
}
});

40. AMD

Как запустить приложение?
Головной файл называется, как правило,
main.js или app.js.
Создаём файл index.html и прописываем в
нём путь к головному файлу
<script data-main="js/main.js"
src="js/require.js"></script>
Если путь к головному файлу содержится
в /config.js, то путь указываем к нему:
<script data-main="js/config.js"
src="js/require.js"></script>

41.

Другие форматы модулей

42. Require.js

Формат CommonJS стандарт написания
модулей Организация пространства имен
осуществляется непосредственно в модуле;
модули помещаются отдельно в разные файлы
и выставляют переменные для публичного
использования.
применяется в Node.js и использует для
определения зависимостей и модулей require и
module.exports:
Пример
var dep1 = require('./dep1');
var dep2 = require('./dep2');
module.exports = function(){
// ...

43. AMD

Пример: есть 2 файла:
// maths.js
exports.per = function(value, total) {
return( (value / total) * 100 );
};
// application.js
var Maths = require("./maths");
assertEqual( Maths.per(50, 100), 50 );
ключевым словом exports помечаются
переменные и функции, которые могут быть
использованы снаружи.
Другие модули могут подключать их через
вызов import.

44. AMD

Можно заключить в формат
переноса для асинхронной загрузки для браузера:
// maths.js
require.define("maths", function(require, exports){
exports.per = function(value, total) {
return( (value / total) * 100 );
};
});
Объявление модуля
// application.js
require.define("application", function(require, exports){
var per = require("./maths").per;
assertEqual( per(50, 100), 50 );
}), ["./maths"]); // Перечисление зависимостей (maths.js)

45. Require.js

UMD (Universal Module Definition)
Универсальное определение модуля (UMD)
формат позволяет использовать один
и тот же модуль и с инструментами AMD,
и в средах CommonJS.
Суть UMD - в проверке поддержки того или
иного формата и объявлении модуля
соответствующим образом
может быть использован как в браузере, так
и в Node.js.
Пример такой реализации:

46. Require.js

Модули ECMAScript 2015
В стандарте ECMAScript 2015 появились нативные
модули JavaScript.
поддерживаются в Safari , в Firefox 54, Chrome
60 и Edge 15.
поддерживают не все браузеры.
для этого потребуется компилятор наподобие Babel,
(переводит код в формат ES5 как AMD или CommonJS),
перед тем, как код будет запущен в браузере.
Синтаксис:
В основе -ключевые слова export и import.
Любая переменная, объявленная в модуле, доступна
за его пределами, только если явно экспортирована
из модуля.

47. Require.js

экспорт — поместить конструкцию export перед любыми элементами, которые надо
экспортировать из модуля:
Пример: файл modules/square.js
export const name = 'square';
export function draw(ctx, length, x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x, y, length, length);
return {
length: length,
x: x,
y: y,
color: color
};
}
Подаём на экспорт сразу несколько объектов
export { name, draw, reportArea, reportPerimeter };
Импортируем из модуля то, что нам нужно
import { name, draw, reportArea, reportPerimeter } from './modules/square.js';

48. Require.js

Синтаксис
Пример: модуль экспортирует функцию:
export default function () { ··· }
класс:
export default class { ··· }
выражение:
export default 5 * 7;
несколько значений:
export const pi = Math.PI;
export function sum(x, y) {
return x + y;}
export function multiply(x, y) {
return x * y;
}

49. Require.js

AMD и CommonJS — это форматы модулей,
а не реализации.
Для поддержки AMD необходима реализация
функций define() и require(), для поддержки
CommonJS
реализация module.exports и require().
Для поддержки модулей во время выполнения
используются загрузчики модулей.
Популярные загрузчики модулей:
RequireJS загружает модули в формате AMD.
curl.js загружает модули AMD и CommonJS.
SystemJS загружает модули AMD и CommonJS.

50. Require.js

Сборщики модулей
загрузчики модулей работают в браузере
и загружают зависимости «на лету», сборщики
модулей заранее подготавливают один файл
со всеми зависимостями (бандл).
Популярные сборщики модулей:
Browserify поддерживает формат CommonJS.
Webpack поддерживает AMD, CommonJS и ES6
модули.
Rollup поддерживает ES6 модули.

51. Require.js

Модуль —многократно используемый код,
инкапсулирующий детали реализации с
открытым API.
Формат модуля —синтаксис определения
и подключения модуля.
Загрузчик модулей интерпретирует и
загружает модуль определенного формата
во время выполнения непосредственно
в браузере.
Сборщик модулей заранее объединяет
модули в один файл, создаёт пакет,
содержащий весь код, во время сборки.

52.

Заключение
English     Русский Правила