Сборка серверного JavaScript-кода отличается от браузерной прежде всего окружением исполнения. Node.js предоставляет доступ к файловой системе, сетевым интерфейсам и встроенным модулям, которые не требуют полифиллов или бандлирования в привычном смысле.
Parcel при работе с серверным кодом переходит в режим, ориентированный на Node.js, где ключевыми становятся следующие аспекты:
fs,
path, http)node_modules)require и importГлавная цель серверной сборки — не уменьшить размер, а обеспечить предсказуемое и переносимое выполнение кода.
Parcel автоматически определяет контекст по целевому окружению или конфигурации.
Типичный входной файл серверного приложения:
// src/server.js
import http from 'http';
import app from './app.js';
const server = http.createServer(app);
server.listen(3000, () => {
process.stdout.write('Server started on port 3000');
});
Сборка выполняется командой:
parcel build src/server.js --target node
Результатом становится один или несколько файлов, подготовленных для запуска в Node.js без дополнительных преобразований.
Parcel v2 использует декларативную модель через
package.json. Основная настройка серверного бандла задаётся
через targets.
{
"name": "my-server-app",
"source": "src/server.js",
"targets": {
"node": {
"context": "node",
"engines": {
"node": ">=18"
},
"outputFormat": "commonjs",
"distDir": "dist/server",
"includeNodeModules": true
}
}
}
Ключевые параметры:
context: “node” Определяет среду выполнения. Parcel отключает браузерные трансформации и полифиллы.
outputFormat
commonjs — классический формат Node.jsesmodule — ESM-вывод для современных окруженийincludeNodeModules Контролирует, будут ли
зависимости из node_modules включены в бандл или оставлены
внешними.
Серверная сборка почти всегда требует строгого контроля внешних библиотек.
Parcel поддерживает два подхода:
{
"targets": {
"node": {
"includeNodeModules": false
}
}
}
В этом случае результат сборки содержит
require('express'), и установка зависимостей обязательна в
runtime.
{
"targets": {
"node": {
"includeNodeModules": true
}
}
}
Parcel включает код зависимостей в бандл, уменьшая количество внешних файлов, но увеличивая размер результата.
Выбор зависит от сценария:
falsetrueNode.js предоставляет набор встроенных модулей, которые Parcel не должен пытаться бандлить:
import fs from 'fs';
import path from 'path';
Parcel автоматически:
node_modulesВажно учитывать, что попытка использовать браузерные API в серверном таргете не имеет смысла:
// некорректная логика для node-target
window.document.querySelector('div');
Такие конструкции должны быть изолированы или разделены по окружениям.
В реальных проектах серверный и клиентский код часто сосуществуют.
Типичная структура:
src/
server/
index.js
routes.js
client/
index.js
Parcel позволяет создать несколько таргетов:
{
"targets": {
"server": {
"context": "node",
"source": "src/server/index.js",
"distDir": "dist/server"
},
"client": {
"context": "browser",
"source": "src/client/index.js",
"distDir": "dist/client"
}
}
}
Это обеспечивает полную изоляцию окружений и предотвращает случайное смешивание API.
Серверные приложения активно используют process.env.
Parcel позволяет инлайнить значения переменных окружения на этапе сборки:
NODE_ENV=production parcel build src/server.js --target node
Или через конфигурацию:
{
"targets": {
"node": {
"define": {
"process.env.NODE_ENV": "\"production\""
}
}
}
}
Такой подход полезен для:
Parcel поддерживает динамические импорты и на сервере:
const loadModule = async () => {
const module = await import('./heavy-module.js');
return module.run();
};
В Node.js-сборке это может приводить к:
Однако чрезмерное дробление серверного кода может ухудшить производительность из-за увеличения количества файловых операций.
Для отладки серверного кода важны корректные stack trace.
Parcel генерирует sourcemaps:
{
"targets": {
"node": {
"sourceMaps": true
}
}
}
Это позволяет:
Parcel поддерживает TypeScript без дополнительной конфигурации.
Серверный пример:
import http from 'http';
const handler = (req: http.IncomingMessage, res: http.ServerResponse) => {
res.end('OK');
};
export default handler;
В серверной сборке важны следующие моменты:
tsconfig.json влияет на резолв модулейpaths учитываются при бандлингеВ монорепозиториях Parcel должен корректно обрабатывать локальные зависимости.
Пример структуры:
packages/
server/
shared/
database/
Серверный пакет:
import { connect } from '@app/database';
import { logger } from '@app/shared';
Parcel:
includeNodeModulesПри сборке серверного кода в production-режиме Parcel применяет ряд оптимизаций:
Команда:
parcel build src/server.js --target node --no-source-maps
В продакшене обычно отключаются:
Parcel поддерживает режим наблюдения:
parcel watch src/server.js --target node
Поведение:
Часто используется совместно с nodemon:
nodemon dist/server.js
Смешивание ESM и CommonJS Несовместимость
require и import может приводить к ошибкам
резолва.
Неправильный target Отсутствие
context: node может привести к включению браузерных
трансформаций.
Лишний бандлинг node_modules Увеличивает размер и замедляет сборку.
Использование browser API Код, зависящий от DOM, не должен попадать в серверный таргет.
Динамические пути в import Могут усложнить статический анализ:
import(`./handlers/${name}.js`);
Parcel хорошо сочетается с несколькими стилями организации серверного кода:
В каждом случае важно правильно разделять entry points и конфигурацию targets, чтобы избежать смешивания окружений и избыточного бандлинга.