diff --git a/adapters/adapter-netlify/src/index.ts b/adapters/adapter-netlify/src/index.ts index 06cbde9..e9530cc 100644 --- a/adapters/adapter-netlify/src/index.ts +++ b/adapters/adapter-netlify/src/index.ts @@ -123,6 +123,26 @@ export async function writeNetlifyConfig( await cp(staticOutDir, path.join(appRoot, "dist", "client"), { recursive: true }); } + // Real bug found from an actual live Netlify deploy of a `renderMode: + // "ssr"` app (never surfaced by `marketing`, the only app verified live + // before now — it's `"ssg"`, so its homepage is served as a static file + // and never invokes the function at all): `bundleForDeploy` below writes + // `dist/server/routes/**/*.js` (and api/**) with `format: "esm"`, but + // nothing in `funcDir` ever declared `"type": "module"` in a package.json. + // `ssr.mjs` itself still loaded fine (Netlify invokes it directly, and a + // `.mjs` extension is always ESM to Node regardless of package.json) — + // the crash only happens the moment `prodRequestHandler.ts`'s + // `importBuilt()` dynamically `import()`s a plain `.js` route file at + // *request* time, which is exactly why this was invisible to a build + // that "succeeds" and a function that "deploys": `SyntaxError: Cannot use + // import statement outside a module` on the first real request to any + // ssr route. Node resolves a `.js` file's module type from the nearest + // package.json — with none present under `funcDir`, it defaults to + // CommonJS. This one file fixes every file under `funcDir`, not just + // `dist/server` — Node's lookup walks up from wherever the loaded file + // actually is. + await writeFile(path.join(funcDir, "package.json"), JSON.stringify({ type: "module" })); + await writeFile( path.join(funcDir, "ssr.mjs"), `import { createProdRequestHandler } from "@devorajs/core";\n` + diff --git a/adapters/adapter-vercel/src/index.ts b/adapters/adapter-vercel/src/index.ts index 0f7cea2..d32fd30 100644 --- a/adapters/adapter-vercel/src/index.ts +++ b/adapters/adapter-vercel/src/index.ts @@ -131,6 +131,22 @@ export async function writeVercelOutput( await cp(staticOutDir, path.join(funcDir, "dist", "static"), { recursive: true }); } + // Real bug — same root cause as adapter-netlify's identical fix (see that + // file's copy of this comment for the full account, found via a live + // Netlify deploy): `bundleForDeploy` writes `dist/server/**/*.js` with + // `format: "esm"`, but nothing in `funcDir` ever declared `"type": + // "module"`. `index.mjs` itself loads fine regardless (Vercel's + // `nodejs20.x` runtime invokes it directly, and `.mjs` is always ESM to + // Node), but `prodRequestHandler.ts`'s `importBuilt()` dynamically + // `import()`s a plain `.js` route file at request time — with no + // package.json to say otherwise, Node defaults that to CommonJS and + // throws `SyntaxError: Cannot use import statement outside a module` on + // the first real request to any `ssr`/`isr`/`csr` route. Never verified + // live on Vercel for those render modes, only `ssg` (never invokes the + // function for its homepage) — so this was equally live-broken here, + // just not yet hit. + await writeFile(path.join(funcDir, "package.json"), JSON.stringify({ type: "module" })); + await writeFile( path.join(funcDir, "index.mjs"), `import { createProdRequestHandler } from "@devorajs/core";\n\n` + diff --git a/packages/cli/dist/index.js b/packages/cli/dist/index.js index 00b8fcc..7e09964 100755 --- a/packages/cli/dist/index.js +++ b/packages/cli/dist/index.js @@ -4794,6 +4794,7 @@ async function writeVercelOutput(app, appRoot, authMode, security, sitemapEnable await cp2(staticOutDir, path16.join(outputDir, "static"), { recursive: true }); await cp2(staticOutDir, path16.join(funcDir, "dist", "static"), { recursive: true }); } + await writeFile3(path16.join(funcDir, "package.json"), JSON.stringify({ type: "module" })); await writeFile3( path16.join(funcDir, "index.mjs"), `import { createProdRequestHandler } from "@devorajs/core"; @@ -4943,6 +4944,7 @@ async function writeNetlifyConfig(app, appRoot, authMode, security, sitemapEnabl await cp3(staticOutDir, path19.join(funcDir, "dist", "static"), { recursive: true }); await cp3(staticOutDir, path19.join(appRoot, "dist", "client"), { recursive: true }); } + await writeFile4(path19.join(funcDir, "package.json"), JSON.stringify({ type: "module" })); await writeFile4( path19.join(funcDir, "ssr.mjs"), `import { createProdRequestHandler } from "@devorajs/core";