Skip to content

fix(constants): inline LIB_VERSION via codegen to fix compiled output#1139

Open
marnelram wants to merge 1 commit intosoftware-mansion:mainfrom
marnelram:fix/lib-version-codegen
Open

fix(constants): inline LIB_VERSION via codegen to fix compiled output#1139
marnelram wants to merge 1 commit intosoftware-mansion:mainfrom
marnelram:fix/lib-version-codegen

Conversation

@marnelram
Copy link
Copy Markdown

Fixes #1138.

Problem

src/constants/resourceFetcher.ts reads the version with require('../../package.json').version. From src/constants/, that path resolves to the package root — correct. But react-native-builder-bob's module target emits the file at lib/module/constants/, one level deeper, and the babel transform leaves the relative require literal unchanged. From the compiled location, ../../package.json is lib/package.json — a file that doesn't exist. Any bundler that resolves through "main" / "module" (web bundlers, Node) blows up.

iOS/Android Metro is unaffected because the package's "react-native": "src/index" field sends Metro to the source directly.

Fix

Generate the version into a committed source file instead of requiring package.json at runtime.

  • New scripts/sync-version.cjs: reads package.json#version, writes src/constants/libVersion.ts.
  • New src/constants/libVersion.ts: holds export const LIB_VERSION: string = '<version>'. Header marks it auto-generated.
  • src/constants/resourceFetcher.ts: re-exports LIB_VERSION from ./libVersion.
  • package.json:
    • scripts.prepare: node scripts/sync-version.cjs && bob build — regenerate before every build.
    • scripts.version: node scripts/sync-version.cjs && git add src/constants/libVersion.ts — keeps the committed file in sync with npm version <bump>.

Why this shape

  • No runtime JSON require, so no relative-path fragility across output layouts.
  • Single source of truth stays package.json#version; the committed libVersion.ts is regenerated before publish and before any version bump.
  • RN consumers reading src/ directly (via the react-native entry) get the committed file — still correct, since it's refreshed at version-bump time.
  • No new dependencies.

Verification

yarn workspace react-native-executorch run prepare
# → [sync-version] wrote .../src/constants/libVersion.ts (LIB_VERSION=0.9.0)
# → ✔ [module] Wrote files to lib/module
# → ✔ [typescript] Wrote definition files to lib/typescript

After build, lib/module/constants/resourceFetcher.js:

"use strict";
export const DOWNLOAD_EVENT_ENDPOINT = 'https://ai.swmansion.com/telemetry/downloads/api/downloads';
export { LIB_VERSION } from './libVersion';

And the new lib/module/constants/libVersion.js:

"use strict";
// AUTO-GENERATED by scripts/sync-version.cjs — do not edit by hand.
// Source of truth: package.json#version.
export const LIB_VERSION = '0.9.0';

yarn workspace react-native-executorch run typecheck, prettier --check, and eslint on the touched files all pass.

Source `src/constants/resourceFetcher.ts` reads the version with
`require('../../package.json')`. That path is correct from
`src/constants/` (two-up = package root), but `react-native-builder-bob`'s
`module` target emits the file at `lib/module/constants/` — one level
deeper — and the babel transform leaves the relative `require` literal
unchanged. From the compiled location, `../../package.json` resolves to
`lib/package.json`, which does not exist. Any bundler that resolves
through `"main"` / `"module"` (web bundlers, Node) crashes with
`Unable to resolve module ../../package.json from
node_modules/react-native-executorch/lib/module/constants/resourceFetcher.js`.
Only Metro for iOS/Android survives, because it honors the
`"react-native": "src/index"` field and reads the source file directly.

Fix by generating the version into a committed source file before
build, so the compiled output never needs a runtime JSON require:

- New `scripts/sync-version.cjs` reads `package.json#version` and writes
  `src/constants/libVersion.ts`.
- `src/constants/resourceFetcher.ts` re-exports `LIB_VERSION` from the
  generated file.
- `scripts.prepare` runs `sync-version.cjs` before `bob build`.
- `scripts.version` runs it on `npm version <bump>` so the committed
  `libVersion.ts` stays in sync with `package.json#version`.

Verified by running `yarn workspace react-native-executorch run prepare`
and confirming `lib/module/constants/resourceFetcher.js` now has
`export { LIB_VERSION } from './libVersion'` and the new
`lib/module/constants/libVersion.js` ships the inlined constant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@chmjkb chmjkb added the bug fix PRs that are fixing bugs label May 11, 2026
@chmjkb chmjkb requested a review from mkopcins May 11, 2026 08:04
@chmjkb
Copy link
Copy Markdown
Collaborator

chmjkb commented May 11, 2026

cc @mkopcins, i believe we can also use that new constant for the model urls to avoid duplicating

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug fix PRs that are fixing bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LIB_VERSION resolves to non-existent lib/package.json after bob build, breaks web/Node consumers

2 participants