Конфигурация через package.json: поле parcel

Бандлер Parcel придерживается принципа минимальной конфигурации и во многих случаях способен работать без отдельных файлов настроек. Значительная часть параметров может быть определена непосредственно внутри файла package.json через специальное поле parcel.

Такой подход позволяет хранить конфигурацию проекта в одном месте наряду с зависимостями, скриптами, метаданными пакета и настройками других инструментов.

Базовая структура выглядит следующим образом:

{
  "name": "my-app",
  "version": "1.0.0",
  "parcel": {
    // настройки Parcel
  }
}

Поле parcel представляет собой объект, содержащий различные параметры сборки, трансформации и обработки ресурсов.


Причины использования конфигурации в package.json

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

  • уменьшение количества конфигурационных файлов;
  • упрощение структуры проекта;
  • централизованное хранение настроек;
  • удобство публикации пакетов;
  • более простая поддержка небольших и средних проектов.

Вместо создания отдельных файлов конфигурации можно определить необходимые параметры непосредственно рядом с настройками проекта.

Пример:

{
  "name": "demo-project",
  "parcel": {
    "extends": "@parcel/config-default"
  }
}

Связь поля parcel с системой целей сборки

Одной из наиболее важных возможностей поля parcel является описание целей сборки (Targets).

Цели позволяют определять различные варианты выходных файлов:

  • браузерные версии;
  • серверные сборки;
  • библиотеки;
  • ESM-модули;
  • CommonJS-пакеты.

Пример конфигурации:

{
  "targets": {
    "main": {
      "context": "node"
    },
    "module": {
      "context": "browser"
    }
  }
}

Однако для библиотек часто используется и более компактный вариант через свойства пакета:

{
  "main": "dist/index.cjs",
  "module": "dist/index.js",
  "types": "dist/index.d.ts"
}

Parcel автоматически анализирует эти поля и создает соответствующие цели сборки.


Поле source

В конфигурации Parcel можно указать исходные точки входа через свойство source.

Пример:

{
  "source": "src/index.js"
}

Несколько файлов:

{
  "source": [
    "src/index.js",
    "src/admin.js"
  ]
}

Это особенно полезно при разработке библиотек, когда необходимо явно определить исходный код пакета.


Использование свойства targets

Наиболее часто поле parcel применяется совместно с настройкой целей сборки.

Пример:

{
  "parcel": {
    "targets": {
      "modern": {
        "outputFormat": "esmodule"
      }
    }
  }
}

Здесь создается цель modern, использующая формат ES Modules.


Настройка выходного каталога

Каждая цель может иметь собственный каталог вывода.

Пример:

{
  "parcel": {
    "targets": {
      "modern": {
        "distDir": "dist/modern"
      }
    }
  }
}

После сборки результаты окажутся в папке:

dist/
└── modern/

Форматы модулей

Parcel поддерживает несколько форматов выходных модулей.

ES Modules

{
  "parcel": {
    "targets": {
      "esm": {
        "outputFormat": "esmodule"
      }
    }
  }
}

Результат:

export function hello() {}

CommonJS

{
  "parcel": {
    "targets": {
      "cjs": {
        "outputFormat": "commonjs"
      }
    }
  }
}

Результат:

exports.hello = hello;

Global

{
  "parcel": {
    "targets": {
      "browser": {
        "outputFormat": "global"
      }
    }
  }
}

Результат будет доступен через глобальное пространство имен браузера.


Управление контекстом выполнения

Параметр context определяет окружение, для которого производится сборка.

Браузер

{
  "parcel": {
    "targets": {
      "browser": {
        "context": "browser"
      }
    }
  }
}

Node.js

{
  "parcel": {
    "targets": {
      "server": {
        "context": "node"
      }
    }
  }
}

Web Worker

{
  "parcel": {
    "targets": {
      "worker": {
        "context": "web-worker"
      }
    }
  }
}

От выбранного контекста зависит набор встроенных API и правила трансформации кода.


Поддержка современных браузеров

Через настройки целей можно контролировать уровень совместимости.

Пример:

{
  "parcel": {
    "targets": {
      "modern": {
        "engines": {
          "browsers": [
            "last 2 Chrome versions"
          ]
        }
      }
    }
  }
}

Parcel автоматически определяет необходимые преобразования JavaScript и CSS.


Использование Browserslist

Чаще всего ограничения платформ задаются через стандартное поле browserslist.

{
  "browserslist": [
    "> 0.5%",
    "last 2 versions",
    "not dead"
  ]
}

Parcel использует эту информацию при сборке клиентских приложений.

В таком случае дополнительная настройка внутри поля parcel обычно не требуется.


Настройка оптимизации

Для отдельных целей можно явно управлять оптимизацией.

Пример:

{
  "parcel": {
    "targets": {
      "production": {
        "optimize": true
      }
    }
  }
}

Обычно данный параметр автоматически активируется в production-сборках, однако его можно определить вручную.


Управление созданием source maps

Source maps позволяют связывать итоговый код с исходными файлами.

Включение:

{
  "parcel": {
    "targets": {
      "debug": {
        "sourceMap": true
      }
    }
  }
}

Отключение:

{
  "parcel": {
    "targets": {
      "production": {
        "sourceMap": false
      }
    }
  }
}

В production-среде отключение source maps помогает уменьшить размер сборки.


Настройка публичного пути

Публичный путь определяет базовый URL для загрузки ресурсов.

Пример:

{
  "parcel": {
    "targets": {
      "web": {
        "publicUrl": "/static"
      }
    }
  }
}

В результате ссылки на ресурсы будут формироваться относительно каталога /static.

Например:

<script src="/static/app.js"></script>

Создание библиотек

Parcel активно используется для разработки npm-библиотек.

Пример конфигурации:

{
  "name": "my-library",
  "source": "src/index.js",
  "main": "dist/main.js",
  "module": "dist/module.js",
  "types": "dist/index.d.ts"
}

Во многих случаях этого уже достаточно для полноценной сборки библиотеки.

Parcel самостоятельно создаст необходимые варианты выходных файлов.


Несколько целей сборки одновременно

Один проект может генерировать несколько разновидностей артефактов.

Пример:

{
  "parcel": {
    "targets": {
      "esm": {
        "outputFormat": "esmodule",
        "distDir": "dist/esm"
      },
      "cjs": {
        "outputFormat": "commonjs",
        "distDir": "dist/cjs"
      }
    }
  }
}

После сборки структура может выглядеть так:

dist/
├── esm/
│   └── index.js
└── cjs/
    └── index.js

Подобная схема часто применяется при публикации универсальных библиотек.


Наследование конфигурации через extends

Parcel поддерживает механизм расширения конфигураций.

Пример:

{
  "parcel": {
    "extends": "@parcel/config-default"
  }
}

В этом случае используется стандартная конфигурация Parcel, поверх которой могут быть добавлены собственные настройки.


Отключение отдельных целей

Иногда требуется временно исключить определенную цель из сборки.

Пример:

{
  "parcel": {
    "targets": {
      "legacy": false
    }
  }
}

Такая цель будет проигнорирована во время процесса сборки.


Настройка имени глобальной переменной

Для формата global можно определить имя экспортируемого объекта.

{
  "parcel": {
    "targets": {
      "browser": {
        "outputFormat": "global",
        "isLibrary": true
      }
    }
  }
}

В сочетании с корректными настройками экспорта библиотека станет доступна как глобальный объект браузера.


Полная конфигурация поля parcel

Пример проекта, использующего различные возможности конфигурации:

{
  "name": "advanced-app",
  "version": "1.0.0",

  "source": "src/index.js",

  "parcel": {
    "extends": "@parcel/config-default",

    "targets": {
      "modern": {
        "context": "browser",
        "outputFormat": "esmodule",
        "distDir": "dist/modern",
        "optimize": true,
        "sourceMap": true,
        "publicUrl": "/assets"
      },

      "server": {
        "context": "node",
        "outputFormat": "commonjs",
        "distDir": "dist/server"
      }
    }
  }
}

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

Рекомендации по использованию

Для небольших приложений обычно достаточно минимальной конфигурации:

{
  "source": "src/index.html"
}

Для библиотек рекомендуется указывать:

{
  "source": "src/index.js",
  "main": "dist/index.cjs",
  "module": "dist/index.js",
  "types": "dist/index.d.ts"
}

Для крупных проектов удобно использовать несколько целей сборки с индивидуальными параметрами:

{
  "parcel": {
    "targets": {
      "browser": {},
      "server": {},
      "legacy": {}
    }
  }
}

Поле parcel служит центральной точкой настройки поведения Parcel внутри package.json, позволяя управлять выходными форматами, окружениями выполнения, оптимизацией, картами исходного кода, каталогами сборки и другими аспектами процесса сборки без необходимости создавать отдельные конфигурационные файлы.