unbuild для TypeScript: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

unbuild для TypeScript: полное руководство с примерами

В современной экосистеме JavaScript и TypeScript сборка проектов является одной из ключевых задач. Разработчики часто сталкиваются с необходимостью настройки сложных конфигураций для Webpack, Rollup или esbuild. Библиотека unbuild предлагает элегантное решение — единую систему сборки, которая объединяет лучшие практики и инструменты в одном интерфейсе. Это не просто очередной сборщик, а унифицированная обёртка над esbuild и Rollup, которая автоматически определяет оптимальную стратегию сборки для вашего проекта.

Основная цель unbuild — максимально упростить процесс сборки TypeScript-библиотек. Вместо того чтобы тратить часы на настройку конфигурационных файлов, разработчик получает готовое решение "из коробки". Библиотека автоматически генерирует CommonJS и ESM сборки, создаёт декларации типов (d.ts), оптимизирует бандлы и поддерживает современные возможности TypeScript. Это делает unbuild идеальным выбором для авторов npm-пакетов и open-source проектов.

Unbuild особенно полезен в следующих сценариях: создание монорепозиториев, сборка библиотек с поддержкой tree-shaking, публикация пакетов с TypeScript-исходниками, миграция с устаревших сборщиков. Благодаря встроенной поддержке package.json экспортов и автоматическому определению точек входа, библиотека позволяет сосредоточиться на написании кода, а не на настройке инфраструктуры.

Установка

Для установки unbuild используется менеджер пакетов npm (или альтернативы — yarn, pnpm). Библиотека устанавливается как dev-зависимость:

npm install -D unbuild

Или с помощью yarn:

yarn add -D unbuild

Для pnpm:

pnpm add -D unbuild

После установки рекомендуется добавить скрипт сборки в package.json:

{
  "scripts": {
    "build": "unbuild",
    "dev": "unbuild --watch"
  }
}

Быстрый старт

Создадим минимальный рабочий проект. Структура файлов:

my-library/
├── src/
│   └── index.ts
├── package.json
└── tsconfig.json

Содержимое src/index.ts:

export function greet(name: string): string {
  return `Hello, ${name}!`;
}

export const version = '1.0.0';

tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "esModuleInterop": true,
    "declaration": true,
    "outDir": "./dist"
  },
  "include": ["src"]
}

Теперь запустим сборку:

npx unbuild

После выполнения в папке dist появятся файлы:

  • dist/index.mjs — ESM сборка
  • dist/index.cjs — CommonJS сборка
  • dist/index.d.ts — декларации типов
  • dist/index.d.mts — декларации для ESM

Unbuild автоматически создаёт обе сборки и генерирует TypeScript-декларации. Для настройки экспортов в package.json добавьте:

{
  "main": "./dist/index.cjs",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs",
      "types": "./dist/index.d.ts"
    }
  }
}

Основные методы и функции

1. defineBuildConfig(config)

Сигнатура: defineBuildConfig(config: BuildConfig): BuildConfig

Описание: Основная функция для создания конфигурации сборки. Принимает объект с настройками и возвращает его с типизацией. Используется в файле build.config.ts.

Пример:

// build.config.ts
import { defineBuildConfig } from 'unbuild';

export default defineBuildConfig({
  entries: ['./src/index'],
  outDir: './dist',
  declaration: true,
  clean: true,
  rollup: {
    emitCJS: true,
  },
});

2. build(config)

Сигнатура: build(config?: BuildConfig): Promise<BuildResult>

Описание: Программный запуск сборки. Позволяет выполнять сборку из кода, а не только через CLI. Возвращает Promise с результатами сборки.

Пример:

import { build } from 'unbuild';

async function runBuild() {
  const result = await build({
    entries: ['./src/index'],
    outDir: './dist',
  });
  console.log('Build completed:', result);
}

runBuild();

3. createBuildContext(config)

Сигнатура: createBuildContext(config?: BuildConfig): BuildContext

Описание: Создаёт контекст сборки, который можно использовать для программного управления процессом. Позволяет выполнять отдельные шаги сборки.

Пример:

import { createBuildContext } from 'unbuild';

const ctx = createBuildContext({
  entries: ['./src/index'],
});

// Выполнить подготовку
await ctx.prepare();

// Запустить сборку
await ctx.build();

// Очистить временные файлы
await ctx.cleanup();

4. mkdist(input, output, options)

Сигнатура: mkdist(input: string, output: string, options?: MkdistOptions): Promise<void>

Описание: Утилита для компиляции TypeScript-файлов в JavaScript с сохранением структуры директорий. Полезна для сборки библиотек с множеством файлов.

Пример:

import { mkdist } from 'unbuild';

await mkdist('./src', './dist', {
  format: 'esm',
  declaration: true,
  pattern: ['**/*.ts', '!**/*.test.ts'],
});

5. copyTemplates(config)

Сигнатура: copyTemplates(config: CopyTemplatesConfig): Promise<void>

Описание: Копирует шаблонные файлы (например, README.md, LICENSE) в директорию сборки. Позволяет автоматизировать подготовку пакета к публикации.

Пример:

import { copyTemplates } from 'unbuild';

await copyTemplates({
  srcDir: './templates',
  destDir: './dist',
  files: ['README.md', 'LICENSE', 'CHANGELOG.md'],
});

6. getBuildConfig(config)

Сигнатура: getBuildConfig(config?: BuildConfig): Promise<ResolvedBuildConfig>

Описание: Разрешает и возвращает полную конфигурацию сборки с применёнными значениями по умолчанию. Полезно для отладки и проверки итоговых настроек.

Пример:

import { getBuildConfig } from 'unbuild';

const resolvedConfig = await getBuildConfig({
  entries: ['./src/index'],
});

console.log('Resolved output directory:', resolvedConfig.outDir);
console.log('Entries:', resolvedConfig.entries);

7. cleanDir(dir)

Сигнатура: cleanDir(dir: string): Promise<void>

Описание: Очищает указанную директорию от файлов и папок. Используется для удаления предыдущей сборки перед новой.

Пример:

import { cleanDir } from 'unbuild';

// Очистить директорию dist перед сборкой
await cleanDir('./dist');

// Теперь можно запускать сборку
await build({ entries: ['./src/index'], outDir: './dist' });

8. resolveEntries(entries)

Сигнатура: resolveEntries(entries: Entry[]): Promise<ResolvedEntry[]>

Описание: Разрешает точки входа для сборки, преобразуя относительные пути в абсолютные и проверяя существование файлов. Полезно для валидации конфигурации.

Пример:

import { resolveEntries } from 'unbuild';

const entries = [
  { name: 'index', input: './src/index.ts' },
  { name: 'utils', input: './src/utils/index.ts' },
];

const resolved = await resolveEntries(entries);
console.log('Resolved entries:', resolved);

9. generateTypes(config)

Сигнатура: generateTypes(config: GenerateTypesConfig): Promise<void>

Описание: Генерирует TypeScript-декларации (.d.ts) для указанных файлов. Может использоваться отдельно от основной сборки.

Пример:

import { generateTypes } from 'unbuild';

await generateTypes({
  entries: ['./src/index.ts'],
  outDir: './types',
  tsconfig: './tsconfig.json',
});

10. createRollupConfig(config)

Сигнатура: createRollupConfig(config: RollupConfig): Promise<RollupOptions>

Описание: Создаёт конфигурацию для Rollup на основе настроек unbuild. Позволяет расширить стандартную сборку дополнительными плагинами Rollup.

Пример:

import { createRollupConfig } from 'unbuild';
import json from '@rollup/plugin-json';

const rollupConfig = await createRollupConfig({
  entries: ['./src/index'],
  outDir: './dist',
  plugins: [json()],
});

console.log('Rollup config:', rollupConfig);

Реальный практический пример

Создадим полноценную библиотеку для работы с математическими операциями. Проект будет включать несколько модулей, тесты и демонстрацию всех возможностей unbuild.

Структура проекта:

math-lib/
├── src/
│   ├── index.ts
│   ├── arithmetic.ts
│   ├── geometry.ts
│   └── utils.ts
├── tests/
│   └── arithmetic.test.ts
├── templates/
│   ├── README.md
│   └── LICENSE
├── build.config.ts
├── package.json
└── tsconfig.json

src/arithmetic.ts:

export function add(a: number, b: number): number {
  return a + b;
}

export function subtract(a: number, b: number): number {
  return a - b;
}

export function multiply(a: number, b: number): number {
  return a * b;
}

export function divide(a: number, b: number): number {
  if (b === 0) {
    throw new Error('Division by zero');
  }
  return a / b;
}

export function power(base: number, exponent: number): number {
  return Math.pow(base, exponent);
}

src/geometry.ts:

export interface Circle {
  radius: number;
}

export interface Rectangle {
  width: number;
  height: number;
}

export function circleArea(circle: Circle): number {
  return Math.PI * circle.radius ** 2;
}

export function rectangleArea(rect: Rectangle): number {
  return rect.width * rect.height;
}

export function circleCircumference(circle: Circle): number {
  return 2 * Math.PI * circle.radius;
}

src/utils.ts:

export function clamp(value: number, min: number, max: number): number {
  return Math.min(Math.max(value, min), max);
}

export function randomInteger(min: number, max: number): number {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

export function sumArray(numbers: number[]): number {
  return numbers.reduce((acc, curr) => acc + curr, 0);
}

export function averageArray(numbers: number[]): number {
  if (numbers.length === 0) return 0;
  return sumArray(numbers) / numbers.length;
}

src/index.ts:

export * from './arithmetic';
export * from './geometry';
export * from './utils';

export const VERSION = '1.0.0';

export function greet(): string {
  return 'Welcome to MathLib!';
}

build.config.ts:

import { defineBuildConfig } from 'unbuild';

export default defineBuildConfig({
  entries: [
    './src/index',
    { name: 'arithmetic', input: './src/arithmetic' },
    { name: 'geometry', input: './src/geometry' },
    { name: 'utils', input: './src/utils' },
  ],
  outDir: './dist',
  declaration: true,
  clean: true,
  rollup: {
    emitCJS: true,
    esbuild: {
      target: 'es2020',
    },
  },
  hooks: {
    'build:done': async (ctx) => {
      console.log('Build completed successfully!');
      console.log(`Output directory: ${ctx.options.outDir}`);
    },
  },
});

package.json:

{
  "name": "math-lib",
  "version": "1.0.0",
  "description": "A comprehensive math library",
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./                    

Рекомендаций