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": "./ Также в библиотеке
Валидация данных в Rust: обзор библиотек и фреймворков
Rate Limiting в Java: библиотеки и инструменты для контроля запросов (Bucket4j, Resilience4j)
Планировщик задач Kotlin: kotlinx-coroutines-core и библиотека korGE
Мониторинг приложений Rust: библиотека `tracing`
Парсинг HTML в PHP: DOMDocument, SimpleXML и cURL для веб-скрапинга