У цій частині ми розглянемо, як розширити нашу бібліотеку гіперскрипта, додавши нові функції, оптимізуючи продуктивність та покращуючи зручність використання.
1. Додавання асинхронних дій
Асинхронні дії дозволять нам працювати з API та виконувати інші операції, які вимагають часу.
Створіть новий файл src/actions/async.js:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import H$ from '../core'; H$.addAction('fetch', async (element, value) => { const [url, method = 'GET', targetSelector] = value.split(':'); try { const response = await fetch(url, { method }); const data = await response.text(); if (targetSelector) { H$(targetSelector).html(data); } else { element.innerHTML = data; } } catch (error) { console.error('Fetch error:', error); } }); H$.prototype.html = function(content) { if (content === undefined) { return this[0].innerHTML; } for (let i = 0; i < this.length; i++) { this[i].innerHTML = content; } return this; }; |
Тепер ви можете використовувати асинхронні дії в HTML:
|
1 2 |
<button h-fetch="/api/data:GET:#result">Load Data</button> <div id="result"></div> |
2. Оптимізація продуктивності
Використання MutationObserver
Замість ініціалізації всіх елементів при завантаженні сторінки, ми можемо використовувати MutationObserver для відстеження змін у DOM та ініціалізації нових елементів з гіперскрипт-атрибутами.
Оновіть src/index.js:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import H$ from './core'; import './actions/classes'; import './actions/attributes'; import './actions/events'; import './actions/async'; function initHyperElements(elements) { H$(elements).hyper(); } const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'childList') { mutation.addedNodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { initHyperElements(node); initHyperElements(node.querySelectorAll('[h-class], [h-attr], [h-on], [h-fetch]')); } }); } }); }); document.addEventListener('DOMContentLoaded', () => { initHyperElements(document.querySelectorAll('[h-class], [h-attr], [h-on], [h-fetch]')); observer.observe(document.body, { childList: true, subtree: true }); }); export default H$; |
3. Додавання підтримки компонентів
Створимо простий механізм для створення повторно використовуваних компонентів.
Додайте новий файл src/component.js:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import H$ from './core'; H$.component = function(name, template, behavior) { customElements.define(name, class extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({mode: 'open'}); shadow.innerHTML = template; } connectedCallback() { if (behavior) { behavior.call(this, H$(this.shadowRoot)); } H$(this.shadowRoot.querySelectorAll('[h-class], [h-attr], [h-on], [h-fetch]')).hyper(); } }); }; export default H$; |
Тепер ви можете створювати та використовувати компоненти:
|
1 2 3 4 5 6 7 8 9 |
H$.component('my-counter', ` <button h-on="click:increment">Count: <span id="count">0</span></button> `, ($) => { let count = 0; window.increment = () => { count++; $('#count').html(count); }; }); |
Використання в HTML:
|
1 |
<my-counter></my-counter> |
4. Додавання підтримки стилів
Створіть новий файл src/actions/styles.js:
|
1 2 3 4 5 6 7 8 9 |
import H$ from '../core'; H$.addAction('style', (element, value) => { const styles = value.split(','); styles.forEach(style => { const [property, val] = style.split(':'); element.style[property.trim()] = val.trim(); }); }); |
Тепер ви можете використовувати стилі безпосередньо в HTML:
|
1 |
<div h-style="color: blue, font-size: 20px">Styled text</div> |
5. Додавання підтримки умовних виразів
Створіть новий файл src/actions/conditions.js:
|
1 2 3 4 5 6 7 8 9 10 11 |
import H$ from '../core'; H$.addAction('if', (element, value) => { const [condition, action] = value.split('?'); if (eval(condition)) { const [actionName, actionValue] = action.split(':'); if (H$.actions[actionName]) { H$.actions[actionName](element, actionValue); } } }); |
Використання в HTML:
|
1 |
<div h-if="window.innerWidth > 768 ? class:add:desktop">Responsive content</div> |
6. Документація та тестування
Документація
Використовуйте JSDoc для документування вашого коду. Наприклад:
|
1 2 3 4 5 6 7 8 |
/** * Adds a new action to the Hyperscript library. * @param {string} name - The name of the action. * @param {Function} action - The function to be executed for this action. */ H$.addAction = function(name, action) { H$.actions[name] = action; }; |
Тестування
Встановіть Jest для модульного тестування:
|
1 |
npm install --save-dev jest |
Створіть тестовий файл __tests__/core.test.js:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
import H$ from '../src/core'; describe('H$ core', () => { test('H$ is a function', () => { expect(typeof H$).toBe('function'); }); test('H$.addAction adds a new action', () => { H$.addAction('test', () => {}); expect(typeof H$.actions.test).toBe('function'); }); }); |
Додайте скрипт для запуску тестів у package.json:
|
1 2 3 |
"scripts": { "test": "jest" } |
Висновок
У цій частині ми розширили нашу бібліотеку гіперскрипта, додавши підтримку асинхронних дій, оптимізувавши продуктивність, додавши підтримку компонентів, стилів та умовних виразів. Ми також розглянули важливість документації та тестування.
Ці вдосконалення роблять нашу бібліотеку більш потужною та гнучкою, дозволяючи розробникам створювати більш складні та інтерактивні веб-додатки з використанням декларативного підходу гіперскрипта.
Наступні кроки могли б включати створення плагінної системи, оптимізацію для роботи з великими обсягами даних та інтеграцію з популярними фреймворками та бібліотеками.