@@ -331,6 +331,75 @@ function getHermesOSBin() {
331331 if ( os . platform ( ) === 'linux' ) return 'linux64-bin' ;
332332}
333333
334+ function getHermesExecutableName ( ) {
335+ return os . platform ( ) === 'win32' ? 'hermesc.exe' : 'hermesc' ;
336+ }
337+
338+ function dirnameOfPackage (
339+ packageJsonPath : string ,
340+ projectRoot = process . cwd ( ) ,
341+ ) {
342+ return path . dirname (
343+ require . resolve ( packageJsonPath , {
344+ paths : [ projectRoot ] ,
345+ } ) ,
346+ ) ;
347+ }
348+
349+ export function resolveHermesCommand ( projectRoot = process . cwd ( ) ) : string {
350+ const osBin = getHermesOSBin ( ) ;
351+ if ( ! osBin ) {
352+ throw new Error ( `Unsupported platform for Hermes: ${ os . platform ( ) } ` ) ;
353+ }
354+
355+ const executableName = getHermesExecutableName ( ) ;
356+ const candidates : string [ ] = [ ] ;
357+
358+ try {
359+ const rnDir = dirnameOfPackage ( 'react-native/package.json' , projectRoot ) ;
360+ candidates . push ( path . join ( rnDir , 'sdks' , 'hermesc' , osBin , executableName ) ) ;
361+ } catch {
362+ // react-native is required for normal RN projects; keep looking so the
363+ // final error can include all candidates we were able to infer.
364+ }
365+
366+ try {
367+ const hermesCompilerDir = dirnameOfPackage (
368+ 'hermes-compiler/package.json' ,
369+ projectRoot ,
370+ ) ;
371+ candidates . push (
372+ path . join ( hermesCompilerDir , 'hermesc' , osBin , executableName ) ,
373+ ) ;
374+ } catch {
375+ // RN 0.85+ uses hermes-compiler, older projects may still use other paths.
376+ }
377+
378+ try {
379+ const hermesEngineDir = dirnameOfPackage (
380+ 'hermes-engine/package.json' ,
381+ projectRoot ,
382+ ) ;
383+ candidates . push (
384+ path . join ( hermesEngineDir , osBin , executableName ) ,
385+ path . join ( hermesEngineDir , 'hermesc' , osBin , executableName ) ,
386+ ) ;
387+ } catch {
388+ // RN 0.70-era projects commonly used hermes-engine; optional for newer RN.
389+ }
390+
391+ const hermesCommand = candidates . find ( ( candidate ) =>
392+ fs . existsSync ( candidate ) ,
393+ ) ;
394+ if ( hermesCommand ) {
395+ return hermesCommand ;
396+ }
397+
398+ throw new Error (
399+ `Cannot find hermesc. Tried:\n${ candidates . map ( ( candidate ) => `- ${ candidate } ` ) . join ( '\n' ) } ` ,
400+ ) ;
401+ }
402+
334403async function checkGradleConfig ( ) : Promise < GradleConfig > {
335404 let enableHermes = false ;
336405 let crunchPngs : boolean | undefined ;
@@ -365,18 +434,7 @@ async function compileHermesByteCode(
365434 shouldCleanSourcemap : boolean ,
366435) {
367436 console . log ( t ( 'hermesEnabledCompiling' ) ) ;
368- const rnDir = path . dirname (
369- require . resolve ( 'react-native' , {
370- paths : [ process . cwd ( ) ] ,
371- } ) ,
372- ) ;
373- let hermesPath = path . join ( rnDir , `/sdks/hermesc/${ getHermesOSBin ( ) } ` ) ;
374-
375- if ( ! fs . existsSync ( hermesPath ) ) {
376- hermesPath = `node_modules/hermes-engine/${ getHermesOSBin ( ) } ` ;
377- }
378-
379- const hermesCommand = `${ hermesPath } /hermesc` ;
437+ const hermesCommand = resolveHermesCommand ( ) ;
380438
381439 const args = [
382440 '-emit-binary' ,
0 commit comments