/** * Fixes npm workspace hoisting for React Native native modules. * * npm workspaces hoists all deps to the root node_modules by default. * Native modules like @react-native-firebase/* and @shopify/react-native-skia * break when hoisted because: * - Firebase podspecs use relative paths to sibling packages (../app/package.json) * - Skia native bindings must resolve from the app's node_modules * * This script moves hoisted native packages back into apps/mobile/node_modules * so CocoaPods autolinking and Metro resolve them correctly. */ const fs = require('fs'); const path = require('path'); const ROOT = path.resolve(__dirname, '..'); const MOBILE_NM = path.join(ROOT, 'apps', 'mobile', 'node_modules'); const WEB_NM = path.join(ROOT, 'apps', 'web', 'node_modules'); const ROOT_NM = path.join(ROOT, 'node_modules'); // Packages that must live in apps/mobile/node_modules, not root const PACKAGES_TO_FIX = [ '@react-native-firebase/app', '@react-native-firebase/analytics', '@react-native-firebase/crashlytics', '@shopify/react-native-skia', ]; for (const pkg of PACKAGES_TO_FIX) { const rootPkg = path.join(ROOT_NM, pkg); const localPkg = path.join(MOBILE_NM, pkg); if (!fs.existsSync(rootPkg)) continue; if (fs.existsSync(localPkg)) continue; // already local // Ensure parent scope dir exists (e.g. @react-native-firebase) const localParent = path.dirname(localPkg); fs.mkdirSync(localParent, { recursive: true }); // Move from root to local fs.renameSync(rootPkg, localPkg); console.log(`fix-hoisting: moved ${pkg} → apps/mobile/node_modules/`); } // Next and its React-facing tooling must resolve the web workspace's React 18 // runtime, not the React 19 runtime hoisted for Expo SDK 54 / React Native. for (const pkg of ['next', 'styled-jsx', 'eslint-config-next']) { const rootPkg = path.join(ROOT_NM, pkg); const localPkg = path.join(WEB_NM, pkg); if (!fs.existsSync(rootPkg) || fs.existsSync(localPkg)) continue; fs.mkdirSync(WEB_NM, { recursive: true }); fs.renameSync(rootPkg, localPkg); console.log(`fix-hoisting: moved ${pkg} → apps/web/node_modules/`); } const localNext = path.join(WEB_NM, 'next'); if (fs.existsSync(localNext)) { const localBinDir = path.join(WEB_NM, '.bin'); const localBin = path.join(localBinDir, 'next'); fs.mkdirSync(localBinDir, { recursive: true }); if (!fs.existsSync(localBin)) { fs.symlinkSync(path.join('..', 'next', 'dist', 'bin', 'next'), localBin); } }