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

Cloudflare deploy: framework prerender inside `void deploy`'s build deletes `.wrangler/deploy/config.json` (ENOENT)

已关闭 适合新手
#463 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@cpojer 已经在做这个了。

开始于 2026年10月20日。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
78/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
typescript

调研方向

从 dist/index.mjs 中的 restorePreviewPointer 开始,并将其 deploy-build guard 与 issue 中描述的 stash 侧检查进行比较。运行提供的双 build 复现步骤,然后验证:存在 stash 时,deploy 模式构建后 .wrangler/deploy/config.json 仍然存在,同时手动预览行为保持不变。

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

描述

Problem

In a TanStack Start app with voidPlugin() and TanStack's own build-time prerender (tanstackStart({ prerender: { enabled: true } })), void deploy fails after the build whenever an earlier plain vite build left a stashed pointer in .void/:

[prerender] Prerendered 4 pages:
...
◇ Preparing deployment...
■ ENOENT: no such file or directory, open '<root>/apps/web/.wrangler/deploy/config.json'

TanStack Start prerenders by starting a Vite preview server inside the build process. Void's plugin sees isPreview === true there and runs the preview restore path meant for a manual vite preview, including in the deploy build:

vite build              ── closeBundle: stash .wrangler/deploy/config.json → .void/preview-deploy-config.json
void deploy
  └ child build (VOID_CLOUDFLARE_DEPLOY_BUILD=1)
      ├ build writes a fresh .wrangler/deploy/config.json
      ├ prerender starts a Vite preview server
      │   └ config(): isPreview → restoreCloudflarePreviewPointer()
      │       ├ writes the stash from the earlier build over the pointer
      │       └ process.once("exit", rmSync(.wrangler/deploy/config.json))
      └ child exits → pointer deleted
  └ readGeneratedDeployConfig() → ENOENT

The stash side already skips deploy builds (closeBundle checks VOID_CLOUDFLARE_DEPLOY_BUILD !== "1"). The restore side has no such check (dist/index.mjs, restorePreviewPointer in voidPlugin).

This is the same pointer mechanism as #419, reached from the other direction. There a preview could not find the pointer. Here a preview inside a deploy build removes it.

Repro

A fresh clone reproduces it without void connect and without Cloudflare credentials. The deploy-mode build uses the env void deploy gives its build child.

git clone https://github.com/SweetRetry/void-starter && cd void-starter
git checkout 5230137
pnpm install
cd apps/web
pnpm exec vp build                                                  # plain build, stashes the pointer
VOID_CLOUDFLARE_DEPLOY_BUILD=1 NODE_ENV=production pnpm exec vp build   # what void deploy runs
ls .wrangler/deploy/config.json                                     # missing

Prerender is configured in apps/web/vite.config.ts. The repo's deploy script works around the bug by deleting .void/preview-deploy-config.json first, so call vp build directly as above.

Controls, each starting from an empty .wrangler/deploy and .void/preview-deploy-config.json:

Case Stash before deploy build Prerender Pointer after deploy build
A present on missing
B deleted on present
C present off present

An exit listener registered through NODE_OPTIONS=--require (so it runs before Void's) saw the pointer present in case A. The outer processes then saw it missing, so it is removed by the exit cleanup.

Suggested fix

Skip the restore in deploy builds, the same check the stash side already has:

 const restorePreviewPointer = () => {
   if (!existsSync(join(root, "void.config.ts"))) return;
+  if (process.env["VOID_CLOUDFLARE_DEPLOY_BUILD"] === "1") return;
   if (restoreCloudflarePreviewPointer(root) && !scheduledPreviewPointerCleanups.has(root)) {

With this patch applied to dist/index.mjs, case A keeps .wrangler/deploy/config.json ({"configPath":"../../dist/server/wrangler.json"}) after the deploy-mode build. A manual vite preview still finds the build output and gets as far as the remote binding session, which then fails only for lack of an API token in a non-interactive shell. That path runs without the env var, so its code is unchanged.

An alternative is for void deploy to remove .void/preview-deploy-config.json before it starts the build. That is the current workaround.

Question

The framework docs describe routing.prerender (deploy-time edge prerendering) for framework mode and don't mention a framework's own build-time prerender. Is TanStack Start's prerender option a supported setup with Void? We chose it so the blog pages ship as static assets in dist/client and a prerender failure fails the build.

Environment

  • void 1.1.11
  • @tanstack/react-start 1.169.2
  • @cloudflare/vite-plugin 1.64.0, wrangler 4.151.0
  • vite-plus 1.3.0
  • Node 24.14.1, pnpm 12.0.0, macOS
主要语言
TypeScript
星标
402
派生
32
平均合并
11 小时 52 分钟
30 天内合并 PR
88

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

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

voidzero-dev/void 的其他 Issue

查看 voidzero-dev/void 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

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