Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/prebuild-ios-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ jobs:
shell: bash
run: |
if [ "${{ inputs.use-hermes-nightly }}" == "true" ]; then
HERMES_VERSION="nightly"
# We are not publishing nightly versions of Hermes V1 yet.
# For now, we can use the latest version of Hermes V1 published on maven and npm.
HERMES_VERSION="latest-v1"
else
HERMES_VERSION=$(sed -n 's/^HERMES_VERSION_NAME=//p' packages/react-native/sdks/hermes-engine/version.properties)
HERMES_VERSION=$(sed -n 's/^HERMES_V1_VERSION_NAME=//p' packages/react-native/sdks/hermes-engine/version.properties)
fi
echo "Using Hermes version: $HERMES_VERSION"
echo "HERMES_VERSION=$HERMES_VERSION" >> $GITHUB_ENV
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ react.internal.useHermesStable=false
react.internal.useHermesNightly=true

# Controls whether to use Hermes 1.0. Clean and rebuild when changing.
hermesV1Enabled=false
hermesV1Enabled=true
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,5 @@ abstract class PrivateReactExtension @Inject constructor(project: Project) {
val codegenDir: DirectoryProperty =
objects.directoryProperty().convention(root.dir("node_modules/@react-native/codegen"))

val hermesV1Enabled: Property<Boolean> = objects.property(Boolean::class.java).convention(false)
val hermesV1Enabled: Property<Boolean> = objects.property(Boolean::class.java).convention(true)
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ internal object DependencyUtils {
fun configureDependencies(
project: Project,
coordinates: Coordinates,
hermesV1Enabled: Boolean = false,
hermesV1Enabled: Boolean = true,
) {
if (
coordinates.versionString.isBlank() ||
Expand Down Expand Up @@ -149,7 +149,7 @@ internal object DependencyUtils {

internal fun getDependencySubstitutions(
coordinates: Coordinates,
hermesV1Enabled: Boolean = false,
hermesV1Enabled: Boolean = true,
): List<Triple<String, String, String>> {
val dependencySubstitution = mutableListOf<Triple<String, String, String>>()
val hermesVersion =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ internal object ProjectUtils {

const val HERMES_FALLBACK = true

const val HERMES_V1_ENABLED_FALLBACK = true

internal fun Project.isNewArchEnabled(): Boolean = true

internal val Project.isHermesEnabled: Boolean
Expand Down Expand Up @@ -73,6 +75,9 @@ internal object ProjectUtils {

internal val Project.isHermesV1Enabled: Boolean
get() =
if (
project.hasProperty(HERMES_V1_ENABLED) || project.hasProperty(SCOPED_HERMES_V1_ENABLED)
) {
(project.hasProperty(HERMES_V1_ENABLED) &&
project.property(HERMES_V1_ENABLED).toString().toBoolean()) ||
(project.hasProperty(SCOPED_HERMES_V1_ENABLED) &&
Expand All @@ -81,6 +86,9 @@ internal object ProjectUtils {
project.extraProperties.get(HERMES_V1_ENABLED).toString().toBoolean()) ||
(project.extraProperties.has(SCOPED_HERMES_V1_ENABLED) &&
project.extraProperties.get(SCOPED_HERMES_V1_ENABLED).toString().toBoolean())
} else {
HERMES_V1_ENABLED_FALLBACK
}

internal fun Project.needsCodegenFromPackageJson(rootProperty: DirectoryProperty): Boolean {
val parsedPackageJson = readPackageJsonFile(this, rootProperty)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ class DependencyUtilsTest {
assertThat(forcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
.isTrue()
assertThat(forcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:4.5.6" })
.isFalse()
assertThat(forcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:7.8.9" })
.isTrue()
}

Expand Down Expand Up @@ -325,10 +327,14 @@ class DependencyUtilsTest {
assertThat(appForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
.isTrue()
assertThat(appForcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:4.5.6" })
.isFalse()
assertThat(appForcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:7.8.9" })
.isTrue()
assertThat(libForcedModules.any { it.toString() == "com.facebook.react:react-android:1.2.3" })
.isTrue()
assertThat(libForcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:4.5.6" })
.isFalse()
assertThat(libForcedModules.any { it.toString() == "com.facebook.hermes:hermes-android:7.8.9" })
.isTrue()
}

Expand Down Expand Up @@ -384,12 +390,20 @@ class DependencyUtilsTest {
assertThat(
appForcedModules.any { it.toString() == "io.github.test.hermes:hermes-android:4.5.6" }
)
.isFalse()
assertThat(
appForcedModules.any { it.toString() == "io.github.test.hermes:hermes-android:7.8.9" }
)
.isTrue()
assertThat(libForcedModules.any { it.toString() == "io.github.test:react-android:1.2.3" })
.isTrue()
assertThat(
libForcedModules.any { it.toString() == "io.github.test.hermes:hermes-android:4.5.6" }
)
.isFalse()
assertThat(
libForcedModules.any { it.toString() == "io.github.test.hermes:hermes-android:7.8.9" }
)
.isTrue()
}

Expand Down Expand Up @@ -430,7 +444,7 @@ class DependencyUtilsTest {
}

@Test
fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly_withClassicHermes() {
fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly_withHermesV1() {
val dependencySubstitutions =
getDependencySubstitutions(DependencyUtils.Coordinates("0.42.0", "0.42.0", "0.43.0"))

Expand All @@ -442,7 +456,7 @@ class DependencyUtilsTest {
)
.isEqualTo(dependencySubstitutions[0].third)
assertThat("com.facebook.react:hermes-engine").isEqualTo(dependencySubstitutions[1].first)
assertThat("com.facebook.hermes:hermes-android:0.42.0")
assertThat("com.facebook.hermes:hermes-android:0.43.0")
.isEqualTo(dependencySubstitutions[1].second)
assertThat(
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210."
Expand All @@ -451,7 +465,7 @@ class DependencyUtilsTest {
}

@Test
fun getDependencySubstitutions_withDefaultGroup_substitutesCorrectly_withHermesV1() {
fun getDependencySubstitutions_withDefaultGroupAndFallback_substitutesCorrectly_withClassicHermes() {
val dependencySubstitutions =
getDependencySubstitutions(
DependencyUtils.Coordinates("0.42.0", "0.42.0", "0.43.0"),
Expand All @@ -475,7 +489,7 @@ class DependencyUtilsTest {
}

@Test
fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly_withClassicHermes() {
fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly_withHermesV1() {
val dependencySubstitutions =
getDependencySubstitutions(
DependencyUtils.Coordinates(
Expand All @@ -494,14 +508,14 @@ class DependencyUtilsTest {
)
.isEqualTo(dependencySubstitutions[0].third)
assertThat("com.facebook.react:hermes-engine").isEqualTo(dependencySubstitutions[1].first)
assertThat("io.github.test.hermes:hermes-android:0.42.0")
assertThat("io.github.test.hermes:hermes-android:0.43.0")
.isEqualTo(dependencySubstitutions[1].second)
assertThat(
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210."
)
.isEqualTo(dependencySubstitutions[1].third)
assertThat("com.facebook.react:hermes-android").isEqualTo(dependencySubstitutions[2].first)
assertThat("io.github.test.hermes:hermes-android:0.42.0")
assertThat("io.github.test.hermes:hermes-android:0.43.0")
.isEqualTo(dependencySubstitutions[2].second)
assertThat("The hermes-android artifact was moved to com.facebook.hermes publishing group.")
.isEqualTo(dependencySubstitutions[2].third)
Expand All @@ -510,14 +524,14 @@ class DependencyUtilsTest {
assertThat("The react-android dependency was modified to use the correct Maven group.")
.isEqualTo(dependencySubstitutions[3].third)
assertThat("com.facebook.react:hermes-android").isEqualTo(dependencySubstitutions[4].first)
assertThat("io.github.test.hermes:hermes-android:0.42.0")
assertThat("io.github.test.hermes:hermes-android:0.43.0")
.isEqualTo(dependencySubstitutions[4].second)
assertThat("The hermes-android dependency was modified to use the correct Maven group.")
.isEqualTo(dependencySubstitutions[4].third)
}

@Test
fun getDependencySubstitutions_withCustomGroup_substitutesCorrectly_withHermesV1() {
fun getDependencySubstitutions_withCustomGroupAndFallbackToClassicHermes_substitutesCorrectly_withClassicHermes() {
val dependencySubstitutions =
getDependencySubstitutions(
DependencyUtils.Coordinates(
Expand All @@ -527,7 +541,7 @@ class DependencyUtilsTest {
"io.github.test",
"io.github.test.hermes",
),
hermesV1Enabled = true,
hermesV1Enabled = false,
)

assertThat("com.facebook.react:react-native").isEqualTo(dependencySubstitutions[0].first)
Expand All @@ -537,14 +551,14 @@ class DependencyUtilsTest {
)
.isEqualTo(dependencySubstitutions[0].third)
assertThat("com.facebook.react:hermes-engine").isEqualTo(dependencySubstitutions[1].first)
assertThat("io.github.test.hermes:hermes-android:0.43.0")
assertThat("io.github.test.hermes:hermes-android:0.42.0")
.isEqualTo(dependencySubstitutions[1].second)
assertThat(
"The hermes-engine artifact was deprecated in favor of hermes-android due to https://github.com/facebook/react-native/issues/35210."
)
.isEqualTo(dependencySubstitutions[1].third)
assertThat("com.facebook.react:hermes-android").isEqualTo(dependencySubstitutions[2].first)
assertThat("io.github.test.hermes:hermes-android:0.43.0")
assertThat("io.github.test.hermes:hermes-android:0.42.0")
.isEqualTo(dependencySubstitutions[2].second)
assertThat("The hermes-android artifact was moved to com.facebook.hermes publishing group.")
.isEqualTo(dependencySubstitutions[2].third)
Expand All @@ -553,7 +567,7 @@ class DependencyUtilsTest {
assertThat("The react-android dependency was modified to use the correct Maven group.")
.isEqualTo(dependencySubstitutions[3].third)
assertThat("com.facebook.react:hermes-android").isEqualTo(dependencySubstitutions[4].first)
assertThat("io.github.test.hermes:hermes-android:0.43.0")
assertThat("io.github.test.hermes:hermes-android:0.42.0")
.isEqualTo(dependencySubstitutions[4].second)
assertThat("The hermes-android dependency was modified to use the correct Maven group.")
.isEqualTo(dependencySubstitutions[4].third)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ class ProjectUtilsTest {
}

@Test
fun isHermesV1Enabled_returnsFalseByDefault() {
assertThat(createProject().isHermesV1Enabled).isFalse()
fun isHermesV1Enabled_returnsTrueByDefault() {
assertThat(createProject().isHermesV1Enabled).isTrue()
}

@Test
Expand Down
1 change: 1 addition & 0 deletions packages/react-native/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,7 @@ extension Target {
.define("NDEBUG", .when(configuration: .release)),
.define("USE_HERMES", to: "1"),
.define("RCT_REMOVE_LEGACY_ARCH", to: "1"),
.define("HERMES_V1_ENABLED", to: "1"),
] + defines + cxxCommonHeaderPaths

return .target(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <jsi/decorator.h>
#include <jsinspector-modern/InspectorFlags.h>

#include <thread>

#include <hermes/inspector-modern/chrome/HermesRuntimeTargetDelegate.h>

#if defined(HERMES_ENABLE_DEBUGGER) && !defined(HERMES_V1_ENABLED)
Expand Down
27 changes: 24 additions & 3 deletions packages/react-native/scripts/ios-prebuild/hermes.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,13 @@ async function prepareHermesArtifactsAsync(
// Only check if the artifacts folder exists if we are not using a local tarball
if (!localPath) {
// Resolve the version from the environment variable or use the default version
let resolvedVersion = process.env.HERMES_VERSION ?? 'nightly';
let resolvedVersion = process.env.HERMES_VERSION ?? 'latest-v1';

if (resolvedVersion === 'nightly') {
if (resolvedVersion === 'latest-v1') {
hermesLog('Using latest-v1 tarball');
const hermesVersion = await getLatestV1VersionFromNPM();
resolvedVersion = hermesVersion;
} else if (resolvedVersion === 'nightly') {
hermesLog('Using latest nightly tarball');
const hermesVersion = await getNightlyVersionFromNPM();
resolvedVersion = hermesVersion;
Expand Down Expand Up @@ -102,14 +106,31 @@ async function prepareHermesArtifactsAsync(
return artifactsPath;
}

async function getLatestV1VersionFromNPM() /*: Promise<string> */ {
const npmResponse /*: Response */ = await fetch(
'https://registry.npmjs.org/hermes-compiler/latest-v1',
);

if (!npmResponse.ok) {
throw new Error(
`Couldn't get a response from NPM: ${npmResponse.status} ${npmResponse.statusText}`,
);
}

const json = await npmResponse.json();
const latestV1 = json.version;
hermesLog(`Using version ${latestV1}`);
return latestV1;
}

async function getNightlyVersionFromNPM() /*: Promise<string> */ {
const npmResponse /*: Response */ = await fetch(
'https://registry.npmjs.org/hermes-compiler/nightly',
);

if (!npmResponse.ok) {
throw new Error(
`Couldn't get an answer from NPM: ${npmResponse.status} ${npmResponse.statusText}`,
`Couldn't get a response from NPM: ${npmResponse.status} ${npmResponse.statusText}`,
);
}

Expand Down
5 changes: 5 additions & 0 deletions packages/react-native/scripts/react_native_pods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ def use_react_native! (
# excluding the legacy arch unless the user turns this flag off explicitly.
ENV['RCT_REMOVE_LEGACY_ARCH'] = ENV['RCT_REMOVE_LEGACY_ARCH'] == '0' ? '0' : '1'

# Enable Hermes V1 by default.
# Users can still turn it off and use legacy hermes by setting the RCT_HERMES_V1_ENABLED
# environment variable to '0'.
ENV['RCT_HERMES_V1_ENABLED']= ENV['RCT_HERMES_V1_ENABLED'] == '0' ? '0' : '1'

ReactNativePodsUtils.check_minimum_required_xcode()

# Current target definition is provided by Cocoapods and it refers to the target
Expand Down
21 changes: 15 additions & 6 deletions packages/react-native/sdks/hermes-engine/hermes-engine.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ end
package = JSON.parse(File.read(File.join(react_native_path, "package.json")))
versionProperties = Hash[*File.read("version.properties").split(/[=\n]+/)]

if ENV['RCT_HERMES_V1_ENABLED'] == "1"
version = versionProperties['HERMES_V1_VERSION_NAME']
else
if ENV['RCT_HERMES_V1_ENABLED'] == "0"
version = versionProperties['HERMES_VERSION_NAME']
else
version = versionProperties['HERMES_V1_VERSION_NAME']
end

# Local monorepo build
if package['version'] == "1000.0.0" then
# We don't want to build Hermes V1 from source
if ENV['RCT_HERMES_V1_ENABLED'] == "0" && package['version'] == "1000.0.0" then
hermesCompilerVersion = package['dependencies']['hermes-compiler']
if hermesCompilerVersion != "0.0.0" then
version = hermesCompilerVersion
Expand Down Expand Up @@ -68,7 +69,15 @@ Pod::Spec.new do |spec|

spec.subspec 'Pre-built' do |ss|
ss.preserve_paths = ["destroot/bin/*"].concat(["**/*.{h,c,cpp}"])
ss.source_files = "destroot/include/hermes/**/*.h"
if ENV["RCT_HERMES_V1_ENABLED"] == "0"
ss.source_files = "destroot/include/hermes/**/*.h"
else
# Hermes v1 is shipping a jsi/hermes.h header which is imported by the hermes.h header
# and that file is not present in React Native's JSI
# (see https://github.com/facebook/react-native/tree/main/packages/react-native/ReactCommon/jsi/jsi/ where there is
# hermes-interface.h but not hermes.h)
ss.source_files = ["destroot/include/hermes/**/*.h", "destroot/include/jsi/hermes.h"]
end
ss.header_mappings_dir = "destroot/include"
ss.ios.vendored_frameworks = "destroot/Library/Frameworks/universal/hermesvm.xcframework"
ss.visionos.vendored_frameworks = "destroot/Library/Frameworks/universal/hermesvm.xcframework"
Expand Down Expand Up @@ -131,7 +140,7 @@ Pod::Spec.new do |spec|
ss.header_dir = 'hermes/Public'
end

if ENV['RCT_HERMES_V1_ENABLED'] != "1"
if ENV['RCT_HERMES_V1_ENABLED'] == "0"
spec.subspec 'inspector' do |ss|
ss.source_files = ''
ss.public_header_files = 'API/hermes/inspector/*.h'
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/sdks/hermes-engine/hermes-utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def hermes_commit_envvar_defined()
end

def hermes_v1_enabled()
return ENV['RCT_HERMES_V1_ENABLED'] == "1"
return ENV['RCT_HERMES_V1_ENABLED'] != "0"
end

def force_build_from_tag(react_native_path)
Expand Down
4 changes: 3 additions & 1 deletion scripts/releases/utils/hermes-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const MAVEN_VERSIONS_FILE_PATH = path.join(

async function getLatestHermesNightlyVersion() /*: Promise<{
compilerVersion: string,
compilerV1Version: string,
runtimeVersion: string,
runtimeV1Version: string,
}> */ {
Expand All @@ -43,6 +44,7 @@ async function getLatestHermesNightlyVersion() /*: Promise<{

return {
compilerVersion,
compilerV1Version,
// runtime version should match the compiler version
runtimeVersion: compilerVersion,
runtimeV1Version: compilerV1Version,
Expand Down Expand Up @@ -84,7 +86,7 @@ async function updateHermesRuntimeDependenciesVersions(
async function updateHermesVersionsToNightly() {
const hermesVersions = await getLatestHermesNightlyVersion();
await updateHermesCompilerVersionInDependencies(
hermesVersions.compilerVersion,
hermesVersions.compilerV1Version,
);
await updateHermesRuntimeDependenciesVersions(
hermesVersions.runtimeVersion,
Expand Down
Loading