Rollup

FAST Element — это современная библиотека для создания веб-компонентов на основе стандарта Custom Elements с расширенными возможностями реактивности и шаблонного рендеринга. Основная цель FAST Element — упрощение разработки компонентов, сохраняя при этом производительность и модульность.

Базовый элемент создается с помощью класса FASTElement, который наследуется для определения нового компонента:

import { FASTElement, html, css } from "@microsoft/fast-element";

const template = html`
  

${x => x.message}

`; const styles = css` .container { padding: 10px; border: 1px solid #ccc; } `; export class MyElement extends FASTElement { message = "Привет, FAST!"; }

Регистрация компонента осуществляется через customElements.define или утилиты FAST:

import { FASTElement, customElement } from "@microsoft/fast-element";

@customElement({ name: "my-element", template, styles })
export class MyElement extends FASTElement {}

Ключевые моменты:

  • template — описывает разметку и привязки.
  • css — определяет стили компонента.
  • Классы наследуют FASTElement, что обеспечивает реактивность и доступ к жизненному циклу веб-компонентов.

Реактивность и привязки

FAST Element использует реактивные свойства, которые автоматически обновляют DOM при изменении значений. Для создания реактивного свойства используется декоратор @observable:

import { FASTElement, observable } from "@microsoft/fast-element";

export class CounterElement extends FASTElement {
  @observable count = 0;

  increment() {
    this.count++;
  }
}

Привязка свойства к шаблону выполняется через ${x => x.property}:

const template = html`
  
Счётчик: ${x => x.count}
`;

Особенности реактивности:

  • Поддержка односторонней и двусторонней привязки.
  • Автоматическое обновление DOM при изменении @observable свойства.
  • Минимизация лишних ререндеров благодаря внутреннему механизму FAST.

Жизненный цикл компонентов

FAST Element предоставляет набор методов жизненного цикла, аналогичных стандартным Web Components:

  • connectedCallback() — вызывается при добавлении элемента в DOM.
  • disconnectedCallback() — вызывается при удалении элемента из DOM.
  • attributeChangedCallback(name, oldValue, newValue) — вызывается при изменении атрибутов.
  • propertyChanged(name, oldValue, newValue) — специфично для FAST Element и работает с @observable.

Пример использования:

export class TimerElement extends FASTElement {
  @observable seconds = 0;
  interval;

  connectedCallback() {
    super.connectedCallback();
    this.interval = setInterval(() => this.seconds++, 1000);
  }

  disconnectedCallback() {
    super.disconnectedCallback();
    clearInterval(this.interval);
  }

  propertyChanged(name, oldValue, newValue) {
    if (name === "seconds") {
      console.log(`Прошло секунд: ${newValue}`);
    }
  }
}

Шаблоны и слоты

FAST Element использует собственный механизм шаблонов на основе html и repeat для динамических списков. Основные конструкции:

  • Стандартный шаблон: ${x => x.property}
  • Условная логика: if через директиву when
import { when } from "@microsoft/fast-element";

const template = html`
  ${when(x => x.isVisible, html`

Элемент виден

`)} `;
  • Повторение коллекций: директива repeat
import { repeat } from "@microsoft/fast-element";

const template = html`
  
    ${repeat(x => x.items, html`
  • ${x => x}
  • `)}
`;
  • Слоты позволяют распределять содержимое внутри компонента:
const template = html`
  

Основной контент

`;

Стилизация

FAST Element поддерживает локальные стили, которые применяются только к компоненту. Для глобальных стилей используется обычный CSS или CSS Variables.

const styles = css`
  :host {
    display: block;
    border-radius: 4px;
    background-color: var(--bg-color, white);
  }
  .title {
    color: var(--text-color, black);
    font-weight: bold;
  }
`;

Ключевые возможности:

  • Использование CSS Variables для динамических тем.
  • Поддержка псевдоклассов :host, :host([attr]).
  • Инкапсуляция стилей предотвращает утечку CSS.

Работа с событиями

FAST Element позволяет связывать события прямо в шаблоне через @event:

const template = html`
  
`;

export class MyElement extends FASTElement {
  handleClick() {
    console.log("Кнопка нажата");
    this.$emit("custom-event", { detail: "данные" });
  }
}

Особенности:

  • @click и другие DOM-события.
  • Метод $emit для создания кастомных событий.
  • Автоматическая корректная привязка контекста (this).

Модулярность и Rollup

Для сборки FAST Element используется Rollup, который позволяет:

  • Собирать компоненты в единый модуль или пакет.
  • Поддерживать Tree Shaking и минимизацию кода.
  • Генерировать как ESM, так и UMD версии для разных окружений.

Пример конфигурации Rollup для FAST Element:

import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import { terser } from "rollup-plugin-terser";
import babel from "@rollup/plugin-babel";

export default {
  input: "src/index.js",
  output: {
    file: "dist/bundle.js",
    format: "esm",
    sourcemap: true
  },
  plugins: [
    resolve(),
    commonjs(),
    babel({ babelHelpers: "bundled" }),
    terser()
  ]
};

Особенности интеграции с FAST:

  • Rollup позволяет эффективно собирать модульные FAST-компоненты в единый пакет.
  • Поддержка Tree Shaking уменьшает размер итогового бандла.
  • Совместимость с TypeScript через @rollup/plugin-typescript.

Динамическая загрузка компонентов

FAST Element легко интегрируется с динамическим импортом:

async function loadComponent() {
  const module = await import("./my-element.js");
  document.body.appendChild(new module.MyElement());
}

Преимущества:

  • Подгрузка компонентов по необходимости.
  • Минимизация начального бандла.
  • Совместимость с современными фронтенд-практиками.

Расширяемость

FAST Element поддерживает миксины и наследование, позволяя строить комплексные компоненты на базе базовых классов:

function LoggerMixin(Base) {
  return class extends Base {
    log(message) {
      console.log(`[${this.constructor.name}] ${message}`);
    }
  };
}

class AdvancedElement extends LoggerMixin(FASTElement) {
  connectedCallback() {
    super.connectedCallback();
    this.log("Элемент подключен");
  }
}

Миксины и наследование:

  • Позволяют создавать повторно используемые функциональные блоки.
  • Совместимы с реактивностью FAST.
  • Упрощают архитектуру сложных библиотек компонентов.