Hermes Integrado
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Esta página ofrece una visión general de cómo se construyen Hermes y React Native.
Si buscas instrucciones sobre cómo usar Hermes en tu aplicación, puedes encontrarlas en esta otra página: usando Hermes
Ten en cuenta que esta página sirve como una inmersión técnica y está dirigida a usuarios que están construyendo extensiones sobre Hermes o React Native. Los usuarios generales de React Native no necesitan conocer información detallada sobre cómo interactúan React Native y Hermes.
Qué es 'Hermes Integrado'
A partir de React Native 0.69.0, cada versión de React Native se construirá junto a una versión de Hermes. Llamamos a este modelo de distribución Hermes Integrado.
Desde la versión 0.69, siempre tendrás un motor JavaScript que ha sido construido y probado junto a cada versión de React Native disponible.
Por qué adoptamos 'Hermes Integrado'
Históricamente, React Native y Hermes seguían dos procesos de lanzamiento distintos con versionamiento diferente. Estos lanzamientos independientes generaban confusión en el ecosistema de código abierto, donde no estaba claro si una versión específica de Hermes era compatible con una versión específica de React Native (ej. necesitabas saber que Hermes 0.11.0 solo era compatible con React Native 0.68.0, etc.)
Tanto Hermes como React Native comparten el código JSI (Hermes aquí y React Native aquí). Si las dos copias de JSI se desincronizan, una compilación de Hermes no será compatible con React Native. Puedes leer más sobre este problema de incompatibilidad ABI aquí.
Para resolver este problema, extendimos el proceso de lanzamiento de React Native para descargar y construir Hermes, asegurando que solo se use una copia de JSI durante su construcción.
Gracias a esto, podemos lanzar una versión de Hermes con cada versión de React Native, garantizando que el motor Hermes sea totalmente compatible con la versión correspondiente. Distribuimos esta versión de Hermes junto con React Native, de ahí el nombre Hermes Integrado.
Cómo afectará esto a los desarrolladores de aplicaciones
Como se mencionó en la introducción, si eres desarrollador de aplicaciones, este cambio no debería afectarte directamente.
Los siguientes párrafos describen los cambios implementados internamente y explican su justificación, en aras de la transparencia.
Usuarios de iOS
En iOS, hemos cambiado la procedencia del hermes-engine que utilizas.
Antes de React Native 0.69, los usuarios descargaban un pod (puedes encontrar el podspec aquí).
En React Native 0.69, los usuarios utilizan un podspec definido dentro del archivo sdks/hermes-engine/hermes-engine.podspec en el paquete NPM de react-native.
Este podspec depende de un tarball precompilado de Hermes que subimos a Maven y a las versiones de GitHub de React Native, como parte del proceso de lanzamiento (ej. ver los recursos de este lanzamiento).
Usuarios de Android
En Android, actualizaremos el archivo android/app/build.gradle en la plantilla predeterminada de la siguiente manera:
dependencies {
// ...
if (enableHermes) {
+ implementation("com.facebook.react:hermes-engine:+") {
+ exclude group:'com.facebook.fbjni'
+ }
- def hermesPath = "../../node_modules/hermes-engine/android/";
- debugImplementation files(hermesPath + "hermes-debug.aar")
- releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
}
Antes de React Native 0.69, los usuarios consumirán hermes-debug.aar y hermes-release.aar del paquete NPM hermes-engine.
En React Native 0.69, los usuarios consumirán los artefactos multivariante de Android disponibles en la carpeta android/com/facebook/react/hermes-engine/ del paquete NPM react-native.
Ten en cuenta también que vamos a eliminar la dependencia de hermes-engine por completo en una futura versión de React Native.
Usuarios de Android en la Nueva Arquitectura
Debido a la naturaleza de nuestra configuración de compilación de código nativo (es decir, cómo usamos el NDK), los usuarios en la Nueva Arquitectura compilarán Hermes desde el código fuente.
Esto alinea el mecanismo de compilación de React Native y Hermes para usuarios en la Nueva Arquitectura (compilarán ambos frameworks desde el código fuente).
Esto significa que dichos usuarios de Android podrían experimentar una reducción de rendimiento en el tiempo de compilación durante su primera compilación.
Puedes encontrar instrucciones para optimizar tu tiempo de compilación y reducir el impacto en esta página: Acelerando tu fase de compilación.
Usuarios de Android en Nueva Arquitectura compilando en Windows
Los usuarios que compilen aplicaciones React Native con Nueva Arquitectura en máquinas Windows deben seguir estos pasos adicionales para que la compilación funcione correctamente:
-
Asegúrate de que el entorno esté configurado correctamente, con Android SDK y node.
-
Instala cmake con Chocolatey
-
Instala cualquiera de estas opciones:
- Build Tools para Visual Studio 2022.
- Visual Studio 22 Community Edition - Seleccionar solo desarrollo para escritorio con C++ es suficiente.
-
Asegúrate de que el Símbolo del sistema de Visual Studio esté configurado correctamente. Esto es necesario porque las variables de entorno del compilador C++ se configuran en ese símbolo del sistema.
-
Ejecuta la aplicación con
npx react-native run-androiddentro de un Símbolo del sistema de Visual Studio.
¿Pueden los usuarios seguir usando otro motor?
Sí, los usuarios pueden habilitar/deshabilitar Hermes libremente (con la variable enableHermes en Android, hermes_enabled en iOS).
El cambio de 'Bundled Hermes' solo afectará cómo se construye y empaqueta Hermes para ti.
A partir de React Native 0.70, el valor predeterminado de enableHermes/hermes_enabled es true.
Cómo afectará esto a colaboradores y desarrolladores de extensiones
Si eres colaborador de React Native o desarrollas extensiones sobre React Native o Hermes, por favor continúa leyendo mientras explicamos cómo funciona Bundled Hermes.
¿Cómo funciona Bundled Hermes internamente?
Este mecanismo se basa en descargar un tarball con el código fuente de Hermes desde el repositorio facebook/hermes dentro del repositorio facebook/react-native. Tenemos un mecanismo similar para otras dependencias nativas (Folly, Glog, etc.) y alineamos a Hermes para que siga la misma configuración.
Al compilar React Native desde main, obtendremos un tarball de main de facebook/hermes y lo compilaremos como parte del proceso de compilación de React Native.
Al construir React Native desde una rama de lanzamiento (como 0.69-stable), utilizaremos una etiqueta en el repositorio de Hermes para sincronizar el código entre ambos repositorios. El nombre específico de esta etiqueta se almacenará en el archivo sdks/.hermesversion dentro de React Native en la rama de lanzamiento (por ejemplo, este archivo en la rama de lanzamiento 0.69).
En cierto sentido, puedes considerar este enfoque similar a un submódulo de git.
Si estás desarrollando sobre Hermes, puedes confiar en estas etiquetas para saber qué versión de Hermes se usó al construir React Native, ya que la versión de React Native está especificada en el nombre de la etiqueta (ej. hermes-2022-05-20-RNv0.69.0-ee8941b8874132b8f83e4486b63ed5c19fc3f111).
Detalles de implementación en Android
Para implementar esto en Android, agregamos una nueva compilación en /ReactAndroid/hermes-engine de React Native que se encargará de construir Hermes y empaquetarlo para su consumo (Ver más contexto aquí).
Ahora puedes activar una compilación del motor Hermes invocando:
// Build a debug version of Hermes
./gradlew :ReactAndroid:hermes-engine:assembleDebug
// Build a release version of Hermes
./gradlew :ReactAndroid:hermes-engine:assembleRelease
desde la rama main de React Native.
No necesitarás instalar herramientas adicionales (como cmake, ninja o python3) en tu máquina ya que configuramos la compilación para usar las versiones NDK de esas herramientas.
En el lado del consumidor Gradle, también implementamos una pequeña mejora: cambiamos de releaseImplementation y debugImplementation a implementation. Esto es posible porque el nuevo artefacto Android hermes-engine es consciente de variantes y emparejará correctamente una compilación de depuración del motor con una compilación de depuración de tu aplicación. No necesitas ninguna configuración personalizada aquí (incluso si usas staging u otros tipos/sabores de compilación).
Sin embargo, esto hizo necesaria esta línea en la plantilla:
exclude group:'com.facebook.fbjni'
Esto es necesario porque React Native consume fbjni usando el enfoque no prefab (es decir, descomprimiendo el .aar y extrayendo archivos .so). Hermes-engine y otras bibliotecas usan prefab para consumir fbjni. Estamos trabajando en solucionar este problema en el futuro para que la importación de Hermes sea de una sola línea.
Detalles de implementación en iOS
La implementación en iOS depende de una serie de scripts ubicados en:
-
/scripts/hermes. Estos scripts contienen lógica para descargar el tarball de Hermes, descomprimirlo y configurar la compilación de iOS. Se invocan durantepod installsi tienes el campohermes_enabledestablecido entrue. -
/sdks/hermes-engine. Estos scripts contienen la lógica de compilación que efectivamente construye Hermes. Fueron copiados y adaptados del repositoriofacebook/hermespara funcionar correctamente dentro de React Native. Específicamente, los scripts dentro de la carpetautilsson responsables de construir Hermes para todas las plataformas Mac.
Hermes se compila como parte del Job build_hermes_macos en CircleCI. Este trabajo producirá como artefacto un tarball que será descargado por el podspec hermes-engine al usar una versión publicada de React Native (aquí hay un ejemplo de los artefactos creados para React Native 0.69 en build_hermes_macos).
Hermes precompilado
Si no hay artefactos precompilados para la versión de React Native que estás usando (por ejemplo, si trabajas con React Native desde la rama main), Hermes deberá compilarse desde el código fuente. Primero, el compilador de Hermes, hermesc, se compilará para macOS durante pod install, luego Hermes mismo se compilará como parte del flujo de trabajo de compilación de Xcode usando el script build-hermes-xcode.sh.
Compilar Hermes desde el código fuente
Hermes siempre se compila desde el código fuente cuando se usa React Native desde la rama main. Si usas una versión estable de React Native, puedes forzar la compilación de Hermes desde el código fuente configurando la variable de entorno CI en true al usar CocoaPods: CI=true pod install.
Símbolos de depuración
Los artefactos precompilados de Hermes no incluyen símbolos de depuración (dSYMs) por defecto. Planeamos distribuir estos símbolos de depuración para cada versión en el futuro. Hasta entonces, si necesitas los símbolos de depuración para Hermes, deberás compilar Hermes desde el código fuente. Se creará un archivo hermes.framework.dSYM en el directorio de compilación junto con cada framework de Hermes.
Me preocupa que este cambio me afecte
Nos gustaría destacar que este es esencialmente un cambio organizativo en dónde se construye Hermes y cómo se sincroniza el código entre los dos repositorios. Este cambio debería ser completamente transparente para nuestros usuarios.
Históricamente, solíamos crear una versión de Hermes para una versión específica de React Native (por ejemplo, v0.11.0 for RN0.68.x).
Con 'Bundled Hermes', puedes confiar en una etiqueta que representará la versión utilizada cuando se publicó una versión específica de React Native.