esbuild: сборка библиотеки или утилиты (build.mjs)
Практический build.mjs для сборки библиотеки или небольшой утилиты через официальный API esbuild: entryPoints, bundle, outdir, minify, sourcemap, target. Запуск: node build.mjs.
Как использовать
- Положить build.mjs в корень проекта, точку входа (например src/index.ts) — в entryPoints.
- Установить esbuild: npm i -D esbuild
- Запуск: node build.mjs
- Результат — в dist/ (или в outdir по вашему выбору)
Собрать библиотеку или CLI-утилиту на TypeScript/ESM без тяжёлого конфига и долгой сборки можно через esbuild. Для одного или нескольких entry-файлов, бандла зависимостей, минификации и source map достаточно вызова esbuild.build() из скрипта. Проблема: подключают Webpack или Vite ради одной утилиты или библиотеки — конфиг раздувается, сборка медленнее. Симптомы: долгий cold build, избыточные плагины. Ниже — минимальный build.mjs по официальному API esbuild, проверка вывода и когда разумнее Vite/Webpack.
Решение
Скрипт использует только официальный API esbuild, без экспериментальных флагов.
Файл: build.mjs (в корне проекта):
import * as esbuild from 'esbuild';
await esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
outdir: 'dist',
minify: true,
sourcemap: true,
target: ['es2020'],
format: 'esm',
platform: 'neutral',
});
console.log('Build done → dist/');
- entryPoints — один или несколько входных файлов; при одном entry в outdir получится файл с тем же именем (например dist/index.js).
- bundle: true — зависимости подтягиваются в один бандл; иначе только транспиляция.
- minify, sourcemap — минификация и source map для отладки прод-сборки.
- target — цель транспиляции (es2020, node18 и т.д.).
- format — ‘esm’ или ‘cjs’; для Node-утилиты можно ‘cjs’.
- platform — ‘neutral’ для универсальной библиотеки, ‘node’ для утилиты только под Node.
Запуск:
npm i -D esbuild
node build.mjs
Точка входа src/index.ts (или src/index.js) должна существовать.
Когда удобен esbuild
- Библиотеки и утилиты — один или несколько entry, быстрый бандл, минификация и source map из коробки.
- CLI на TypeScript/ESM — один файл под Node без лишних плагинов.
- Часть пайплайна — вызов из npm-скриптов, Gulp, CI.
Когда лучше Vite/Webpack
- Полноценный фронт с HTML, dev-сервером, HMR — у Vite это из коробки; у esbuild только serve/watch.
- Сложный граф ассетов (CSS-препроцессоры, SVG как компоненты, тонкий контроль чанков) — богаче у Vite/Webpack.
- Легаси, динамические импорты вида
import(variable)— Webpack и плагины обходят такие кейсы; esbuild ожидает статические импорты.
Проверка
- Успешная сборка и наличие файлов:
node build.mjs
ls -la dist/
Ожидаем файлы вида index.js и при sourcemap: true — index.js.map. Ошибки вывода esbuild в консоль (например отсутствующий entry).
- Проверка вывода (Node-утилита):
node dist/index.js
Если точка входа — исполняемый скрипт, он должен выполниться. Для библиотеки проверьте импорт в тестовом файле: import ... from './dist/index.js'.
- Размер и минификация — после сборки откройте
dist/index.js: код должен быть в одну строку (при minify: true). Размер можно сравнить до/после отключения minify.
Типичные ошибки
- Entry point not found — путь в
entryPointsневерный или файл отсутствует. Укажите путь относительно корня проекта (напримерsrc/index.ts). - Cannot find module — зависимость не установлена или esbuild не резолвит её (например нестандартное расширение). Для Node-сборки можно задать
platform: 'node', тогда в бандл не тянутся браузерные полифиллы. - Source map не подхватывается — убедитесь, что в конце сгенерированного .js есть комментарий
//# sourceMappingURL=index.js.mapи файл .map лежит рядом. Для отладки в IDE/Node проверьте настройки (например NODE_OPTIONS=—enable-source-maps).
Где применять
- Библиотеки и утилиты: npm-пакеты, внутренние либы, CLI. Сборка одной командой, без HTML и dev-сервера.
- CI / скрипты: вызов
node build.mjsв package.json или пайплайне; один артефакт в dist/.
Связанные сниппеты: Vite: конфиг для production, Типовая миграция Webpack → Vite, Webpack: конфиг для production — для сравнения при выборе сборщика.