Поле main в package.json определяет точку
входа модуля при использовании в среде, поддерживающей
CommonJS-резолюцию (Node.js и часть инструментов сборки).
Типичное значение:
{
"main": "dist/index.js"
}
При импорте пакета без указания конкретного файла резолвер обращается
к main и загружает указанный файл:
const lib = require("my-library");
В контексте современных сборщиков, включая Parcel, значение
main перестаёт быть единственным источником истины, но
продолжает играть роль базовой точки входа для
CommonJS-совместимости.
Важные особенности поведения:
require()module, exports)module
или exportsТипичная структура пакета:
dist/
index.js
index.mjs
src/
index.js
package.json
{
"main": "dist/index.js"
}
moduleПоле module введено для поддержки ES Modules в
экосистеме до появления стандартизированного поля exports.
Оно указывает на сборку, предназначенную для ESM-резолвинга.
Пример:
{
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js"
}
Разделение позволяет различным инструментам использовать оптимальный формат:
main → CommonJSmodule → ES ModulesВ контексте Parcel поле module активно используется для
tree-shaking и построения ESM-графа зависимостей. ES Modules позволяют
статически анализировать импорт:
import { sum } from "my-library";
Parcel может:
Ключевая особенность:
module имеет приоритет над main в
ESM-сценарияхТипичная конфигурация:
{
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js"
}
Резолюция модулей зависит от типа окружения:
CommonJS:
const pkg = require("pkg");
Используется:
mainindex.jsES Modules:
import pkg from "pkg";
Используется:
module (если поддерживается инструментом)exports (при наличии)Parcel анализирует оба сценария и строит два параллельных графа: CJS и ESM. Это позволяет поддерживать гибридные библиотеки без дублирования логики импорта.
exportsПоле exports является современным стандартом Node.js и
определяет явную карту экспортируемых точек входа. Оно заменяет неявное
поведение main и module, предоставляя строгую
структуру доступа к файлам пакета.
Простейший вариант:
{
"exports": "./dist/index.js"
}
Более сложная конфигурация:
{
"exports": {
".": {
"require": "./dist/index.cjs.js",
"import": "./dist/index.esm.js"
}
}
}
Такой подход позволяет:
my-lib/internal/file.js)Parcel полностью поддерживает exports и использует его
как приоритетный источник резолюции.
При сборке и импорте пакета порядок приоритета обычно следующий:
exportsmodule (в ESM-сценариях)mainindex.js (fallback)Этот порядок важен для понимания поведения при конфликтующих настройках.
Пример конфликта:
{
"main": "dist/cjs.js",
"module": "dist/esm.js",
"exports": "./dist/modern.js"
}
В этом случае exports полностью перекрывает
main и module.
При создании библиотеки важно учитывать совместимость с разными окружениями.
Рекомендуемая структура:
{
"name": "example-lib",
"version": "1.0.0",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"exports": {
".": {
"require": "./dist/cjs/index.js",
"import": "./dist/esm/index.js"
}
}
}
Такая конфигурация обеспечивает:
requireimportTree-shaking зависит от того, какой формат используется:
module, import) → статический
анализmain, require) → ограниченный
анализParcel использует module и exports.import
как основной источник для оптимизаций. Это позволяет удалять
неиспользуемые части кода.
Пример:
// utils.js
export function used() {}
export function unused() {}
import { used } from "lib";
В итоговую сборку попадёт только used.
main к
exportsСовременные пакеты постепенно смещаются от main/module к
exports, поскольку:
exports более строгийТем не менее main остаётся необходимым для:
Библиотека для широкого использования:
{
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js"
}
Современная библиотека:
{
"exports": {
".": {
"import": "./dist/index.js"
}
}
}
Смешанный подход:
{
"main": "dist/cjs.js",
"module": "dist/esm.js",
"exports": {
".": {
"require": "./dist/cjs.js",
"import": "./dist/esm.js"
}
}
}
Parcel одинаково корректно обрабатывает все три варианта, выбирая оптимальный путь сборки в зависимости от целевой среды.
Parcel анализирует package.json на этапе построения
графа зависимостей. Поля влияют на:
Особенно важно:
module ускоряет ESM-анализexports ограничивает доступ к внутренним
файламmainПри сборке монорепозиториев это становится критически важным, поскольку каждая зависимость может иметь собственную стратегию экспорта.
Часто встречающиеся проблемы:
Несогласованность путей
{
"main": "dist/index.js",
"module": "dist/index.mjs",
"exports": "./src/index.js"
}
Проблема: exports указывает на исходники вместо
сборки.
Отсутствие ESM-сборки при заявленном module
{
"module": "dist/index.js"
}
Проблема: файл CommonJS помечен как ESM.
Перекрытие exports
{
"main": "dist/a.js",
"exports": "./dist/b.js"
}
main становится недостижимым.
При публикации в npm структура package.json
определяет:
Parcel при установке пакета анализирует эти поля и строит оптимальный план включения зависимостей в финальный бандл, минимизируя лишний код и дублирование модулей.