В Parcel система целей сборки (targets) определяет, под какую среду выполняется итоговый бандл: браузер, Node.js, Electron и другие окружения. При выборе Node.js target сборщик перестраивает граф модулей, формат вывода и поведение зависимостей так, чтобы код корректно выполнялся в серверной среде без браузерных API.
Node target в Parcel ориентирован на создание серверных приложений, CLI-утилит и библиотек, которые выполняются в среде Node.js. Его ключевая задача — исключить браузерные предположения из сборки и адаптировать код под Node runtime.
Parcel использует декларативную модель конфигурации, где цели сборки
описываются через package.json или через CLI.
Каждый target определяет:
Структура targets в package.json:
{
"targets": {
"node": {
"context": "node",
"engines": {
"node": ">=18"
},
"outputFormat": "commonjs",
"distDir": "dist/node"
}
}
}
Ключевой параметр Node target — context: "node". Он
переключает внутреннюю логику Parcel:
В browser target Parcel может автоматически добавлять полифилы для
process, Buffer, path,
crypto. В node target это поведение отключается.
Модули fs, path, stream,
url, crypto остаются нативными и не
подменяются браузерными заглушками.
Parcel не пытается адаптировать код под DOM-окружение, что сокращает количество трансформаций.
Node target может генерировать два основных формата:
"outputFormat": "commonjs"
Используется для максимальной совместимости со старыми версиями Node.js и большинством npm-пакетов.
Пример результата:
const fs = require("fs");
module.exports = function readFile(path) {
return fs.readFileSync(path, "utf8");
};
"outputFormat": "module"
Подходит для современных версий Node.js с поддержкой ESM.
import fs from "fs";
export function readFile(path) {
return fs.readFileSync(path, "utf8");
}
Parcel автоматически адаптирует расширения и синтаксис под выбранный формат.
Node target можно задать без конфигурационного файла:
parcel build src/index.js --target node
Дополнительные параметры:
parcel build src/index.js \
--target node \
--dist-dir dist/node \
--no-minify
CLI target переопределяет настройки из package.json,
если конфликтует.
Parcel поддерживает мульти-target сборку, что особенно важно для универсальных библиотек.
Пример конфигурации:
{
"targets": {
"browser": {
"context": "browser",
"outputFormat": "esmodule",
"distDir": "dist/browser"
},
"node": {
"context": "node",
"outputFormat": "commonjs",
"distDir": "dist/node"
}
}
}
Структура входа:
export function sharedLogic() {
return "core";
}
Parcel создаёт два независимых бандла, оптимизированных под разные среды.
В node target Parcel ведёт себя иначе по отношению к встроенным модулям:
Модули:
fspathosnethttpостаются внешними зависимостями.
import path from "path";
import fs from "fs";
В итоговом бандле они сохраняются как require("fs").
Parcel в Node target может работать в двух режимах:
Зависимости включаются в бандл, если они ESM или не отмечены как external.
При некоторых конфигурациях зависимости остаются внешними:
"targets": {
"node": {
"external": ["express"]
}
}
Это используется для серверных приложений, где
node_modules доступны на диске.
Node target учитывает поле exports:
{
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
}
}
Parcel корректно выбирает entrypoint в зависимости от outputFormat и context.
Tree shaking в Node target работает иначе, чем в браузерном:
Пример:
export function used() {
return "used";
}
export function unused() {
return "unused";
}
Если unused не импортируется, Parcel удалит её, но
только при отсутствии sideEffects в package.json.
Node target учитывает:
{
"sideEffects": false
}
Это позволяет безопасно удалять неиспользуемые модули.
Если sideEffects: true, Parcel сохраняет выполнение всех
импортов, даже если они не используются напрямую.
Node target активно использует process.env:
if (process.env.NODE_ENV === "production") {
console.log("prod mode");
}
Parcel выполняет compile-time replacement:
process.env.NODE_ENV → "production"
Это позволяет удалять условные ветки в продакшене.
Parcel генерирует source maps для Node сборок:
{
"sourceMaps": true
}
Это критично для:
Node.js поддерживает source maps нативно, начиная с современных версий, что делает интеграцию прозрачной.
Node target поддерживает:
const module = await import("./dynamic.js");
Parcel преобразует это в:
В ESM режиме Node target Parcel эмулирует:
import { fileURLToPath } from "url";
import { dirname } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
В CommonJS режиме они остаются нативными.
Node target включает специфические оптимизации:
Нет загрузки document, window,
navigator.
Меньше bootstrap-кода по сравнению с browser target.
Быстрее разрешение модулей за счёт Node resolution algorithm.
Node target корректно работает с TypeScript входами:
{
"extends": "@parcel/config-default",
"targets": {
"node": {
"context": "node"
}
}
}
Parcel выполняет:
В монорепо структурах Node target часто используется для:
Parcel корректно обрабатывает workspace зависимости, избегая дублирования зависимостей в бандле.
exportswindow.fetch()
в node target приведёт к runtime error без polyfill.
Использование module в старых версиях Node без ESM
поддержки вызывает ошибку загрузки.
Если не указать external для тяжёлых библиотек, bundle может стать избыточным.
Node target следует Node resolution algorithm:
Parcel не переопределяет эту модель, а расширяет её оптимизациями сборки.