[PR #1077] [MERGED] refactor(build): dedupe JSON file safe-read pattern #1074

Closed
opened 2026-05-06 13:11:51 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/1077
Author: @james-elicx
Created: 5/5/2026
Status: Merged
Merged: 5/5/2026
Merged by: @james-elicx

Base: mainHead: refactor/dedupe-json-file-read


📝 Commits (1)

  • 2047044 refactor(build): dedupe JSON file safe-read pattern

📊 Changes

3 files changed (+37 additions, -15 deletions)

View changed files

📝 packages/vinext/src/build/server-manifest.ts (+3 -7)
📝 packages/vinext/src/build/standalone.ts (+10 -8)
packages/vinext/src/utils/safe-json-file.ts (+24 -0)

📄 Description

Summary

Follow-up to #1058. Extracts the repeated try { JSON.parse(readFileSync(...)) } catch pattern from build pipeline files into a single shared helper.

New helper: packages/vinext/src/utils/safe-json-file.ts

readJsonFile<T>(path: string, options?: { onError?: (err: unknown) => void }): T | null

Returns null on any read/parse failure. Optional onError lets callers log/observe errors while still receiving null. Callers map null to whatever fallback they need (?? [], ?? undefined, etc.).

Files changed

  • packages/vinext/src/utils/safe-json-file.ts — new helper.
  • packages/vinext/src/build/server-manifest.tsreadPrerenderSecret now uses readJsonFile. Public signature unchanged (string | undefined).
  • packages/vinext/src/build/standalone.tsreadServerExternalsManifest now uses readJsonFile with the existing onError warning preserved. The existsSync gate is kept so an existing-but-malformed file still triggers the warning.

Subtle differences between the original sites

  • readPrerenderSecret swallowed errors silently and returned undefined — preserved by mapping the helper's null to undefined via optional chaining on the parsed object.
  • readServerExternalsManifest logged via console.warn and returned [] — preserved by passing an onError callback and using ?? [].
  • readPackageJson in standalone.ts is not the same pattern — it is a thin parse wrapper with no try/catch and no fallback (it propagates errors). Left untouched to preserve its throwing semantics; callers rely on it.

Test plan

  • pnpm vp test run tests/app-router.test.ts tests/pages-router.test.ts — 508 passed
  • pnpm fmt --write on touched files
  • pnpm knip — clean (no unused exports)

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/1077 **Author:** [@james-elicx](https://github.com/james-elicx) **Created:** 5/5/2026 **Status:** ✅ Merged **Merged:** 5/5/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `refactor/dedupe-json-file-read` --- ### 📝 Commits (1) - [`2047044`](https://github.com/cloudflare/vinext/commit/204704480956b127544fab5ddeb6afaf9aadaa6a) refactor(build): dedupe JSON file safe-read pattern ### 📊 Changes **3 files changed** (+37 additions, -15 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/build/server-manifest.ts` (+3 -7) 📝 `packages/vinext/src/build/standalone.ts` (+10 -8) ➕ `packages/vinext/src/utils/safe-json-file.ts` (+24 -0) </details> ### 📄 Description ## Summary Follow-up to #1058. Extracts the repeated `try { JSON.parse(readFileSync(...)) } catch` pattern from build pipeline files into a single shared helper. New helper: `packages/vinext/src/utils/safe-json-file.ts` ```ts readJsonFile<T>(path: string, options?: { onError?: (err: unknown) => void }): T | null ``` Returns `null` on any read/parse failure. Optional `onError` lets callers log/observe errors while still receiving `null`. Callers map `null` to whatever fallback they need (`?? []`, `?? undefined`, etc.). ## Files changed - `packages/vinext/src/utils/safe-json-file.ts` — new helper. - `packages/vinext/src/build/server-manifest.ts` — `readPrerenderSecret` now uses `readJsonFile`. Public signature unchanged (`string | undefined`). - `packages/vinext/src/build/standalone.ts` — `readServerExternalsManifest` now uses `readJsonFile` with the existing `onError` warning preserved. The `existsSync` gate is kept so an existing-but-malformed file still triggers the warning. ## Subtle differences between the original sites - `readPrerenderSecret` swallowed errors silently and returned `undefined` — preserved by mapping the helper's `null` to `undefined` via optional chaining on the parsed object. - `readServerExternalsManifest` logged via `console.warn` and returned `[]` — preserved by passing an `onError` callback and using `?? []`. - `readPackageJson` in `standalone.ts` is **not** the same pattern — it is a thin parse wrapper with no try/catch and no fallback (it propagates errors). Left untouched to preserve its throwing semantics; callers rely on it. ## Test plan - [x] `pnpm vp test run tests/app-router.test.ts tests/pages-router.test.ts` — 508 passed - [x] `pnpm fmt --write` on touched files - [x] `pnpm knip` — clean (no unused exports) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:11:51 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#1074
No description provided.