From 0389fa14e5faa3a046545e890d8efa2b048ee08b Mon Sep 17 00:00:00 2001 From: hassanalsa3aka Date: Wed, 16 Sep 2026 02:05:16 +0300 Subject: [PATCH] fix: include package.json in SSR function files to resolve ESM import issues --- apps/admin/netlify.toml | 15 ++++++++++++++- apps/dashboard/netlify.toml | 11 ++++++++++- apps/marketing/netlify.toml | 9 ++++++++- packages/cli/dist/index.js | 2 +- packages/scaffold/src/scaffoldAppFiles.ts | 12 +++++++++++- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/apps/admin/netlify.toml b/apps/admin/netlify.toml index dcbd4eb..57632f6 100644 --- a/apps/admin/netlify.toml +++ b/apps/admin/netlify.toml @@ -7,8 +7,21 @@ # See apps/dashboard/netlify.toml for why this exists — a real, confirmed # bug from an actual authenticated deploy (ROADMAP.md #4/#13). +# +# `.../ssr/package.json` added here for the same underlying reason: +# Netlify's function packager only zips up what it can statically trace +# from ssr.mjs's imports, PLUS whatever included_files explicitly lists — +# the plain `package.json` (`{"type":"module"}`) adapter-netlify writes +# into the function directory, to make Node treat dist/server/**/*.js as +# real ESM instead of defaulting to CommonJS, is neither imported nor +# previously listed here, so it never reached the deployed function at +# all despite existing in every local build — confirmed via a real deploy +# still throwing "Cannot use import statement outside a module" even +# after that fix landed. Same root cause as the rest of this list: a file +# read at runtime, not statically imported, is invisible to the tracer +# unless named here explicitly. [functions.ssr] - included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**"] + included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**", "netlify/functions/ssr/package.json"] [[redirects]] from = "/*" diff --git a/apps/dashboard/netlify.toml b/apps/dashboard/netlify.toml index 5f35f9d..270ff3f 100644 --- a/apps/dashboard/netlify.toml +++ b/apps/dashboard/netlify.toml @@ -11,8 +11,17 @@ # can trace from ssr.mjs's static imports; routes/ and dist/server/ are # read at runtime via fs.readdirSync/dynamic import(), invisible to that # tracer. See ROADMAP.md #4/#13's "real live deploy" account. +# +# `.../ssr/package.json` added for the identical reason, found the same +# way (a real live deploy, this time on apps/admin — still throwing +# "Cannot use import statement outside a module" even after adapter-netlify +# was fixed to write that file): the file exists in every local build, but +# was neither imported nor listed here, so the tracer never included it in +# the deployed function either. Anything read at runtime instead of +# statically imported has to be named in this list explicitly — no +# exceptions, package.json included. [functions.ssr] - included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**"] + included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**", "netlify/functions/ssr/package.json"] [[redirects]] from = "/*" diff --git a/apps/marketing/netlify.toml b/apps/marketing/netlify.toml index 3923442..da56d59 100644 --- a/apps/marketing/netlify.toml +++ b/apps/marketing/netlify.toml @@ -18,8 +18,15 @@ # can trace from ssr.mjs's static imports; routes/ and dist/server/ are # read at runtime via fs.readdirSync/dynamic import(), invisible to that # tracer. See ROADMAP.md #4/#13's "real live deploy" account. +# +# `.../ssr/package.json` added for the identical reason — see +# apps/dashboard/netlify.toml's copy of this comment for the full account +# (found via a real live deploy of apps/admin, not this app, since +# marketing's "ssg" render mode never invokes the function for its own +# homepage — but the same bug applies here the moment any route here uses +# ssr/isr/csr). [functions.ssr] - included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**"] + included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**", "netlify/functions/ssr/package.json"] [[redirects]] from = "/*" diff --git a/packages/cli/dist/index.js b/packages/cli/dist/index.js index 7e09964..a2fd554 100755 --- a/packages/cli/dist/index.js +++ b/packages/cli/dist/index.js @@ -5372,7 +5372,7 @@ hydrateCsrRoutes(); functions = "netlify/functions" [functions.ssr] - included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**"] + included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**", "netlify/functions/ssr/package.json"] [[redirects]] from = "/*" diff --git a/packages/scaffold/src/scaffoldAppFiles.ts b/packages/scaffold/src/scaffoldAppFiles.ts index c3631a5..e73fa1d 100644 --- a/packages/scaffold/src/scaffoldAppFiles.ts +++ b/packages/scaffold/src/scaffoldAppFiles.ts @@ -274,8 +274,18 @@ export async function scaffoldAppFiles(appDir: string, appName: string, opts: Sc // can't see it" case (the same class of problem Vercel's own tracer // had with react/react-dom, ROADMAP.md #4, just missing here for a // different reason). + // + // `.../ssr/package.json` in the list too — a second, later real bug: + // adapter-netlify writes a plain package.json (`{"type":"module"}`) + // straight into the function directory so Node treats the ESM + // dist/server/**/*.js output as real ESM instead of defaulting to + // CommonJS. That file is neither statically imported nor previously + // listed here either, so it hit the exact same "invisible to the + // tracer" problem as routes/api/dist above — confirmed via a real + // live deploy still throwing "Cannot use import statement outside a + // module" even after adapter-netlify was fixed to write it. `[functions.ssr]\n` + - ` included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**"]\n\n` + + ` included_files = ["netlify/functions/ssr/routes/**", "netlify/functions/ssr/api/**", "netlify/functions/ssr/dist/**", "netlify/functions/ssr/package.json"]\n\n` + `[[redirects]]\n` + ` from = "/*"\n` + ` to = "/.netlify/functions/ssr"\n` +