Skip to content

Commit

Permalink
[0.73] Make Hermes the default JS engine (#12371)
Browse files Browse the repository at this point in the history
This PR backports #12321 to 0.73.

## Description

This PR makes Hermes the default JS engine for RNW going forward.

For now, this is still managed by setting the `<UseHermes>` MSBuild property. However, if the property is not explicitly set, the default value in `JSEngine.props` will now be `true` instead of `false`.

The property will remain exposed (and now set to `true`) in project's `ExperimentalFeatures.props` files. This will be done for new projects created with the `npx react-native-windows-init` command targeting versions with this change. (Use or omission of the `--useHermes` flag will no longer be recognized at project creation time). Hermes will also be the default for projects created with the new `npx react-native init-windows` CLI command.

Current users attempting to *upgrade* their existing projects with these tools will be given a warning if they were previously using the Chakra engine, and instructions to revert back to using Chakra if necessary. However, support for Chakra will be deprecated in the future, so best to migrate sooner rather than later.

In addition, this PR should also enable Hermes use when consuming the official (experimental) NuGet package binaries.

Finally, this PR updates our CI infrastructure to instead denote "Chakra" (rather than "Hermes") for builds and tests.

### Type of Change
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing functionality to not work as expected)
- This change requires a documentation update

### Why
Hermes is the officially supported and maintained JS engine for React Native, and as time goes on, the cost of maintain Chakra (which hasn't been updated in years) only increases. The "new" architecture includes Hermes.

Resolves #11251 

### What
See above

## Screenshots
N/A

## Testing
Ran existing tests

## Changelog
Should this change be included in the release notes: yes

Hermes is now the default JS engine for all new projects and will eventually be the only supported JS engine.
  • Loading branch information
jonthysell committed Nov 10, 2023
1 parent 8424413 commit ffbe2ea
Show file tree
Hide file tree
Showing 19 changed files with 158 additions and 57 deletions.
33 changes: 17 additions & 16 deletions .ado/jobs/cli-init.yml
Expand Up @@ -51,32 +51,32 @@ parameters:
platform: x86
projectType: lib
additionalRunArguments: --no-autolink --no-deploy
- Name: X86DebugCppHermes
- Name: X86DebugCppChakra
language: cpp
configuration: Debug
platform: x86
projectType: app
additionalInitArguments: --useHermes
- Name: X64ReleaseCsHermes
useChakra: true
- Name: X64ReleaseCsChakra
language: cs
configuration: Release
platform: x64
projectType: app
additionalInitArguments: --useHermes
useChakra: true
runWack: true
- Name: Arm64ReleaseCsHermes
- Name: Arm64ReleaseCsChakra
language: cs
configuration: Release
platform: ARM64
projectType: app
additionalInitArguments: --useHermes
useChakra: true
additionalRunArguments: --no-deploy
- Name: X64ReleaseCppHermes
- Name: X64ReleaseCppChakra
language: cpp
configuration: Release
platform: x64
projectType: app
additionalInitArguments: --useHermes
useChakra: true
runWack: true
- Name: X86DebugCppNuget
language: cpp
Expand Down Expand Up @@ -224,32 +224,32 @@ parameters:
platform: x86
projectType: lib
additionalRunArguments: --no-autolink --no-deploy
- Name: X86DebugCppHermes
- Name: X86DebugCppChakra
language: cpp
configuration: Debug
platform: x86
projectType: app
additionalInitArguments: --useHermes
- Name: X64ReleaseCsHermes
useChakra: true
- Name: X64ReleaseCsChakra
language: cs
configuration: Release
platform: x64
projectType: app
additionalInitArguments: --useHermes
useChakra: true
runWack: true
- Name: Arm64ReleaseCsHermes
- Name: Arm64ReleaseCsChakra
language: cs
configuration: Release
platform: ARM64
projectType: app
additionalInitArguments: --useHermes
useChakra: true
additionalRunArguments: --no-deploy
- Name: X64ReleaseCppHermes
- Name: X64ReleaseCppChakra
language: cpp
configuration: Release
platform: x64
projectType: app
additionalInitArguments: --useHermes
useChakra: true
runWack: true
- Name: X86DebugCppNuget
language: cpp
Expand Down Expand Up @@ -410,4 +410,5 @@ jobs:
additionalRunArguments: ${{ matrix.additionalRunArguments }}
runWack: ${{ coalesce(matrix.runWack, false) }}
buildEnvironment: ${{ parameters.buildEnvironment }}
useChakra: ${{ coalesce(matrix.useChakra, false) }}
useNuGet: ${{ coalesce(matrix.useNuGet, false) }}
20 changes: 10 additions & 10 deletions .ado/jobs/e2e-test.yml
Expand Up @@ -15,30 +15,30 @@ parameters:
Matrix:
- Name: X64Chakra
BuildPlatform: x64
UseHermes: false
UseChakra: true
- Name: X64Hermes
BuildPlatform: x64
UseHermes: true
UseChakra: false
- Name: X86Chakra
BuildPlatform: x86
UseHermes: false
UseChakra: true
- Name: X86Hermes
BuildPlatform: x86
UseHermes: true
UseChakra: false
- BuildEnvironment: Continuous
Matrix:
- Name: X64Chakra
BuildPlatform: x64
UseHermes: false
UseChakra: true
- Name: X64Hermes
BuildPlatform: x64
UseHermes: true
UseChakra: false
- Name: X86Chakra
BuildPlatform: x86
UseHermes: false
UseChakra: true
- Name: X86Hermes
BuildPlatform: x86
UseHermes: true
UseChakra: false

jobs:
- ${{ each config in parameters.buildMatrix }}:
Expand Down Expand Up @@ -77,7 +77,7 @@ jobs:
parameters:
package: packages/e2e-test-app
feature: UseHermes
value: ${{ matrix.UseHermes }}
value: ${{ not(coalesce(matrix.UseChakra, false)) }}

- template: ../templates/run-windows-with-certificates.yml
parameters:
Expand Down Expand Up @@ -157,7 +157,7 @@ jobs:
- ${{ each config in parameters.buildMatrix }}:
- ${{ if eq(config.BuildEnvironment, parameters.buildEnvironment) }}:
- ${{ each matrix in config.Matrix }}:
- ${{ if eq(matrix.UseHermes, true) }}:
- ${{ if eq(matrix.UseChakra, false) }}:
- job: E2ETestFabric${{ matrix.Name }}
displayName: E2E Test App Fabric ${{ matrix.Name }}

Expand Down
48 changes: 29 additions & 19 deletions .ado/jobs/integration-test.yml
Expand Up @@ -16,54 +16,64 @@ parameters:
BuildPlatform: ARM64
BuildConfiguration: Debug
DeployOptions: --no-deploy # We don't have Arm agents
UseHermes: false
- Name: X64WebDebug
BuildPlatform: x64
BuildConfiguration: Debug
DeployOptions:
UseHermes: false
- Name: X64ReleaseHermes
- Name: X86WebDebug
BuildPlatform: x86
BuildConfiguration: Debug
DeployOptions:
- Name: X64Release
BuildPlatform: x64
BuildConfiguration: Release
DeployOptions:
UseHermes: true
- Name: X86WebDebug
- Name: X86Release
BuildPlatform: x86
BuildConfiguration: Debug
BuildConfiguration: Release
DeployOptions:
- Name: X64ReleaseChakra
BuildPlatform: x64
BuildConfiguration: Release
DeployOptions:
UseHermes: false
- Name: X86ReleaseHermes
UseChakra: true
- Name: X86ReleaseChakra
BuildPlatform: x86
BuildConfiguration: Release
DeployOptions:
UseHermes: true
UseChakra: true
- BuildEnvironment: Continuous
Matrix:
- Name: Arm64Debug
BuildPlatform: ARM64
BuildConfiguration: Debug
DeployOptions: --no-deploy # We don't have Arm agents
UseHermes: false
- Name: X64WebDebug
BuildPlatform: x64
BuildConfiguration: Debug
DeployOptions:
UseHermes: false
- Name: X64ReleaseHermes
- Name: X86WebDebug
BuildPlatform: x86
BuildConfiguration: Debug
DeployOptions:
- Name: X64Release
BuildPlatform: x64
BuildConfiguration: Release
DeployOptions:
UseHermes: true
- Name: X86WebDebug
- Name: X86Release
BuildPlatform: x86
BuildConfiguration: Debug
BuildConfiguration: Release
DeployOptions:
- Name: X64ReleaseChakra
BuildPlatform: x64
BuildConfiguration: Release
DeployOptions:
UseHermes: false
- Name: X86ReleaseHermes
UseChakra: true
- Name: X86ReleaseChakra
BuildPlatform: x86
BuildConfiguration: Release
DeployOptions:
UseHermes: true
UseChakra: true

jobs:
- ${{ each config in parameters.buildMatrix }}:
Expand Down Expand Up @@ -101,7 +111,7 @@ jobs:
parameters:
package: packages/integration-test-app
feature: UseHermes
value: ${{ matrix.UseHermes }}
value: ${{ not(coalesce(matrix.UseChakra, false))}}

- ${{ if eq(matrix.BuildConfiguration, 'Debug') }}:
# The build is more likely to crash after we've started other bits that
Expand Down
9 changes: 9 additions & 0 deletions .ado/templates/react-native-init.yml
Expand Up @@ -24,6 +24,9 @@ parameters:
- name: additionalRunArguments
type: string
default: ''
- name: useChakra
type: boolean
default: false
- name: useNuGet
type: boolean
default: false
Expand Down Expand Up @@ -102,6 +105,12 @@ steps:
workingDirectory: $(Agent.BuildDirectory)\testcli
env:
npm_config_registry: http://localhost:4873
- template: set-experimental-feature.yml
parameters:
package: ..\testcli
feature: UseHermes
value: ${{ not(parameters.UseChakra) }}

- ${{ if eq(parameters.projectType, 'app') }}:
- powershell: |
Expand Down
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "[0.73] Make Hermes the default JS engine",
"packageName": "@react-native-windows/cli",
"email": "jthysell@microsoft.com",
"dependentChangeType": "patch"
}
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "[0.73] Make Hermes the default JS engine",
"packageName": "react-native-windows",
"email": "jthysell@microsoft.com",
"dependentChangeType": "patch"
}
Expand Up @@ -300,6 +300,28 @@ export function tryFindPropertyValue(
return null;
}

/**
* Search for the given property in the project contents and return its value.
* @param projectContents The XML project contents.
* @param propertyName The property to look for.
* @return The value of the tag if it exists.
*/
export function tryFindPropertyValueAsBoolean(
projectContents: Node,
propertyName: string,
): boolean | null {
const rawValue = tryFindPropertyValue(projectContents, propertyName);

switch (rawValue) {
case 'true':
return true;
case 'false':
return false;
default:
return null;
}
}

export function findPropertyValue(
projectContents: Node,
propertyName: string,
Expand Down
22 changes: 22 additions & 0 deletions packages/@react-native-windows/cli/src/generator-windows/index.ts
Expand Up @@ -16,6 +16,7 @@ import findUp from 'find-up';
import {
readProjectFile,
findPropertyValue,
tryFindPropertyValueAsBoolean,
} from '../commands/config/configUtils';

import {
Expand Down Expand Up @@ -130,6 +131,27 @@ export async function copyProjectTemplateAndReplace(
console.log('Using experimental NuGet dependency.');
}

const experimentalPropsPath = path.join(
destPath,
windowsDir,
'ExperimentalFeatures.props',
);

let existingUseHermes: boolean | null = null;
if (fs.existsSync(experimentalPropsPath)) {
existingUseHermes = tryFindPropertyValueAsBoolean(
readProjectFile(experimentalPropsPath),
'UseHermes',
);
}

if (existingUseHermes === false) {
console.warn(
'Hermes is now the default JS engine and will be enabled for this project. Support for Chakra will be deprecated in the future. To disable Hermes and keep using Chakra for now, see https://microsoft.github.io/react-native-windows/docs/hermes#disabling-hermes.',
);
}
options.useHermes = true;

if (options.useWinUI3) {
throw new CodedError(
'IncompatibleOptions',
Expand Down
2 changes: 1 addition & 1 deletion packages/e2e-test-app/windows/ExperimentalFeatures.props
Expand Up @@ -2,7 +2,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup Label="Microsoft.ReactNative Experimental Features">
<UseHermes>false</UseHermes>
<UseHermes>true</UseHermes>
<EnableSourceLink>true</EnableSourceLink>
<ReactExperimentalFeaturesSet>true</ReactExperimentalFeaturesSet>
</PropertyGroup>
Expand Down
Expand Up @@ -2,7 +2,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup Label="Microsoft.ReactNative Experimental Features">
<UseHermes>false</UseHermes>
<UseHermes>true</UseHermes>
<EnableSourceLink>true</EnableSourceLink>
<ReactExperimentalFeaturesSet>true</ReactExperimentalFeaturesSet>
</PropertyGroup>
Expand Down
Expand Up @@ -6,6 +6,10 @@
* @format
*/

// Make sure that we import something from react-native so that we build a complete bundle
// eslint-disable-next-line no-unused-vars
import {View} from 'react-native';

import {default as myTrivialTurboModule} from './NativeMyTrivialTurboModule';

myTrivialTurboModule.startFromJS();
Expand Up @@ -6,6 +6,10 @@
* @format
*/

// Make sure that we import something from react-native so that we build a complete bundle
// eslint-disable-next-line no-unused-vars
import {View} from 'react-native';

import {default as mySimpleTurboModule} from './NativeMySimpleTurboModuleCxx';

// The logging of the TurboModule functions is verified against the test action sequence.
Expand Down

0 comments on commit ffbe2ea

Please sign in to comment.