Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Bug: client-mode build crashes (`ERR_MODULE_NOT_FOUND`) when adding nitro v3's vite plugin — prerender hook hardcodes `dist/server/server.js`

未关闭
#381 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
48/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
typescript, vite

调研方向

Reproduce the failure with the linked solid-2-nitro-repro at commit e31c0fa by running pnpm build, then inspect the client-mode solid:start/prerender hook and configurePreviewServer behavior described in dist/esm/index.mjs. Compare the Vite environment outputs with the hardcoded dist/server/server.js and dist/client/index.html paths. Done means the Nitro configuration builds without ERR_MODULE_NOT_FOUND and the integration has a clear ownership or path-handling behavior.

由索引模型根据 Issue 内容生成。

描述

Description

Adding nitro v3 (nitro/vite) next to a client-mode start: true setup breaks the production build. The plugin's solid:start/prerender buildApp hook imports the SSR handler from a hardcoded dist/server/server.js, but nitro's vite plugin reroutes both environment outputs before that, so the file never exists and the build dies with a bare ERR_MODULE_NOT_FOUND pointing into the plugin's own dist/esm/index.mjs.

The same config with ssr: true (SSR mode) builds fine — nitro runs its own [SSR] → [Nitro] stages and produces .output/server/index.mjs (node-server preset). The crash is specific to client mode (ssr: false), where the prerender hook unconditionally reads dist/server.

Note that ssr: false + serverFunctions: true is a documented, legitimate server-bearing setup — not user error: the README's client-mode section says no server bundle remains "unless serverFunctions is enabled, in which case dist/server is kept and its handleRequest serves the endpoint". With server functions enabled there is server code by design even when SSR is off, and the README lists Nitro among the hosts that consume that { fetch }/handleRequest shape. So "Solid builds the server bundle, nitro hosts it" is the intended integration; only the client-mode build-time glue breaks it.

Reproduction

Two-commit repro repo: https://github.com/lkwr/solid-2-nitro-repro

Commit Config pnpm build
9fb2261 — "init bare solid 2.0 template" solid({ start: true, diagnostics: true }) ✅ works
e31c0fa — "add nitro & enable server functions" solid({ start: true, diagnostics: true, ssr: false, serverFunctions: true }) + nitro() ❌ crashes
git clone https://github.com/lkwr/solid-2-nitro-repro
pnpm install
git checkout e31c0fa
pnpm build

The only changes in commit 2 are vite.config.ts and package.json:

 import { defineConfig } from 'vite';
 import solid from '@solidjs/vite-plugin';
+import { nitro } from 'nitro/vite';

   plugins: [
-    solid({ start: true, diagnostics: true }),
+    solid({ start: true, diagnostics: true, ssr: false, serverFunctions: true }),
+    nitro()
   ],
+    "nitro": "^3.0.260903-beta",

Observed

vite v8.3.1 building client environment for production...
✓ 43 modules transformed.
.output/public/.vite/manifest.json                 0.45 kB
.output/public/assets/logo-BKhbptE1.svg            1.59 kB
.output/public/assets/virtual_solid-ssr-entry-client-2z-wuqR5.js   39.63 kB

✓ built in 65ms
vite v8.3.1 building ssr environment for production...
✓ 8 modules transformed.
node_modules/.nitro/vite/services/ssr/server.js    6.62 kB

✓ built in 1.01s
error during build:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/Lukas/test/solid-nitro/dist/server/server.js' imported from /Users/Lukas/test/solid-nitro/node_modules/.pnpm/@[email protected][email protected]/node_modules/@solidjs/vite-plugin/dist/esm/index.mjs
    at finalizeResolution (node:internal/modules/esm/resolve:241:11)
    ...
  code: 'ERR_MODULE_NOT_FOUND',
  url: 'file:///Users/Lukas/test/solid-nitro/dist/server/server.js'

Notes from bisecting the repro:

  • Removing serverFunctions: true (keeping start: true, ssr: false + nitro()) still crashes identically — the prerender hook's import is unconditional in client mode.
  • Setting ssr: true makes the build succeed (nitro consumes the server side, .output/server/index.mjs). Only client mode crashes.

Root cause

In @solidjs/vite-plugin 3.0.0-next.46, dist/esm/index.mjs, the client-mode prerender hook (solid:start/prerender, order: 'post'):

const serverDir = path.resolve(root, "dist/server"); // hardcoded
const handler = await import(
  pathToFileURL(path.join(serverDir, "server.js")).href
);
const response = await handler.handleRequest(
  new Request(new URL(base || "/", "http://localhost")),
);
writeFileSync(
  path.resolve(root, "dist/client/index.html"),
  await response.text(),
); // hardcoded

nitro's vite plugin patches the environments first: the client build lands in .output/public/…, the ssr environment in node_modules/.nitro/vite/services/ssr/server.js, and nitro then builds its own .output/server/…. Nothing ever writes dist/server/server.js, so the prerender import fails.

Affected assumptions in that hook (and the same hardcode family elsewhere — e.g. configurePreviewServer also does import(path.resolve(root, 'dist/server/server.js'))):

  1. The SSR handler is at dist/server/server.js — but nitro (as a supported { fetch } consumer per the README) reroutes environment outputs.
  2. The prerendered shell is written to dist/client/index.html — nitro's layout is .output/public.
  3. In client mode start.external is documented as inert ("Server-only options are inert here … and so is start.external"), so there is currently no supported seam to point the prerender/preview steps at a relocated server bundle.

What's missing is the build-time seam: the plugin's dev middlewares stand down automatically when a host adopts the ssr environment, but the client-mode prerender (and preview dispatch) still read the hardcoded path.

Expected behavior

One (or more) of:

  • Derive the SSR handler location from the resolved environment (the outDir/entry the ssr environment was actually built to) rather than a hardcoded dist/server.
  • When another plugin has taken ownership of / rerouted the ssr environment (as nitro v3 does — the same ownership the plugin already detects in dev to stand its middlewares down), skip the plugin's own prerender/preview dispatch (nitro can prerender itself) instead of importing a path that no longer matches.
  • At minimum, surface a clear diagnostic ("SSR handler not found at <root>/dist/server/server.js — if another plugin owns the server build, configure X") instead of a bare ERR_MODULE_NOT_FOUND whose only importer reference points into @solidjs/vite-plugin/dist/esm/index.mjs.

Environment

@solidjs/vite-plugin 3.0.0-next.46
solid-js / @solidjs/web / @solidjs/diagnostics 2.0.0-rc.11
vite 8.3.1
nitro 3.0.260903-beta (nitro/vite)
node / pnpm v26.10.0 / 12.6.0
OS macOS
主要语言
TypeScript
星标
520
派生
70
平均合并
21 小时 42 分钟
30 天内合并 PR
36

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

solidjs/solid-vite-plugin 的其他 Issue

查看 solidjs/solid-vite-plugin 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。