Як ми всіх на юх послали (ну або продовження історії про шаблонизотор)

Взагалі я дуже велелюбний чоловік, особливо в плані різних булочок. Але щось у мені перевертається, як тільки це от (ще секунду тому мені щиро симпатичне) знаходить ореол святості і стає предметом поклоніння. В цей самий момент мій внутрішній голос (так, я чую голоси) строго так мені каже – «ходімо ми звідси!».

І ось така хрень досить часто відбувається в нашому непростому, божевільному, але вельми веселому світі технологій. В моєму конкретному випадку – в світі веб-розробки.

Позавчора був JQ. Ну корисна їй богу штучка. Але стали з'являтися фахівці щиро вважають, що JQ – це частина JavaScript і що без нього прив'язка подій до вузлів зовсім неможлива (шепіт в залі: потомушта там якісь проблеми з кросбраузерністю, цссс). І стали зводитися церкви з храмами, і став JQ з ікон на нас грішних дивитися, і книги писалися з назвою «Програмуємо JQuery» (JQ «програмуємо», Карл!).

А вчора був AngularJS. І був він великим, тому що стоїть за ним… Ага, він самий і стоїть.

А сьогодні ось ReactJS. Взагалі наше все. Чому? Тому що він хороший, тому що він правильний, тому що він проти прямого доступу до DOM. А чому? А тому що неправильно до DOM звертатися! А чому? Хлопчик, іди в ж#пу!

Ні, Друзі, не подумайте – у мене зовсім не накипіло – повірте, я брав призові місця на конкурсах лояльності. Просто всьому своє місце і своє призначення. Стріляти з танка, намагаючись придушити муху – це якось несерйозно. Але в якийсь момент ми починаємо саме це і спостерігати, коли під простенький проект підтягується підлогу мегабайта JavaScript (з вихідними кодами на TypeScript, тому що на JS вже ніхто не пише і не запитуйте «чому?» — відповідь була абзацом вище).

ReactJS дійсно чудова штукенція. І коли перед нами постало завдання зробити додаток з блек джеком і шлю купою віджетів з можливістю їх тягати робочого столу (яких має бути кілька), зі всякими віконцями, вкладками та іншої фігньою, ми без вагань обрали ReactJS. Але якщо до нас приходить «освічений» замовник з простеньким проектом і як би натякає, що він (проект) має бути на базі Angualr або ReactJS, то хочеться поплакати, випити, побитися і знову випити в знак примирення. І знаєте, майже завжди спрацьовує, хоча в окремих випадках доводиться таки виписувати путівку в теплі краї.

Між тим мені пощастило з командою. І як вже зазначалося в попередньому пості, було мені дозволено паралельно розвивати простенький шаблонизатор. Хоча щось мені підказує, що у компанії є свої власні суто егоїстичні інтереси )).

Загалом з часу його перший явища публіки, а саме через п'ять місяців, шаблонизатор зазнав істотні зміни. Про що і буде дана замітка (гул у залі: всі розходимося, це не про ReactJS і навіть не про Angular). Стійте! Я ще обов'язково кілька раз скажу слово «React».

Отже, головне, що було зроблено – велике об'єднання паралельних проектів. Тепер одна (немаленька) бібліотека об'єднує в собі:

  • Аналог RequireJS
  • Завантажувач ресурсів (зразок CSS файлів)
  • Контролер кеша
  • Всяк базовий функціонал (зразок AJAX запитів, інструментів по роботі з DOM, CSS та інше)
  • Ну і шаблонизатор, мова про нього
Я ні в якому разі не збираюся Вас втомлювати купою сухого і нудного матеріалу, а наведу лише «пару» простих прикладів, щоб показати, про що власне мова.

Ось, наприклад, Вам потрібна банальна таблиця. І є у вас API якийсь, що дані в JSON видає. Беремо і малюємо окремий HTML файлик з шаблоном. Та стилі потрібні прикріпити не забуваємо.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Flex.Template</title>
< meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="pattern.css" />
</head>
<body>
<table data type="Demo.Table">
<tr>
<th>{{titles.column_0}}</th>
<th>{{titles.column_1}}</th>
<th>{{titles.column_2}}</th>
<th>{{titles.column_3}}</th>
</tr>
<tr {{[rows]}}>
<td>{{column_0}}</td>
<td>{{column_1}}</td>
<td>{{column_2}}</td>
<td>{{column_3}}</td>
</tr>
</table>
</body>
</html>

Тепер, там, де це необхідно, рендерим наш шаблон

_patterns.get({
//Посилання на шаблон
url : '/components/table.simple/component.html',
//Наказ куди "кріпити"
node : document.body,
//Власне контент
hooks : {
titles : {
column_0: 'Column #0',
column_1: 'Column #1',
column_2: 'Column #2',
column_3: 'Column #3',
},
//Посилання на дані рядків таблиці
rows: _patterns.url('/examples/json/table.json')
},
}).render();

Ось власне і все (тута результат). І що особливо приємно, так це те, що шаблон можна відкрити локально і налагодити (спокійно, не поспішаючи і не відволікаючись) стилі – адже перед нами банальна HTML-сторінка.

Звичайно, можна дані і ручками ввести.

var data_source = [];
for (var i = 0; i < 100; i += 1) {
data_source.push({
column_0: (Math.random() * 1000).toFixed(4),
column_1: (Math.random() * 1000).toFixed(4),
column_2: (Math.random() * 1000).toFixed(4),
column_3: (Math.random() * 1000).toFixed(4),
});
}
_patterns.get({
url : '/patterns/table/single/pattern.html',
node : document.body,
hooks : {
titles: {
column_0: 'Column #0',
column_1: 'Column #1',
column_2: 'Column #2',
column_3: 'Column #3',
},
rows: data_source
}
}).render();

А можна прямо в розмітку запхати – нічого не забороняється, адже головне, щоб за любові.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--BEGIN: Patterns definitions-->
<link rel="pattern" name="my_table" src="/html/table/template.html" data-hooks="rows, c_0, c_1, c_2, c_3" />
<!--END: Patterns definitions-->
</head>
<body>
<my_table>
<rows>
<c_0>0.0</c_0> <c_1>0.1</c_1> <c_2>0.2</c_2> <c_3>0.3</c_3>
<c_0>1.0</c_0> <c_1>1.1</c_1> <c_2>1.2</c_2> <c_3>1.3</c_3>
<c_0>2.0</c_0> <c_1>2.1</c_1> <c_2>2.2</c_2> <c_3>2.3</c_3>
<c_0>3.0</c_0> <c_1>3.1</c_1> <c_2>3.2</c_2> <c_3>3.3</c_3>
<c_0>4.0</c_0> <c_1>4.1</c_1> <c_2>4.2</c_2> <c_3>4.3</c_3>
</rows>
</my_table>
</body>

З розміткою взагалі досить зручні речі робити можна. Є у Вас, наприклад, колекція вкладок, досить важка, як ця:

<div class="tabs-container">
<div class="tabs-buttons">
<a class="tab-button">Tab 0</a>
<a class="tab-button">Tab 1</a>
<a class="tab-button">Tab 2</a>
</div>
<div class="tabs-content">
<div class="tab-content">
<p class="tab-content">Tab content 0</p>
</div>
<div class="tab-content">
<p class="tab-content">Tab content 1</p>
</div>
<div class="tab-content">
<p class="tab-content">Tab content 2</p>
</div>
</div>
</div>

Помістивши це шаблон, тобто в окремий HTML файл:

<div class="tabs-container">
<div class="tabs-buttons">
<a class="tab-button" {{[buttons]}} onclick="{{@onClick}}">{{button}}</a>
</div>
<div class="tabs-content">
<div class="tab-content" {{[tabs]}}>{{tab}}</div>
</div>
</div>

В розмітці (на сторінці) з шаблоном зможемо робити так:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--BEGIN: Patterns definitions-->
<link rel="pattern" name="tabs" src="/html/tabs/template.html" data-hooks="buttons, tabs, button, tab" />
<!--END: Patterns definitions-->
</head>
<body>
<tabs>
<buttons>
<button>Tab 0</button>
<button>Tab 2</button>
<button>Tab 3</button>
</buttons>
<tabs>
<tab><p>Content of tab 0</p></tab>
<tab><p>Content of tab 1</p></tab>
<tab><p>Content of tab 2</p></tab>
</tabs>
</tabs>
</body>

І читається легше і зрозуміло інтуїтивно. Вкладки промо-сайту власне так і зроблено.

Вся принадність у тому, що всі шаблони зберігаються локально на клієнті. Тобто при повторній завантаження сторінки, частина розмітки цієї самої сторінки просто не буде завантажена, а взята буде з клієнта. Що також справедливо і для таких ресурсів як JS і CSS файлів. Виключно в якості експерименту є функція повного кешування сторінки, але це поки лише експерименти.

Ще можна, ясна річ, створювати свої контролери під шаблон, наділяючи його якимось функціоналом. Можна «на живу» змінювати значення усередині шаблона (у прикладі з таблицею змінювати значення комірок); модельки є, події (неодмінно стандартні); ну і звичайно, допускається отримати доступ до DOM і насолоджуватися ним по мірі знань.

Багато чого там можна робити, про що почитати не забороняється ось тут (виключно, якщо є вільний час).

Однак окремо зауважу вимоги, які виставлялися до Flex-Patterns при його розробці, що від частини відображає можливості його використання.

  • перше і найважливіше – тільки стандартний HTML, тільки поточний стандарт JS. Тобто будь-який шаблон – це просто HTML файл і ніяких прибул.

  • це чисте front-end рішення, і, хоча шаблони можна монтувати в розмітку, Flex-Pattern є клієнтським рішенням, а не серверним.

  • повна незалежність від чого-небудь. Досить підключити тільки Flex-Patterns, щоб почати з ним роботу і отримати додатковий базовий функціонал (про який було сказано вище).
Власне, це і є ті три кити, на яких базується ідея.

Ну і знову про React'е (я ж обіцяв), бо минулого разу було багато відсилань до нього і «прохань» порівняти, хоча не порівнюються ці речі, тому що різні вагові категорії. Можу лише розповісти про відмінності.

  • React потребує купі обслуговуючого персоналу додаткового оточення (для нормальної і комфортної роботи). Flex-Patterns повністю самодостатній (і це не рахуючи можливості створювати модулі, наявності базового функціоналу кшталт того, що JQ має і інших плюшок) – підчепив і працюй.

  • React'у комфортно з npm, а Flex-Patterns навіть не знає, що це таке.

  • React використовує щось схоже на HTML, але не HTML. Flex-Patterns ґрунтується тільки на HTML і не вимагає знань про defaultValue.

  • React в цілому досить недовірливий до розробника і багато в чому обмежує його (що, напевно, має свої плюси). Flex-Patterns повністю довіряє тому, хто його прихистив підключив до сторінки.

  • React працює спритніше. Flex-Patterns в цілому на 25-35% повільніше, але «помітно» це на невеликих шаблонах (скажімо на таблиці 1000 рядків), де швидкість відтворення у React 100 – 120 ms., а у Flex-Patterns 150 – 200 ms. Якщо ж говорити про величезні об'єктах (зразок таблиці 10 000 рядків), то результат практично ідентичний.

  • Пам'яті «їдять» обидва порівнянно.

  • React «заважає» розмітку і логіку, між тим як Flex-Patterns наполегливо намагається розділити її і розкидати по файликам (що може здатися незручним), не допускаючи ніякого коду всередині HTML.

  • React довіряє кешування браузеру, Flex-Patterns паранойдально кешує шаблони самостійно.

  • Над React працює «трохи» більше однієї людини, над Flex-Patterns «трохи» менше.

  • React є святе поняття state, а Flex-Patterns атеїст і грішити дозволяє.
А наостанок пара слів про майбутнє проекту (якщо кому цікаво звичайно). Проект виріс і його розвиток все більш і більш трудомістка задача. У найближчих планах – сувора дієта, яка за моїми оцінками дозволить скинути вагу з ~200 кб до 120 – 170 кб (де перше є голос оптиміста). Також в повітрі витає ідея зробити теж саме, але для JQ, що дозволило б отримати на виході бібліотеку розміром в 70 – 100 кб (не забувайте всередині не тільки шаблонизатор, а багато ще чого, що по суті дублює можливості JQ).

Однак без Вашої підтримки навряд чи обійтися. А! Злякалися ))) Ні, мова не про фінанси. Просто мені виділять трохи більше часу під цю справу, якщо будуть зірочки (я не брешу, таке ось умова і викотили). Для Вас – це клік, а для мене – додаткова хвилинка на розвиток цього створення. Спасибі заздалегідь.

Щастя всім, добра і світла.

ЗИ. Вчіть React ;)
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.