stack/apps/backend/scripts/patch-required-server-files.mjs
Devin AI e971fd8fcd fix: patch required-server-files manifest to include CJS boundary marker
Workaround for vercel/next.js#91661 — Next.js 16.2 omits .next/package.json
from the required-server-files manifest, so Vercel's serverless functions
don't get the CJS boundary marker. Without it, Node.js resolves the project's
"type": "module" and treats the compiled server bundles as ESM, breaking
require() calls at runtime.

This adds a postbuild script that patches the manifest to include the file,
matching the upstream fix in vercel/next.js#93612 (only in canary as of 16.2.6).

The previous approach of removing "type": "module" broke the codegen step
which uses tsx/esbuild and needs ESM for top-level await support.

Co-Authored-By: Konstantin Wohlwend <n2d4xc@gmail.com>
2026-05-20 19:07:19 +00:00

37 lines
1.3 KiB
JavaScript

/**
* Workaround for https://github.com/vercel/next.js/issues/91661
*
* Next.js 16.2 doesn't include `.next/package.json` (the CJS boundary marker)
* in the `required-server-files.json` manifest. Without it, Vercel's serverless
* functions inherit `"type": "module"` from the project's package.json, causing
* `require is not defined` at runtime.
*
* The upstream fix landed in vercel/next.js#93612 (canary only as of 16.2.6).
* This script patches the manifest after `next build` to include the file.
*
* Remove this script once we upgrade to a stable Next.js release containing the fix.
*/
import { readFileSync, writeFileSync, existsSync } from 'fs';
import { join } from 'path';
const distDir = '.next';
const manifestPath = join(distDir, 'required-server-files.json');
if (!existsSync(manifestPath)) {
// Not all build modes produce this manifest (e.g. compile-only docker builds)
process.exit(0);
}
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
const packageJsonEntry = join(distDir, 'package.json');
if (!manifest.files.includes(packageJsonEntry)) {
manifest.files.push(packageJsonEntry);
writeFileSync(manifestPath, JSON.stringify(manifest));
console.log(`Patched ${manifestPath}: added ${packageJsonEntry} to files array`);
} else {
console.log(`${manifestPath} already includes ${packageJsonEntry}, no patch needed`);
}