Библиотека Lit

логотип библиотеки Lit 2023

Что такое Lit?

Lit - это простая библиотека для создания быстрых, легких веб-компонентов.

В основе Lit лежит базовый класс компонента, уничтожающий котельные плиты, который обеспечивает реактивное состояние, масштабируемые стили и декларативную систему шаблонов, которая является крошечной, быстрой и выразительной.

Что я могу создать с помощью Lit?

С помощью Lit можно создать практически любой вид веб-интерфейса!

Первое, что нужно знать о Lit, это то, что каждый компонент Lit - это стандартный веб-компонент. Веб-компоненты обладают суперспособностью к взаимодействию: изначально поддерживаемые браузерами, веб-компоненты могут быть использованы в любой HTML-среде, с любым фреймворком или вообще без него.

Это делает Lit идеальным выбором для разработки разделяемых компонентов или систем проектирования. Компоненты Lit можно использовать в различных приложениях и сайтах, даже если эти приложения и сайты построены на различных фронтенд-стеках. Разработчикам сайтов, использующим компоненты Lit, не нужно писать или даже видеть какой-либо код Lit; они могут просто использовать компоненты так же, как и встроенные элементы HTML.

Lit также идеально подходит для постепенного улучшения базовых HTML-сайтов. Браузеры распознают компоненты Lit в вашей разметке и инициализируют их автоматически - независимо от того, создан ли ваш сайт вручную, управляется ли он с помощью CMS, построен на основе серверного фреймворка или создан с помощью таких инструментов, как Jekyll или eleventy.

Конечно, из компонентов Lit можно создавать высокоинтерактивные, многофункциональные приложения, как и с помощью таких фреймворков, как React или Vue. Возможности Lit и опыт разработчиков сопоставимы с этими популярными альтернативами, но Lit минимизирует блокировку, максимизирует гибкость и повышает ремонтопригодность за счет использования нативной компонентной модели браузера.

Когда вы создаете приложение с помощью Lit, вы можете легко добавлять в него ванильные веб-компоненты или веб-компоненты, созданные с помощью других библиотек. Вы даже можете обновить Lit до новой версии или перейти на другую библиотеку - по одному компоненту за раз, не прерывая разработку продукта.

Каково это - развиваться с Lit?

Если вы занимались современной компонентной веб-разработкой, вы должны чувствовать себя в Lit как дома. Даже если вы раньше не работали с компонентами, мы думаем, что Lit покажется вам очень доступным.

Каждый компонент Lit - это самодостаточная единица пользовательского интерфейса, собранная из небольших строительных блоков: стандартных элементов HTML и других веб-компонентов. В свою очередь, каждый компонент Lit сам по себе является строительным блоком, который может быть использован в HTML-документе, другом веб-компоненте или компоненте фреймворка для создания более крупных и сложных интерфейсов.

Вот небольшой, но нетривиальный компонент (таймер обратного отсчета), который иллюстрирует, как выглядит код Lit, и подчеркивает несколько ключевых особенностей:

my-timer.ts

import {LitElement, html, css} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
/* playground-fold */
import {play, pause, replay} from './icons.js';
/* playground-fold-end */

@customElement("my-timer")
export class MyTimer extends LitElement {
  static styles = css`/* playground-fold */

    :host {
      display: inline-block;
      min-width: 4em;
      text-align: center;
      padding: 0.2em;
      margin: 0.2em 0.1em;
    }
    footer {
      user-select: none;
      font-size: 0.6em;
    }
    /* playground-fold-end */`;

  @property() duration = 60;
  @state() private end: number | null = null;
  @state() private remaining = 0;

  render() {
    const {remaining, running} = this;
    const min = Math.floor(remaining / 60000);
    const sec = pad(min, Math.floor(remaining / 1000 % 60));
    const hun = pad(true, Math.floor(remaining % 1000 / 10));
    return html`
      ${min ? `${min}:${sec}` : `${sec}.${hun}`}
      <footer>
        ${remaining === 0 ? '' : running ?
          html`<span @click=${this.pause}>${pause}</span>` :
          html`<span @click=${this.start}>${play}</span>`}
        <span @click=${this.reset}>${replay}</span>
      </footer>
    `;
  }
  /* playground-fold */

  start() {
    this.end = Date.now() + this.remaining;
    this.tick();
  }

  pause() {
    this.end = null;
  }

  reset() {
    const running = this.running;
    this.remaining = this.duration * 1000;
    this.end = running ? Date.now() + this.remaining : null;
  }

  tick() {
    if (this.running) {
      this.remaining = Math.max(0, this.end! - Date.now());
      requestAnimationFrame(() => this.tick());
    }
  }

  get running() {
    return this.end && this.remaining;
  }

  connectedCallback() {
    super.connectedCallback();
    this.reset();
  }/* playground-fold-end */

}
/* playground-fold */

function pad(pad: unknown, val: number) {
  return pad ? String(val).padStart(2, '0') : val;
}/* playground-fold-end */

index.html

<!doctype html>
<head><!-- playground-fold -->
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@1,800&display=swap" rel="stylesheet">
  <script type="module" src="./my-timer.js"></script>
  <style>
    body {
      font-family: 'JetBrains Mono', monospace;
      font-size: 36px;
    }
  </style>
  <!-- playground-fold-end -->
</head>
<body>
  <my-timer duration="7"></my-timer>
  <my-timer duration="60"></my-timer>
  <my-timer duration="300"></my-timer>
</body>

icons.ts

import {html} from 'lit';

export const replay = html`<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><title>Replay</title><g><rect fill="none" height="24" width="24"/><rect fill="none" height="24" width="24"/><rect fill="none" height="24" width="24"/></g><g><g/><path d="M12,5V1L7,6l5,5V7c3.31,0,6,2.69,6,6s-2.69,6-6,6s-6-2.69-6-6H4c0,4.42,3.58,8,8,8s8-3.58,8-8S16.42,5,12,5z"/></g></svg>`;
export const pause = html`<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><title>Pause</title><path d="M0 0h24v24H0V0z" fill="none"/><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>`;
export const play = html`<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><title>Play</title><path d="M0 0h24v24H0V0z" fill="none"/><path d="M10 8.64L15.27 12 10 15.36V8.64M8 5v14l11-7L8 5z"/></svg>`;

Некоторые моменты, которые следует отметить:

  • Главная особенность Lit - базовый класс LitElement, удобное и универсальное расширение родного HTMLElement. Вы расширяете его, чтобы определить свои собственные компоненты.

  • Выразительные, декларативные шаблоны Lit (использующие литералы шаблонов с метками JavaScript) позволяют легко описать, как компонент должен быть отображен.

  • Реактивные свойства представляют публичный API компонента и/или его внутреннее состояние; ваш компонент автоматически перерисовывается при изменении реактивного свойства.

  • Стили по умолчанию масштабируются, что позволяет упростить селекторы CSS и гарантирует, что стиль вашего компонента не будет загрязнять (или быть загрязненным) окружающий контекст.

  • Lit отлично работает в ванильном JavaScript, или вы можете использовать TypeScript для еще лучшей эргономики, используя декораторы и объявления типов.

  • Lit не требует компиляции или сборки во время разработки, поэтому его можно использовать практически без инструментов. Первоклассная поддержка IDE (завершение кода, линтинг и т.д.) и инструменты для производства (локализация, минификация шаблонов и т.д.) легко доступны.

Почему я должен выбрать Lit?

Как мы уже отмечали, Lit - отличный выбор для создания всех видов веб-интерфейсов, сочетающий в себе преимущества веб-компонентов, основанных на взаимодействии, с современным, эргономичным опытом разработчика.

Lit также:

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

  • Быстрота. Обновления происходят быстро, поскольку Lit отслеживает динамические части пользовательского интерфейса и обновляет только их при изменении базового состояния - не нужно перестраивать все виртуальное дерево и приводить его в соответствие с текущим состоянием DOM.

  • Легкий вес. Lit весит около 5 КБ (минимизированный и сжатый), что позволяет сохранить небольшой размер пакета и сократить время загрузки.

  • Команда, стоящая за Lit, работает с веб-компонентами с самого первого дня. Мы помогаем Google поддерживать десятки тысяч компонентов, предлагаем полный набор полифиллов для веб-компонентов и принимаем активное участие в работе над стандартами и сообществом.

  • Каждая функция Lit тщательно разрабатывается с учетом развития веб-платформы; мы стремимся помочь вам использовать все преимущества, которые предоставляет платформа сегодня, и при этом писать код, готовый воспользоваться преимуществами будущих улучшений.

Источники