11import { getConfig } from '@expo/config' ;
22import { getPbxproj } from '@expo/config-plugins/build/ios/utils/Xcodeproj' ;
33import Server from '@expo/metro/metro/Server' ;
4- import type MetroServer from '@expo/metro/metro/Server' ;
54import fs from 'fs' ;
65import path from 'path' ;
76
@@ -13,26 +12,24 @@ export interface ModuleGenerationArguments {
1312 metro : Server | null ;
1413}
1514
16- function findUpTSConfig ( cwd : string ) : string | null {
17- const tsconfigPath = path . resolve ( cwd , './tsconfig.json' ) ;
18- if ( fs . existsSync ( tsconfigPath ) ) {
19- return path . dirname ( tsconfigPath ) ;
15+ function findUpPackageJsonDirectory (
16+ cwd : string ,
17+ directoryToPackage : Map < string , string >
18+ ) : string | undefined {
19+ if ( [ '.' , path . sep ] . includes ( cwd ) ) return undefined ;
20+ if ( directoryToPackage . has ( cwd ) ) return directoryToPackage . get ( cwd ) ;
21+
22+ const packageFound = fs . existsSync ( path . resolve ( cwd , './package.json' ) ) ;
23+ if ( packageFound ) {
24+ directoryToPackage . set ( cwd , cwd ) ;
25+ return cwd ;
2026 }
21-
22- const parent = path . dirname ( cwd ) ;
23- if ( parent === cwd ) return null ;
24-
25- return findUpTSConfig ( parent ) ;
26- }
27-
28- function findUpTSProjectRootOrThrow ( dir : string ) : string {
29- const tsProjectRoot = findUpTSConfig ( dir ) ;
30- if ( ! tsProjectRoot ) {
31- throw new Error ( 'Local modules watched dir needs to be inside a TS project with tsconfig.json' ) ;
27+ const packageRoot = findUpPackageJsonDirectory ( path . dirname ( cwd ) , directoryToPackage ) ;
28+ if ( packageRoot ) {
29+ directoryToPackage . set ( cwd , packageRoot ) ;
3230 }
33- return tsProjectRoot ;
31+ return packageRoot ;
3432}
35-
3633const nativeExtensions = [ '.kt' , '.swift' ] ;
3734
3835function isValidLocalModuleFileName ( fileName : string ) : boolean {
@@ -90,7 +87,8 @@ function trimExtension(fileName: string): string {
9087function typesAndLocalModulePathsForFile (
9188 projectRoot : string ,
9289 watchedDirRootAbolutePath : string ,
93- absoluteFilePath : string
90+ absoluteFilePath : string ,
91+ directoryToPackage : Map < string , string >
9492) : {
9593 moduleTypesFilePath : string ;
9694 viewTypesFilePath : string ;
@@ -102,8 +100,14 @@ function typesAndLocalModulePathsForFile(
102100 const fileName = path . basename ( absoluteFilePath ) ;
103101 const moduleName = trimExtension ( fileName ) ;
104102
105- const watchedDirTSProjectRoot = findUpTSProjectRootOrThrow ( watchedDirRootAbolutePath ) ;
106- const filePathRelativeToTSProjectRoot = path . relative ( watchedDirTSProjectRoot , absoluteFilePath ) ;
103+ const watchedDirProjectRoot = findUpPackageJsonDirectory (
104+ watchedDirRootAbolutePath ,
105+ directoryToPackage
106+ ) ;
107+ if ( ! watchedDirProjectRoot ) {
108+ throw Error ( 'Watched directory is not inside a project with package.json!' ) ;
109+ }
110+ const filePathRelativeToTSProjectRoot = path . relative ( watchedDirProjectRoot , absoluteFilePath ) ;
107111 const filePathRelativeToTSProjectRootWithoutExtension = trimExtension (
108112 filePathRelativeToTSProjectRoot
109113 ) ;
@@ -231,10 +235,16 @@ function onSourceFileCreated(
231235 projectRoot : string ,
232236 watchedDirRootAbolutePath : string ,
233237 absoluteFilePath : string ,
238+ directoryToPackage : Map < string , string > ,
234239 filesWatched ?: Set < string >
235240) : void {
236241 const { moduleTypesFilePath, viewTypesFilePath, viewExportPath, moduleExportPath, moduleName } =
237- typesAndLocalModulePathsForFile ( projectRoot , watchedDirRootAbolutePath , absoluteFilePath ) ;
242+ typesAndLocalModulePathsForFile (
243+ projectRoot ,
244+ watchedDirRootAbolutePath ,
245+ absoluteFilePath ,
246+ directoryToPackage
247+ ) ;
238248
239249 if ( filesWatched && fileWatchedWithAnyNativeExtension ( absoluteFilePath , filesWatched ) ) {
240250 filesWatched . add ( absoluteFilePath ) ;
@@ -270,7 +280,8 @@ export default _default`
270280
271281async function generateMirrorDirectories (
272282 projectRoot : string ,
273- filesWatched ?: Set < string >
283+ filesWatched ?: Set < string > ,
284+ directoryToPackage : Map < string , string > = new Map < string , string > ( )
274285) : Promise < void > {
275286 createFreshMirrorDirectories ( projectRoot ) ;
276287
@@ -296,6 +307,7 @@ async function generateMirrorDirectories(
296307 projectRoot ,
297308 watchedDirRootAbolutePath ,
298309 absoluteDirentPath ,
310+ directoryToPackage ,
299311 filesWatched
300312 ) ;
301313 } else if ( dirent . isDirectory ( ) ) {
@@ -336,6 +348,7 @@ export async function startModuleGenerationAsync({
336348} : ModuleGenerationArguments ) : Promise < void > {
337349 const dotExpoDir = ensureDotExpoProjectDirectoryInitialized ( projectRoot ) ;
338350 const filesWatched = new Set < string > ( ) ;
351+ const directoryToPackage : Map < string , string > = new Map < string , string > ( ) ;
339352
340353 const isFileExcluded = ( absolutePath : string ) => {
341354 for ( const glob of excludePathsGlobs ( projectRoot ) ) {
@@ -359,7 +372,12 @@ export async function startModuleGenerationAsync({
359372
360373 const onSourceFileRemoved = ( absoluteFilePath : string , watchedDirRootAbolutePath : string ) => {
361374 const { moduleTypesFilePath, moduleExportPath, viewExportPath, viewTypesFilePath } =
362- typesAndLocalModulePathsForFile ( projectRoot , watchedDirRootAbolutePath , absoluteFilePath ) ;
375+ typesAndLocalModulePathsForFile (
376+ projectRoot ,
377+ watchedDirRootAbolutePath ,
378+ absoluteFilePath ,
379+ directoryToPackage
380+ ) ;
363381
364382 filesWatched . delete ( absoluteFilePath ) ;
365383 if ( ! fileWatchedWithAnyNativeExtension ( absoluteFilePath , filesWatched ) ) {
@@ -395,7 +413,13 @@ export async function startModuleGenerationAsync({
395413 ) {
396414 const { filePath } = event ;
397415 if ( event . type === 'add' ) {
398- onSourceFileCreated ( projectRoot , watchedDirAncestor , filePath , filesWatched ) ;
416+ onSourceFileCreated (
417+ projectRoot ,
418+ watchedDirAncestor ,
419+ filePath ,
420+ directoryToPackage ,
421+ filesWatched
422+ ) ;
399423 } else if ( event . type === 'delete' ) {
400424 onSourceFileRemoved ( filePath , watchedDirAncestor ) ;
401425 }
@@ -405,5 +429,5 @@ export async function startModuleGenerationAsync({
405429
406430 watcher ?. addListener ( 'change' , listener ) ;
407431
408- await generateMirrorDirectories ( projectRoot , filesWatched ) ;
432+ await generateMirrorDirectories ( projectRoot , filesWatched , directoryToPackage ) ;
409433}
0 commit comments