Skip to content

fix(compiler): include compiler version in persistent cache fingerprint - #754

Closed
clayrisser wants to merge 1 commit into
onejs:mainfrom
clayrisser:fix/compiler-cache-version-fingerprint
Closed

fix(compiler): include compiler version in persistent cache fingerprint#754
clayrisser wants to merge 1 commit into
onejs:mainfrom
clayrisser:fix/compiler-cache-version-fingerprint

Conversation

@clayrisser

Copy link
Copy Markdown
Contributor

Symptom

After changing @vxrn/compiler's transform behavior (upgrading it, or in our case editing a carried pnpm patch on it), dev builds kept serving the old transform output. The persistent transform cache in node_modules/.vxrn/compiler-cache lives in the app's node_modules and survives package upgrades, so stale entries keep winning until someone manually deletes the cache dir — a very confusing failure mode, because the symptom looks like "my compiler change did nothing."

Root cause

getCachedTransform() validates entries against input file mtime + content hash, plus getConfigFingerprint() — which hashes only the four config toggles (enableCompiler, enableReanimated, enableNativewind, enableNativeCSS):

  • inputs unchanged ✓
  • config unchanged ✓
  • compiler implementation changed ✗ (not part of the key)

Nothing in the cache key captures the compiler implementation itself, so any release that changes transform output (or any patch applied to the package) silently reuses transforms produced by the previous implementation.

Fix

Fold the compiler's own package version into getConfigFingerprint(). Version discovery mirrors the existing getPackageVersion() pattern in packages/one/src/cli.ts (CJS/ESM dual __dirname/import.meta.url handling); it walks .. and ../.. so it resolves the right package.json both from compiled dist/{esm,cjs} output and straight from src (tests), verifies name === '@vxrn/compiler', and falls back to a static marker if the read fails.

Verification

Smoke-tested against the public cache API (setCachedTransform/getCachedTransform) with a fixed input file and default config, comparing main vs this branch:

  • main writes cache key c9fc91f1… (no version in the fingerprint)
  • this branch writes 91a459dd…, which exactly matches an independently recomputed sha1 of the fingerprint JSON with version: "1.24.1" — proving the version resolves for real (not the fallback) and lands in the key
  • re-running on this branch produces no new key and hits the cache (key is stable across processes)

tsc --noEmit, oxlint, and oxfmt --check are clean on the package. (vitest run --dir src currently fails on unmodified main in my environment with a vite resolution error from transformBabel.test.ts, unrelated to this change.)

Downstream

We hit this in production in the multiplatform.one framework, where we carry pnpm patches on @vxrn/compiler (Hermes dev-lowering fixes we're upstreaming separately): after every patch edit the compiler cache kept serving pre-patch transforms. We currently carry a manual PATCH_VERSION marker in the fingerprint as a pnpm patch; a version-based marker upstream retires it and fixes the general upgrade case for everyone.

Made with Cursor

The transform cache in node_modules/.vxrn/compiler-cache validates entries
against input file mtime/content and a fingerprint of the config toggles
only. Transform output also depends on the compiler implementation itself,
so entries written by an older @vxrn/compiler survive an upgrade (inputs
and config unchanged) and keep serving stale transforms.

Fold the compiler's own package version into getConfigFingerprint() so the
cache invalidates whenever the compiler changes. Version discovery mirrors
getPackageVersion() in packages/one/src/cli.ts (CJS/ESM dual dirname, works
from dist/{esm,cjs} and from src for tests), with a static fallback marker
if package.json cannot be found.

Co-authored-by: Cursor <cursoragent@cursor.com>
@clayrisser clayrisser closed this Aug 14, 2026
@clayrisser
clayrisser deleted the fix/compiler-cache-version-fingerprint branch August 14, 2026 20:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant