Публикация JavaScript-библиотеки в npm-экосистеме опирается на корректную структуру пакета, предсказуемую сборку и совместимость модулей. В связке с современными инструментами сборки используется Parcel, который обеспечивает автоматическую трансформацию кода, поддержку ESM/CJS и генерацию production-сборок без сложной конфигурации.
Базовая структура проекта библиотеки обычно включает:
src/ — исходный кодdist/ — итоговая сборкаpackage.json — описание пакетаREADME.md — документация.npmignore или конфигурация files в
package.jsonКлючевой принцип: в npm публикуется только результат сборки, а не исходники.
Файл конфигурации пакета формируется через npm и описывает все аспекты публикации.
Базовая инициализация:
npm init
После создания package.json фиксируются основные
поля:
{
"name": "my-library",
"version": "1.0.0",
"main": "dist/index.cjs",
"module": "dist/index.js",
"source": "src/index.js",
"type": "module",
"files": [
"dist"
]
}
Исходный код библиотеки должен быть максимально чистым и не зависеть от окружения публикации.
Пример структуры:
src/
index.js
utils/
format.js
validate.js
Главный экспорт:
export { format } from "./utils/format.js";
export { validate } from "./utils/validate.js";
Parcel автоматически анализирует зависимости, формируя граф модулей.
Parcel поддерживает сборку библиотек без конфигурационного файла. Достаточно указать входной файл.
Команда сборки:
parcel build src/index.js --dist-dir dist
Parcel автоматически:
Для отключения source maps:
parcel build src/index.js --no-source-maps
Современная библиотека должна поддерживать оба формата модулей.
Parcel позволяет генерировать несколько выходных файлов через поля
package.json:
{
"main": "dist/index.cjs",
"module": "dist/index.js",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
}
Часто используется две сборки:
Файл src/index.js определяет контракт библиотеки. Важно
ограничить поверхность API:
export { parseDate } from "./date/parse.js";
export { formatDate } from "./date/format.js";
Не рекомендуется экспортировать внутренние утилиты напрямую, чтобы не фиксировать их как часть публичного API.
В package.json зависимости делятся на:
Используются внутри библиотеки:
"dependencies": {
"lodash-es": "^4.17.21"
}
Обязательные внешние зависимости:
"peerDependencies": {
"react": ">=18"
}
Инструменты разработки:
"devDependencies": {
"parcel": "^2.0.0"
}
Parcel учитывает зависимости при построении графа модулей, исключая dev-зависимости из production-сборки.
Критически важные поля:
{
"name": "my-library",
"version": "1.0.0",
"description": "Utility library",
"license": "MIT",
"files": ["dist"],
"sideEffects": false
}
Флаг влияет на tree-shaking:
false — безопасное удаление неиспользуемого кодаДля ограничения содержимого пакета используются:
src/
tests/
parcel-cache/
Предпочтительный способ:
"files": ["dist", "README.md"]
Типичный workflow:
parcel build src/index.js --dist-dir dist
Проверка результата:
dist/
index.js
index.cjs
index.js.map
Перед отправкой пакета в реестр npm выполняется аутентификация:
npm login
Публикация:
npm publish
Для scoped-пакетов:
npm publish --access public
Используется semver:
Команды:
npm version patch
npm version minor
npm version major
При использовании Parcel важно учитывать:
"source": "src/index.js"
Внутренние файлы не экспортируются напрямую наружу.
Чем меньше публичных экспортов, тем стабильнее библиотека.
Хотя Parcel способен обрабатывать TypeScript, типы публикуются отдельно:
"types": "dist/index.d.ts"
Генерация типов выполняется отдельно от Parcel через
tsc.
Sourcemaps обеспечивают отладку production-кода:
parcel build src/index.js --dist-dir dist --source-maps
Локальная проверка:
npm pack
Создаётся .tgz архив, идентичный публикации в npm.
Причина: отсутствие files или
.npmignore.
Причина: не синхронизированы main, module,
exports.
Причина: перенос runtime-библиотек в
devDependencies.
Причина: sideEffects не настроен.
project/
src/
dist/
package.json
README.md
Финальный package.json:
{
"name": "my-library",
"version": "1.0.0",
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"sideEffects": false
}
Сборка через Parcel формирует дистрибутив, готовый к публикации в экосистему npm с поддержкой современных модульных стандартов и оптимизаций.