Stencil — это компилятор для веб-компонентов, который использует JSX для описания разметки компонентов. Одной из ключевых особенностей JSX в Stencil является возможность настройки функции, которая интерпретирует JSX-элементы. Эта настройка реализуется через custom JSX pragma. Понимание работы с pragma позволяет изменять поведение рендеринга и интегрировать сторонние библиотеки или собственные абстракции поверх JSX.
JSX pragma — это функция, которая вызывается при трансформации JSX в
вызовы JavaScript. По умолчанию Stencil использует функцию
h (hyperscript) для генерации виртуальных
DOM-элементов:
import { h } from '@stencil/core';
const element = Привет;
// Транспилируется в
const element = h('div', { class: 'container' }, 'Привет');
Функция h принимает три основных параметра:
Stencil позволяет указать свою функцию для обработки JSX через
настройку jsx в tsconfig.json или через
комментарий /** @jsx */. Например:
/** @jsx myCreateElement */
import { myCreateElement } from './my-jsx-pragmas';
const element = ;
При компиляции
будет
преобразован в:
myCreateElement('button', { disabled: true }, 'Клик');
Такой подход полезен, когда необходимо:
Функция pragma может выглядеть так:
export function myCreateElement(tag: any, props: any, ...children: any[]) {
// Добавление дополнительного класса ко всем div
if (tag === 'div') {
props = { ...props, class: (props?.class || '') + ' custom-div' };
}
// Логирование для отладки
console.log('Создаётся элемент', tag, props, children);
// Вызов стандартного h для совместимости со Stencil
return h(tag, props, ...children);
}
Использование:
const app = Содержимое;
// На выходе создается div с классом "custom-div"
Для корректной работы кастомного JSX pragma с TypeScript необходимо
обновить типизацию JSX. В Stencil это делается через глобальный
JSX namespace:
declare global {
namespace JSX {
interface IntrinsicElements {
div: { id?: string; class?: string };
button: { disabled?: boolean; onClick?: () => void };
}
}
}
Это гарантирует:
h для
стандартных нужд проекта без строгой необходимости. Это может усложнить
миграцию и совместимость с обновлениями Stencil.Custom JSX pragma полностью совместим с компонентами Stencil. Например:
import { Component, Prop, h } from '@stencil/core';
import { myCreateElement } from './my-jsx-pragmas';
@Component({
tag: 'my-button',
shadow: true
})
export class MyButton {
@Prop() label: string;
render() {
/** @jsx myCreateElement */
return ;
}
}
В этом случае компонент использует кастомную логику для генерации кнопки, сохраняя при этом реактивность и поддержку Shadow DOM.