В serverless-экосистемах основная единица деплоя — функция, выполняемая в изолированной среде (AWS Lambda, Google Cloud Functions, Azure Functions). Ограничения на размер архива, время холодного старта, файловую систему и доступные runtime-библиотеки формируют специфические требования к процессу сборки. Parcel используется как инструмент, способный автоматизировать бандлинг кода и зависимостей в единый оптимизированный артефакт.
Parcel выполняет анализ графа зависимостей, объединяет модули, проводит трансформации (Babel, TypeScript, PostCSS), а затем формирует финальный бандл, пригодный для исполнения в Node.js-окружении Lambda.
Serverless-функции отличаются от традиционных серверных приложений рядом ограничений:
/var/task)Эти ограничения напрямую влияют на стратегию бандлинга: итоговый пакет должен быть компактным, предсказуемым и лишённым лишних runtime-зависимостей.
Parcel строит граф зависимостей начиная с entry-point файла функции, например:
// handler.js
export async function handler(event) {
return {
statusCode: 200,
body: JSON.stringify({ message: "OK" })
};
}
Parcel анализирует импортируемые модули, объединяет их и формирует единый bundle:
parcel build handler.js --target node --dist-dir dist
Ключевой аспект — выбор target, определяющий поведение
трансформаций и формат вывода.
Для serverless-кода используется Node.js target, который обеспечивает совместимость с Lambda runtime:
{
"targets": {
"lambda": {
"engines": {
"node": ">=18"
},
"context": "node",
"outputFormat": "commonjs",
"includeNodeModules": false
}
}
}
Параметр includeNodeModules: false означает исключение
node_modules из бандла. Это критично для:
Parcel поддерживает несколько подходов к работе с зависимостями:
Все зависимости включаются в итоговый файл.
Преимущества:
Недостатки:
Код приложения объединяется, а node_modules остаются
внешними:
{
"targets": {
"lambda": {
"includeNodeModules": false
}
}
}
Такой подход характерен для Lambda, где зависимости загружаются отдельно.
В некоторых сценариях часть пакетов помечается как внешняя:
{
"targets": {
"lambda": {
"externals": ["aws-sdk", "sharp"]
}
}
}
Это особенно важно для AWS SDK, который часто уже присутствует в runtime.
Parcel выполняет несколько стадий оптимизации:
В serverless-контексте tree-shaking приобретает критическое значение, так как даже небольшое сокращение влияет на cold start latency.
Parcel поддерживает TypeScript без дополнительной конфигурации:
export const handler = async (event: any) => {
return {
statusCode: 200,
body: JSON.stringify({ ok: true })
};
};
В процессе сборки происходит:
Type checking при этом может выполняться отдельно через
tsc --noEmit.
Dynamic imports позволяют разделять функциональность:
export const handler = async (event) => {
const module = await import("./heavy-module.js");
return module.process(event);
};
Parcel интерпретирует такие конструкции как точки разделения чанков. Однако в serverless-среде code splitting часто ограничен:
Поэтому dynamic import применяется точечно, в основном для тяжёлых вспомогательных модулей.
После сборки Parcel формируется структура:
dist/
handler.js
handler.js.map
Дальнейшая упаковка:
cd dist
zip -r function.zip .
Этот архив загружается в Lambda как deployment package.
В serverless-окружении часто используется AWS SDK, уже доступный в runtime. Его включение в бандл увеличивает размер без необходимости.
Конфигурация исключения:
{
"targets": {
"lambda": {
"externals": ["aws-sdk"]
}
}
}
Это позволяет использовать встроенную версию SDK.
Некоторые зависимости содержат native bindings (например,
bcrypt, sharp). Parcel не всегда может
корректно их встроить в единый bundle.
Типичная стратегия:
npm install --platform=linux --arch=x64Serverless-функции активно используют environment variables:
const region = process.env.AWS_REGION;
const table = process.env.TABLE_NAME;
Parcel не встраивает значения переменных автоматически, но позволяет
использовать .env при сборке:
parcel build handler.js --env production
Дополнительно применяется dotenv на уровне рантайма:
import "dotenv/config";
В монорепозиториях Parcel анализирует зависимости между пакетами:
/packages
/api
/shared
/core
Serverless-функция может импортировать внутренние пакеты:
import { validate } from "@shared/validator";
Parcel строит единый dependency graph, что позволяет избежать ручной сборки каждого пакета.
Cold start в Lambda зависит от:
Parcel влияет на все три параметра через:
Уменьшение количества файлов внутри bundle часто оказывает большее влияние, чем микрооптимизации кода.
Типичный pipeline:
npm ci
parcel build handler.js --dist-dir dist
cd dist && zip -r function.zip .
aws lambda update-function-code \
--function-name my-function \
--zip-file fileb://function.zip
Parcel поддерживает multi-entry сборку:
/functions
getUser.js
createUser.js
deleteUser.js
Конфигурация:
{
"targets": {
"lambda": {
"source": "functions/*.js",
"distDir": "dist"
}
}
}
Каждая функция получает отдельный bundle, что соответствует модели serverless-деплоя.
В serverless-сценариях Parcel часто конкурирует с другими bundler-инструментами, однако его модель отличается:
Эти свойства делают его применимым в задачах, где важна скорость итераций и предсказуемость результата.