Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions adapters/adapter-netlify/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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` +
Expand Down
16 changes: 16 additions & 0 deletions adapters/adapter-vercel/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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` +
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down
Loading