Bir Zod Paketini Hem CommonJS Hem ESM'e Derlemek
packages/schemas üç farklı runtime tarafından import ediliyor: NestJS (CommonJS ağırlıklı), Next.js (ESM), Vite (ESM). Aynı Zod şemasının üçünde de sorunsuz çalışması için paket tek bir formata değil, ikisine birden derleniyor.
İki ayrı tsconfig
// packages/schemas/tsconfig.cjs.json
{
"extends": "@myself/typescript-config/base.json",
"compilerOptions": { "module": "node16", "moduleResolution": "node16", "outDir": "dist/cjs", "declaration": true, "noEmit": false }
}
// packages/schemas/tsconfig.esm.json
{
"extends": "@myself/typescript-config/base.json",
"compilerOptions": { "module": "esnext", "moduleResolution": "bundler", "outDir": "dist/esm", "declaration": true, "noEmit": false }
}
Build script ikisini sırayla çalıştırıyor: tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json. Aynı src/ iki farklı outDir'a, iki farklı module hedefiyle derleniyor.
Tüketicinin hangi dosyayı alacağını exports belirliyor
{
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/cjs/index.d.ts",
"exports": {
".": { "types": "./dist/cjs/index.d.ts", "import": "./dist/esm/index.js", "require": "./dist/cjs/index.js" }
}
}
Node'un require()'ı require anahtarına, bir bundler'ın import'u import anahtarına gidiyor — Node.js kendi çözümleme algoritmasını, Next.js/Vite kendi bundler'larınınkini kullanıyor, hiçbiri yanlış formatı almıyor.
Neden tek format yetmiyor
Sadece CJS derlenirse Next.js/Vite'ın ESM tree-shaking'i düzgün çalışmaz; sadece ESM derlenirse NestJS'in require() tabanlı module yükleme zinciri kırılır. İki ayrı outDir'a derlemek, tek bir kaynak dosyadan (src/post.ts gibi) her iki dünyaya da doğru formatta çıktı üretmenin en basit yolu — bundler'a "ikisini de destekle" demek yerine, iki gerçek derleme çıktısı üretip seçimi exports haritasına bırakıyoruz.