Настройка сборки и bundling

Основные принципы сборки

SvelteKit использует современный подход к сборке, ориентированный на Vite как инструмент сборки и бандлинга. Vite обеспечивает высокую скорость сборки за счёт использования ES-модулей и предварительной трансформации кода только по необходимости. Для UI-библиотек это критически важно, поскольку позволяет минимизировать размер итогового бандла и ускорить загрузку компонентов на клиенте.

Ключевые моменты при настройке сборки:

  • ES-модули vs CommonJS – SvelteKit по умолчанию поддерживает экспорт ES-модулей. Для публикации UI-библиотеки рекомендуется использовать esm-формат, обеспечивающий tree-shaking.
  • Tree-shaking – удаление неиспользуемого кода из бандла. В SvelteKit это реализуется за счёт компиляции Svelte-компонентов и анализа импорта/экспорта в модуле.
  • Минификация – Vite автоматически минифицирует JS и CSS при продакшн-сборке, используя esbuild.

Конфигурация vite.config.js для UI-библиотек

Для UI-библиотек важно правильно настроить vite.config.js, чтобы сборка была легковесной, совместимой и поддерживала SSR. Основные опции:

import { sveltekit } from '@sveltejs/kit/vite';
import path from 'path';

export default {
  plugins: [sveltekit()],
  build: {
    lib: {
      entry: path.resolve(__dirname, 'src/index.js'),
      name: 'MyUILib',
      fileName: (format) => `my-ui-lib.${format}.js`,
      formats: ['es', 'cjs']
    },
    rollupOptions: {
      external: ['svelte', 'svelte/internal'],
      output: {
        globals: {
          svelte: 'Svelte'
        }
      }
    }
  },
  resolve: {
    alias: {
      '@components': path.resolve('./src/components')
    }
  }
};

Разбор ключевых пунктов:

  • lib.entry – точка входа для сборки UI-библиотеки. Обычно это src/index.js или src/lib.js.
  • formats – форматы бандла: ES-модули (es) для современных проектов и CommonJS (cjs) для Node.js и старых сборок.
  • external – список зависимостей, которые не должны попадать в бандл. Например, Svelte и другие сторонние библиотеки.
  • alias – удобство импорта компонентов, сокращает пути и предотвращает дублирование кода.

Работа с CSS и стилями компонентов

SvelteKit поддерживает встроенные CSS-модули, а также интеграцию с PostCSS и Tailwind. Для UI-библиотеки критично обеспечить корректный экспорт стилей:

  • Scoped CSS – все стили Svelte-компонентов по умолчанию изолированы, что предотвращает конфликт с глобальными стилями.
  • Экспорт глобальных стилей – при необходимости можно создать отдельный CSS-файл и подключать его через import 'my-ui-lib/styles.css'.
  • Минификация CSS – Vite автоматически минифицирует CSS при продакшн-сборке.

Пример интеграции Tailwind в SvelteKit UI-библиотеку:

// tailwind.config.cjs
module.exports = {
  content: ['./src/**/*.{svelte,js}'],
  theme: {
    extend: {}
  },
  plugins: []
};

В src/index.js можно подключить стили:

import './styles/tailwind.css';
export { default as Button } from './components/Button.svelte';

Настройка bundle для оптимизации

Для больших UI-библиотек важно настроить разделение кода (code splitting) и динамический импорт:

  • Code splitting – разбивает библиотеку на отдельные чанки, которые загружаются по требованию.
  • Dynamic import – позволяет импортировать отдельные компоненты только при их использовании:
// Пример ленивой загрузки компонента
let ButtonComponent;
async function loadButton() {
  if (!ButtonComponent) {
    const module = await import('./components/Button.svelte');
    ButtonComponent = module.default;
  }
  return ButtonComponent;
}
  • RollupOptions – настройка внешних зависимостей и глобальных переменных позволяет избежать дублирования кода и уменьшить размер финального бандла.

SSR и сборка UI-библиотеки

SvelteKit поддерживает server-side rendering. Для UI-библиотеки это важно, чтобы компоненты корректно рендерились на сервере без ошибок. Основные рекомендации:

  • Использовать проверку browser для кода, который зависит от DOM:
import { browser } from '$app/environment';

if (browser) {
  // код, работающий только в браузере
}
  • Не включать зависимости, требующие window/document, в бандл для SSR. Их лучше пометить как external.
  • Проверять корректность гидратации компонентов на клиенте.

Интеграция с NPM

После сборки UI-библиотеки важно правильно подготовить пакет к публикации:

  • package.json:
{
  "name": "my-ui-lib",
  "version": "1.0.0",
  "main": "dist/my-ui-lib.cjs.js",
  "module": "dist/my-ui-lib.es.js",
  "types": "dist/index.d.ts",
  "files": ["dist"],
  "exports": {
    ".": {
      "import": "./dist/my-ui-lib.es.js",
      "require": "./dist/my-ui-lib.cjs.js"
    }
  }
}
  • Генерация деклараций TypeScript (.d.ts) для поддержки автодополнения и типизации.
  • Разделение продакшн и development сборок через скрипты npm run build и npm run dev.

Автоматизация сборки

Для удобства используется комбинация Vite, Rollup и скриптов npm. Типичный workflow:

  1. npm run dev – локальная сборка и проверка компонентов.
  2. npm run build – продакшн сборка, минификация, генерация .d.ts.
  3. npm publish – публикация на npm.

Такой подход обеспечивает эффективный, модульный и масштабируемый бандлинг, позволяя создавать UI-библиотеки, совместимые с современными проектами SvelteKit.