1import path from 'path'; 2import resolveFrom from 'resolve-from'; 3 4/** 5 * Return true if the parent folder for a given file path is named "node_modules". 6 * 7 * @example 8 * isModuleRootPathInNodeModulesFolder('./foo/expo') -> false 9 * isModuleRootPathInNodeModulesFolder('./node_modules/expo') -> true 10 */ 11function isModuleRootPathInNodeModulesFolder(moduleRootPath: string): boolean { 12 const parentFolderName = path.basename(path.dirname(moduleRootPath)); 13 return parentFolderName === 'node_modules'; 14} 15 16/** 17 * Given a node module name, and a project path, this method will: 18 * 19 * 1. Resolve the module path. 20 * 2. Find the module root folder. 21 * 3. Return true if the module root folder is in a folder named `node_modules` 22 * 23 * @param projectRoot 24 * @param moduleId 25 * 26 * @example 27 * isModuleSymlinked('./expo/apps/native-component-list', { 28 * moduleId: 'react-native' 29 * }) 30 */ 31export function isModuleSymlinked( 32 projectRoot: string, 33 { 34 moduleId, 35 isSilent, 36 }: { 37 moduleId: string; 38 isSilent?: boolean; 39 } 40): boolean { 41 try { 42 const moduleRootPath = path.dirname(resolveFrom(projectRoot, `${moduleId}/package.json`)); 43 return !isModuleRootPathInNodeModulesFolder(moduleRootPath); 44 } catch (error) { 45 if (!isSilent) { 46 throw error; 47 } 48 // Failed to resolve the package.json relative to the project, not sure what to do here. 49 // This is probably not possible due to node module resolution. 50 return false; 51 } 52} 53