Сочетание Vite и Lit формирует легковесный, высокопроизводительный стек для разработки веб-компонентов. Vite обеспечивает мгновенный dev-сервер с ESM-модулем и оптимизированную сборку, а Lit предоставляет минималистичный слой для создания Web Components с декларативным шаблонизатором и реактивной моделью состояния.
Основная идея интеграции заключается в том, что Lit-компоненты остаются нативными Web Components, а Vite выступает как современная среда разработки, обеспечивающая быстрый HMR, оптимизацию зависимостей и продакшн-бандлинг через Rollup.
Стартовая конфигурация Vite для Lit обычно строится на стандартном шаблоне vanilla, с добавлением TypeScript при необходимости.
npm create vite@latest vite-lit-app
cd vite-lit-app
npm install
Далее установка Lit:
npm install lit
Типичная структура при использовании Lit:
src/
components/
my-element.ts
styles/
global.css
main.ts
index.html
vite.config.ts
Ключевая особенность — отсутствие фреймворк-специфичной обвязки. Lit-компоненты являются самостоятельными модулями.
Lit использует декораторы и базовый класс LitElement.
Компонент описывается как класс с реактивными свойствами и шаблоном.
import { LitElement, html, css } from 'lit';
import { customElement, property } from 'lit/decorators.js';
@customElement('my-element')
export class MyElement extends LitElement {
static styles = css`
p {
color: blue;
font-size: 16px;
}
`;
@property({ type: String })
name = 'Lit';
render() {
return html`
<p>Привет, ${this.name}</p>
`;
}
}
import './components/my-element';
document.body.innerHTML = `
<my-element name="Vite + Lit"></my-element>
`;
Vite решает несколько ключевых задач при работе с Lit:
Особенно важно, что Lit-компоненты не требуют дополнительной трансформации — Vite работает напрямую с TypeScript и современным JavaScript.
Базовая конфигурация минимальна:
import { defineConfig } from 'vite';
export default defineConfig({
server: {
open: true
},
build: {
target: 'es2019'
}
});
Lit не требует специфического плагина Vite, так как не использует JSX или нестандартные runtime-преобразования.
Lit активно используется вместе с TypeScript для типизации свойств и событий компонентов.
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"experimentalDecorators": true,
"useDefineForClassFields": true
}
}
Ключевой параметр — experimentalDecorators, необходимый
для поддержки декораторов Lit.
Lit реализует реактивность через декоратор @property.
Изменение значения автоматически вызывает повторный рендер.
@property({ type: Number })
count = 0;
increment() {
this.count++;
}
render() {
return html`
<button @click=${this.increment}>
Счётчик: ${this.count}
</button>
`;
}
Vite в этом процессе не участвует напрямую, но обеспечивает мгновенное обновление модуля при изменении кода.
Lit поддерживает инкапсулированные стили через Shadow DOM. Это хорошо сочетается с Vite, так как стили обрабатываются как JS-строки без дополнительной сборки.
static styles = css`
:host {
display: block;
padding: 12px;
}
button {
background: black;
color: white;
}
`;
Дополнительно можно использовать глобальные стили через импорт CSS в Vite:
import './styles/global.css';
Vite позволяет импортировать изображения, шрифты и другие ресурсы напрямую в компоненты.
import logo from '../assets/logo.png';
render() {
return html`<img src=${logo} />`;
}
При сборке Vite оптимизирует и хеширует файлы автоматически.
ESM-модель Vite позволяет лениво загружать Lit-компоненты.
await import('./components/heavy-element.js');
После загрузки компонент становится доступным без дополнительной конфигурации. Это удобно для крупных приложений с разделением кода.
Lit использует стандартные DOM-события, а Vite не вмешивается в их обработку.
dispatchEvent(new CustomEvent('user-select', {
detail: { id: 1 },
bubbles: true,
composed: true
}));
Прослушивание:
document.querySelector('my-element')
?.addEventListener('user-select', (e: Event) => {
console.log((e as CustomEvent).detail);
});
Vite использует Rollup в production-режиме, что позволяет эффективно обрабатывать Lit-приложения:
Lit хорошо поддаётся tree-shaking благодаря ESM-структуре импорта:
import { html } from 'lit';
Hot Module Replacement в Vite работает на уровне модулей. Для Lit это означает:
При изменении render-функции Vite пересылает обновлённый модуль, а Lit повторно применяет шаблон.
Хотя Lit не включает встроенный роутинг, Vite легко комбинируется с легковесными решениями.
Пример динамической отрисовки:
const route = location.pathname;
if (route === '/about') {
await import('./pages/about-page');
}
Такой подход сохраняет минимальный размер бандла.
Vite оптимизирует зависимости через pre-bundling. Lit совместим с большинством UI- и утилитарных библиотек:
import { debounce } from 'lodash-es';
Важно использовать ESM-версии пакетов для корректного tree-shaking.
Vite предоставляет доступ к переменным окружения:
console.log(import.meta.env.VITE_API_URL);
Lit-компоненты могут использовать эти значения напрямую в логике или шаблонах.
Хотя Lit ориентирован на клиентский рендеринг, Vite может использоваться в SSR-сценариях через Node-окружение.
Основной подход:
Lit поддерживает серверный рендеринг через render() в
Node-окружении, что позволяет интегрировать его в Vite
SSR-пайплайны.
При росте проекта структура с Vite и Lit обычно переходит к модульной модели:
Vite поддерживает такую архитектуру без дополнительного слоя конфигурации, сохраняя скорость разработки и сборки.
Сочетание Vite и Lit обеспечивает:
Lit работает напрямую с DOM, а Vite — с модулями, что исключает избыточные абстракции и повышает общую производительность приложения.