From 02e1f92d7d5bf4d510eeef1372f5fc898027ef8f Mon Sep 17 00:00:00 2001 From: Marnelram <89900105+marnelram@users.noreply.github.com> Date: Sun, 10 May 2026 19:08:38 -0700 Subject: [PATCH] fix(constants): inline LIB_VERSION via codegen to fix compiled output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 ` 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) --- packages/react-native-executorch/package.json | 3 ++- .../scripts/sync-version.cjs | 24 +++++++++++++++++++ .../src/constants/libVersion.ts | 3 +++ .../src/constants/resourceFetcher.ts | 2 +- 4 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 packages/react-native-executorch/scripts/sync-version.cjs create mode 100644 packages/react-native-executorch/src/constants/libVersion.ts diff --git a/packages/react-native-executorch/package.json b/packages/react-native-executorch/package.json index ac32b09d5f..ee1dd01197 100644 --- a/packages/react-native-executorch/package.json +++ b/packages/react-native-executorch/package.json @@ -37,7 +37,8 @@ "typecheck": "tsc --noEmit", "lint": "eslint \"**/*.{js,ts,tsx}\"", "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib", - "prepare": "bob build", + "prepare": "node scripts/sync-version.cjs && bob build", + "version": "node scripts/sync-version.cjs && git add src/constants/libVersion.ts", "prepack": "cp ../../README.md ./README.md", "postpack": "rm ./README.md" }, diff --git a/packages/react-native-executorch/scripts/sync-version.cjs b/packages/react-native-executorch/scripts/sync-version.cjs new file mode 100644 index 0000000000..a955c3da45 --- /dev/null +++ b/packages/react-native-executorch/scripts/sync-version.cjs @@ -0,0 +1,24 @@ +#!/usr/bin/env node +// Reads this package's package.json#version and writes it into +// src/constants/libVersion.ts as a literal export. We do this so the +// compiled output (lib/module/constants/libVersion.js) does not need +// a runtime require('../../package.json') — that path is correct from +// src/constants/ but wrong from lib/module/constants/ after bob's output +// nesting, and breaks any consumer that resolves through the "main"/ +// "module" fields instead of the "react-native" field (e.g. web/Node). + +const { readFileSync, writeFileSync } = require('node:fs'); +const { resolve } = require('node:path'); + +const pkgPath = resolve(__dirname, '..', 'package.json'); +const outPath = resolve(__dirname, '..', 'src', 'constants', 'libVersion.ts'); + +const { version } = JSON.parse(readFileSync(pkgPath, 'utf8')); + +const body = + '// AUTO-GENERATED by scripts/sync-version.cjs — do not edit by hand.\n' + + '// Source of truth: package.json#version.\n' + + `export const LIB_VERSION: string = '${version}';\n`; + +writeFileSync(outPath, body, 'utf8'); +console.log(`[sync-version] wrote ${outPath} (LIB_VERSION=${version})`); diff --git a/packages/react-native-executorch/src/constants/libVersion.ts b/packages/react-native-executorch/src/constants/libVersion.ts new file mode 100644 index 0000000000..d7ae51c1f9 --- /dev/null +++ b/packages/react-native-executorch/src/constants/libVersion.ts @@ -0,0 +1,3 @@ +// AUTO-GENERATED by scripts/sync-version.cjs — do not edit by hand. +// Source of truth: package.json#version. +export const LIB_VERSION: string = '0.9.0'; diff --git a/packages/react-native-executorch/src/constants/resourceFetcher.ts b/packages/react-native-executorch/src/constants/resourceFetcher.ts index ae6c5f1a3b..f825584473 100644 --- a/packages/react-native-executorch/src/constants/resourceFetcher.ts +++ b/packages/react-native-executorch/src/constants/resourceFetcher.ts @@ -1,4 +1,4 @@ export const DOWNLOAD_EVENT_ENDPOINT = 'https://ai.swmansion.com/telemetry/downloads/api/downloads'; -export const LIB_VERSION: string = require('../../package.json').version; +export { LIB_VERSION } from './libVersion';