Summary: Microsoft’s RN for macOS fork supports the Hermes engine nowadays https://github.com/microsoft/react-native-macos/pull/473. As a longer term work item, we’ve started moving bits that are not invasive for iOS but _are_ a maintenance burden on us—mostly when merging—upstream. Seeing as this one is a recent addition, it seemed like a good candidate to start with. As to the actual changes, these include: * Sharing Android’s Hermes executor with the objc side of the codebase. * Adding a CocoaPods subspec to build the Hermes inspector source and its dependencies (`Folly/Futures`, `libevent`). * Adding the bits to the Xcode build phase script that creates the JS bundle for release builds to compile Hermes bytecode and source-maps… * …coincidentally it turns out that the Xcode build phase script did _not_ by default output source-maps for iOS, which is now fixed too. All of the Hermes bits are automatically enabled, on macOS, when providing the `hermes-engine-darwin` [npm package](https://www.npmjs.com/package/hermes-engine-darwin) and enabling the Hermes pods. ## Changelog [General] [Added] - Upstream RN macOS Hermes integration bits Pull Request resolved: https://github.com/facebook/react-native/pull/29748 Test Plan: Building RNTester for iOS and Android still works as before. To test the actual changes themselves, you’ll have to use the macOS target in RNTester in the macOS fork, or create a new application from `master`: <img width="812" alt="Screenshot 2020-08-18 at 16 55 06" src="https://user-images.githubusercontent.com/2320/90547606-160f6480-e18c-11ea-9a98-edbbaa755800.png"> Reviewed By: TheSavior Differential Revision: D23304618 Pulled By: fkgozali fbshipit-source-id: 4ef0e0f60d909f3c59f9cfc87c667189df656a3b
hermes-inspector provides a bridge between the low-level debugging API exposed by Hermes and higher-level debugging protocols such as the Chrome DevTools protocol.
Targets
- chrome: classes that implement the Chrome DevTools Protocol adapter. Sits on top of classes provided by the inspector target.
- detail: utility classes and functions
- inspector: protocol-independent classes that sit on top of the low-level Hermes debugging API.
Testing
Tests are implemented using gtest. Debug logging is enabled for tests, and you can get debug logs to show even when tests are passing by running the test executable directly:
$ buck build //xplat/js/react-native-github/ReactCommon/hermes/inspector:chrome-tests
$ buck-out/gen/js/react-native-github/ReactCommon/hermes/inspector/chrome-tests
[...]
You can use standard gtest filters to only execute a particular set of tests:
$ buck-out/gen/js/react-native-github/ReactCommon/hermes/inspector/chrome-tests \
--gtest_filter='ConnectionTests.testSetBreakpoint'
You can debug the tests using lldb or gdb:
$ lldb buck-out/gen/js/react-native-github/ReactCommon/hermes/inspector/chrome-tests
$ gdb buck-out/gen/js/react-native-github/ReactCommon/hermes/inspector/chrome-tests
Formatting
Make sure the code is formatted using the hermes clang-format rules before committing:
$ xplat/js/react-native-github/ReactCommon/hermes/inspector/tools/format
We follow the clang format rules used by the rest of the Hermes project.
Adding Support For New Message Types
To add support for a new Chrome DevTools protocol message, add the message you want to add to tools/message_types.txt, and re-run the message types generator:
$ xplat/js/react-native-github/ReactCommon/hermes/inspector/tools/run_msggen
This will generate C++ structs for the new message type in
chrome/MessageTypes.{h,cpp}.
You'll then need to:
- Implement a message handler for the new message type in
chrome::Connection. - Implement a public API for the new message type in
Inspector. This will most likely return afolly::Futurethat the message handler in (1) can use for chaining. - Implement a private API for the new message type in
Inspectorthat performs the logic in Inspector's executor. (Inspector.cpp contains a comment explaining why the executor is necessary.) - Optionally, implement a method for the new message type in
InspectorState. In most cases this is probably not necessary--one of the existing methods inInspectorStatewill work.
For a diff that illustrates these steps, take a look at D6601459.
Testing Integration With Nuclide and Apps
For now, the quickest way to use hermes-inspector in an app is with Eats. First, make sure the packager is running:
$ js1 run
Then, on Android, build the fbeats target:
$ buck install --run fbeats
On iOS, build the //Apps/Internal/Eats:Eats target:
$ buck install --run //Apps/Internal/Eats:Eats
You can also build Eats in Xcode using arc focus if you prefer an
IDE:
$ arc focus --force-build \
-b //Apps/Internal/Eats:Eats \
cxxreact //xplat/hermes/API:HermesAPI //xplat/hermes/lib/VM:VM jsi \
jsinspector hermes-inspector FBReactKit FBReactModule FBCatalystWrapper \
//xplat/js:React //xplat/js/react-native-github:ReactInternal
For all the above commands, if you want to build the inspector -O0 for better
debug info, add the argument --config hermes.build_mode=dbg.
You should then be able to launch the app and see it listed in the list of Mobile JS contexts in the Nuclide debugger.