번들 규칙
무엇이 담기고 무엇이 거절되는지, 호환 플래그와 wasm 은 어떻게 켜지는지.
runlot deploy 가 만드는 tar 하나가 배포의 전부입니다. 검사는 CLI·컨트롤 플레인·노드에서 각각 한 번씩 돌고, 노드는 "컨트롤 플레인이 이미 봤다" 는 이유로 건너뛰지 않습니다.
상한
| 축 | 상한 |
|---|---|
| 업로드(압축) | 64 MiB |
| 푼 뒤 누적 | 512 MiB |
| 항목 하나 | 64 MiB |
| 항목 수 | 20,000 |
| 경로 길이 | 255 바이트 |
runlot.json | 1 MiB |
넘으면 bundle_too_large 입니다. 대개는 assets 안에 node_modules 나 빌드 캐시가 들어간 경우입니다.
compatibilityDate
{ "compatibilityDate": "2025-01-15" }YYYY-MM-DD 여야 합니다. 없으면 2024-09-23 입니다. 런타임보다 미래인 날짜는 거절되므로, 기본값을 계속 앞당기지 않습니다.
compatibilityFlags
허용 목록입니다. 지금 켤 수 있는 것은 nodejs_compat 하나뿐입니다.
{ "compatibilityFlags": ["nodejs_compat"] }목록 밖의 플래그는 거절됩니다. unsafe_module 같은 것은 사용자 코드가 프로세스를 통째로 쥐게 만들기 때문에, 어떤 매니페스트도 켤 수 없어야 합니다.
대개는 직접 적을 필요가 없습니다. 번들에 node: 내장 모듈 import 가 하나라도 있으면 CLI 가 알아서 켭니다 — 그 플래그 없이는 로드 오류라 사용자가 고를 것이 없기 때문입니다. TypeORM·Sequelize·Knex 를 쓰면 이 길로 켜집니다.
기본으로 켜 두지 않는 이유는 nodejs_compat 이 전역(process, Buffer)과 모듈 해석을 바꾸기 때문입니다. 그것을 요구하지 않은 워커의 뜻을 배포가 바꿔서는 안 됩니다.
wasm 모듈
WASM 은 번들 안에서 new WebAssembly.Module(bytes) 로 컴파일할 수 없습니다 — 런타임이 그 길을 막습니다. 대신 매니페스트의 모듈로 들어갑니다.
{
"main": "worker/index.js",
"modules": [{ "name": "query_compiler.wasm", "type": "wasm", "path": "worker/query_compiler.wasm" }]
}이것도 CLI 가 자동으로 씁니다. Prisma 의 쿼리 컴파일러가 이 길로 들어갑니다.
type 은 wasm 만 받고, 모듈 이름은 worker 일 수 없으며(진입 모듈의 이름입니다) 중복될 수 없습니다.
거절되는 것
- 심볼릭 링크 — 번들 안의 심링크 하나로 노드의 아무 파일이나 서빙 대상이 됩니다
- 프로젝트 루트 밖을 가리키는 경로 —
"assets": "../../etc" - 절대 경로와
.. - 중복 tar 항목 — 컨트롤 플레인이 검사한 것과 노드가 쓰는 것이 달라지는 유일한 길입니다
- 경로 안의 NUL
- 아는 값이 아닌
framework— 지금 아는 값은next하나입니다