From de854668ea27b1b23230bf17557fbffab6a576c9 Mon Sep 17 00:00:00 2001 From: David Akpan <51506996+praisedavid787@users.noreply.github.com> Date: Thu, 3 Sep 2026 17:01:07 +0100 Subject: [PATCH] fix: stop bundlers inlining JEST_WORKER_ID into isTest() Metro runs transforms in jest-worker processes, which set JEST_WORKER_ID. Bundlers such as babel-preset-expo inline static process.env.X member expressions at transform time, including inside node_modules, so the transform worker's id was baked into the app bundle as a literal. isTest() then returned true in ordinary debug and release builds and createMMKV() returned the in-memory mock: storage appeared to work in-session but was never written to disk, and every store was empty on next launch. Indexing a variable is not inlined, so the check now sees the real runtime environment. Jest and Vitest still set these variables at runtime in their workers, so test runs are unaffected. --- packages/react-native-mmkv/src/isTest.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/react-native-mmkv/src/isTest.ts b/packages/react-native-mmkv/src/isTest.ts index 93429611..f702c70b 100644 --- a/packages/react-native-mmkv/src/isTest.ts +++ b/packages/react-native-mmkv/src/isTest.ts @@ -3,7 +3,19 @@ export function isTest(): boolean { // In a WebBrowser/Electron the `process` variable does not exist return false } - return ( - process.env.JEST_WORKER_ID != null || process.env.VITEST_WORKER_ID != null - ) + // Read through a variable rather than as `process.env.JEST_WORKER_ID`. + // + // Metro parallelises transforms with jest-worker, which sets JEST_WORKER_ID + // in each worker process, and bundlers such as babel-preset-expo inline + // static `process.env.X` member expressions at transform time -- including + // inside node_modules. The transform worker's id therefore gets baked into + // the app bundle as a literal, isTest() returns true in a normal debug or + // release build, and createMMKV() silently returns the in-memory mock. + // Storage then appears to work in-session but is never written to disk. + // + // Only static member expressions are inlined, so indexing a variable sees + // the real runtime environment. Jest and Vitest still set these at runtime + // in their workers, so genuine test runs are unaffected. + const env: Record = global.process.env || {} + return Boolean(env['JEST_WORKER_ID'] || env['VITEST_WORKER_ID']) }