Cloudflare deploy: framework prerender inside `void deploy`'s build deletes `.wrangler/deploy/config.json` (ENOENT)
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 78/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- typescript
- 領域
- build-system, cloud
調査の方向性
dist/index.mjs の restorePreviewPointer から始め、その deploy build のガードを issue に記載された stash 側のチェックと比較してください。提供された 2 ビルドの再現手順を実行し、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
- 平均マージ
- 13時間 14分
- マージ済み PR(30日)
- 73
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
voidzero-dev/void のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
voidzero-dev/void#459 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 1/5 1〜3時間 初心者へのやさしさ 78/100
voidzero-dev/void#428 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 53/100
voidzero-dev/void#472 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 52/100
voidzero-dev/void#471 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 55/100
voidzero-dev/void#470 ·
メンテナーはふだん 1 日以内に返信
voidzero-dev/void の issue をすべて見る
似ている issue
-
area:security documentation effort:S priority:P2
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
メンテナーはふだん 1 日以内に返信
-
app:web meta:ops
難易度 2/5 半日 初心者へのやさしさ 78/100
osu-tournament-rating/otr#1113 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
typegoose/mongodb-memory-server#1040 ·
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 92/100