1import path from 'path'; 2import resolveFrom from 'resolve-from'; 3 4const debug = require('debug')('expo:start:server:metro:router') as typeof console.log; 5 6/** 7 * Get the relative path for requiring the `/app` folder relative to the `expo-router/entry` file. 8 * This mechanism does require the server to restart after the `expo-router` package is installed. 9 */ 10export function getAppRouterRelativeEntryPath(projectRoot: string): string | undefined { 11 // Auto pick App entry 12 const routerEntry = 13 resolveFrom.silent(projectRoot, 'expo-router/entry') ?? getFallbackEntryRoot(projectRoot); 14 if (!routerEntry) { 15 return undefined; 16 } 17 // It doesn't matter if the app folder exists. 18 const appFolder = path.join(projectRoot, 'app'); 19 const appRoot = path.relative(path.dirname(routerEntry), appFolder); 20 debug('routerEntry', routerEntry, appFolder, appRoot); 21 return appRoot; 22} 23 24/** If the `expo-router` package is not installed, then use the `expo` package to determine where the node modules are relative to the project. */ 25function getFallbackEntryRoot(projectRoot: string): string { 26 const expoRoot = resolveFrom.silent(projectRoot, 'expo/package.json'); 27 if (expoRoot) { 28 return path.join(path.dirname(path.dirname(expoRoot)), 'expo-router/entry'); 29 } 30 return path.join(projectRoot, 'node_modules/expo-router/entry'); 31} 32