Vite buildが成功表示後に落ちる時はdistの鮮度で判定する
Windowsでは、ViteやNode.jsのbuildが成果物を書き出したあとに落ちることがあります。
ログには built in ... と出るのに、プロセスの終了コードは非ゼロ。TauriのpackagingやCIでは、この状態をどう扱うかが問題になります。
ここで一番危ないのは、dist/ が存在するだけで成功扱いすることです。前回の古い dist/ が残っていれば、今回のbuildが失敗していても成功に見えてしまいます。
症状
よくある見え方は次のようなものです。
vite build
✓ built in 4.2s
process exited with code -1073741819
Windowsでは 0xC0000005 のようなaccess violationとして見えることもあります。
このとき、本当にbuildが失敗したのか、成果物を書いたあとにteardownで落ちただけなのかを分ける必要があります。
distがあるだけでは不十分
次の確認は危険です。
vite build
test -f dist/index.html
dist/index.html が前回buildの残骸でも通ってしまうからです。
必要なのは、今回のbuildで新しく生成されたことの確認です。
- build前に
dist/を消す - 今回
index.htmlが作られたことを確認する index.htmlが参照するassetが存在する- WASMなど必須assetが空ファイルではない
PowerShell wrapperで判定する
Windowsでは、PowerShellを親プロセスにしてbuildを実行すると扱いやすいです。Nodeの子プロセスが落ちても、PowerShell側で結果を判定できます。
$ErrorActionPreference = "Stop"
$Dist = Join-Path (Get-Location) "dist"
if (Test-Path $Dist) {
Remove-Item $Dist -Recurse -Force
}
npm run typecheck
npm run vite-build
$index = Join-Path $Dist "index.html"
if (-not (Test-Path $index)) {
throw "dist/index.html was not created"
}
$age = (Get-Date) - (Get-Item $index).LastWriteTime
if ($age.TotalSeconds -gt 10) {
throw "dist/index.html is stale"
}
本番用には、Viteの終了コードも取り、非ゼロでも成果物が新鮮で完全なら「emit後クラッシュ」として扱う、という分岐にします。
判定ルール
考え方は次の通りです。
exit 0 + fresh output -> 成功
exit non-zero + fresh output -> emit後クラッシュとして扱える
exit non-zero + stale output -> 失敗、retryまたは停止
非ゼロを全部無視するのは危険です。TypeScriptエラー、importミス、asset欠落は失敗として止めるべきです。
使いどころ
この手順は、次の条件で役に立ちます。
- buildログでは成功に見える
- 終了コードだけ非ゼロ
- Windowsでたまに落ちる
- Tauriなどのpackaging前にfrontend成果物が必要
- 古い
dist/を成功扱いしたくない
特にデスクトップアプリのrelease buildでは、frontend buildの失敗を見逃すと、起動しても画面がないexeを作ることがあります。
まとめ
Vite buildが成功表示後に落ちる時、dist/ の存在だけで判断しないでください。
build前に dist/ を消し、今回生成された成果物かどうかを確認します。これで、本当の失敗とemit後クラッシュを分けられます。