Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turbo Modules + Developer Scenarios #195

Open
stmoy opened this issue Jan 29, 2020 · 9 comments
Open

Turbo Modules + Developer Scenarios #195

stmoy opened this issue Jan 29, 2020 · 9 comments
Labels
🗣 Discussion This label identifies an ongoing discussion on a subject

Comments

@stmoy
Copy link
Collaborator

stmoy commented Jan 29, 2020

Introduction

#40 gives a primer the high level overview and architecture of Turbo Modules, but there doesn't seem to be a single place that discusses each of the developer scenarios around Turbo Modules. The purpose of this issue is to outline a set of scenarios and articulate how Turbo Modules fits in with each.

I've included answers (often partial) to the best of my knowledge, but I'm happy to be told I'm wrong or to receive more up-to-date information.

The Core of It

Scenario 1: Update existing module

The author of an existing native module react-native-foo has heard about Turbo Modules and the Leancore effort. Since react-native-foo is such a highly used module, they want to ensure that their module works when Turbo Modules come online.

Q: What work does react-native-foo need to do to be compatible with Turbo Modules? Do they need to rewrite their whole android and iOS implementations?

A: At a high level, the module author will need to write a JS spec, which will then generate some interfaces. The module author then copy/pastes the existing business logic to fill in the stubs. The signatures of the module's methods should not change (except minor ones that should be caught by Codegen)

Q: How will community module authors know that they need to update to Turbo Modules?

A: TBD. No step-by-step docs have been written yet.

Scenario 2: Writing new Module w/ platform-specific APIs

Alex has a great idea for a totally new module react-native-bar that has platform-specific implementations for iOS/Android/Windows.

Q: How does somebody write a new Turbo Module that has platform-specific APIs?

A: Same as scenario 1.

Scenario 3: Writing a new Module w/ platform-agnostic APIs

Bryce has a bunch of legacy C++ code that is platform-agnostic. Bryce would like to create a module that encapsulates this code and hopes it can be shared on iOS/Android/Windows.

Q: How does somebody write a new Turbo Module that has platform-agnostic/C++ APIs? Is the story different than Scenario 2?

A: Same as Scenario 1. Codegen will also produce C++ stubs from the JS spec.

Scenario 4: Existing App using Native Modules already

An app author wrote their app using the native module react-native-foo. Per Scenario 1, react-native-foo has been updated to become a turbo module.

Q: What (if anything) does an app author need to do to migrate from NM react-native-foo to TM react-native-foo?

A: ?

Scenario 5: App using Turbo Modules

Sage is working on an app written in React Native and wants to use react-native-foo. Sage knows that "ye olde" native modules can be included by performing “yarn add” + “react-native link foo” but isn’t sure how to include a Turbo Module.

Q: How does an app developer integrate TMs into their app?

A: TBD, but at a high level there will be an additional build-script that maintains packages and will have a straightforward way to auto-link as before.

Sceario 6: Native Modules + Turbo Moduels within the same app

An app author is using both react-native-camera and react-native-async-storage. Lets say that camera has been updated to support turbo modules, but let’s say AsyncStorage has not.

Q: What does this app author need to do? (Do they stay on the old version of camera? Can they mix and match?)

A: The app will opt in with a flag. The app will ignore non-migrated modules. Note that modules that are TM capable are also NM capable, meaning modules that migrate to TM will work everywhere.

Q: How are they expected to handle this transition over time?

A: See above. The app will need to determine if all of their modules are TM - if they are, they can then opt in with a flag. If not, the app shouldn't opt in yet.

Scenario 7: Platform developers ie. Windows support for TM

Andrew is working on updating React Native 4 Windows to support Turbo Modules.

Q: At a high-level, what steps are involved in making RN4W (or any out of tree platform) work with TMs?

A: ?

Discussion points

Q: What is the timeframe for Turbo Modules? (When will the codegen be ready? Docs? Guidance? Etc.?)

A: Generally, first half of 2020. However, it's unclear exactly what will be in that first release.

Q: Turbo Modules have a shared C++ layer. Is the expectation that authors will write significantly more shared code? Or will they still write mostly platform-specific code?  

A: ?

Useful links

@stmoy
Copy link
Collaborator Author

stmoy commented Jan 29, 2020

cc: @ejanzer

@kelset kelset added the 🗣 Discussion This label identifies an ongoing discussion on a subject label Jan 30, 2020
@RSNara
Copy link

RSNara commented Jan 30, 2020

What is the timeframe for Turbo Modules? (When will the codegen be ready? Docs? Guidance? Etc.?)

There are a few things that need to be done before we can tell OSS users of RN to start using TurboModules:

  • On iOS, there are a few OSS NativeModules that need to be migrated to the TurboModule system: RCTNativeAnimatedModule, RCTEventDispatcher, RCTTiming, RCTCxxModule, RCTEventEmitter, RCTDevLoadingView. This migration may require changes/bugfixes to the TurboModule system.
  • On Android, the generated base class for each NativeModule must be able to create its TurboModule jsi::HostObject. This requires changes to our internal codegen. Internally, we currently rely on a giant C++ function that maps a module's JS name to its TurboModule jsi::HostObject. Every application needs to write its own C++ function. This is very cumbersome and very difficult to maintain (we have land-blocking tests to ensure correctness). So, we need to move away from this internally.
  • We need to write TurboModule OSS documentation. At minimum, this will include an overview of the architecture of TurboModules (for both iOS and Android), and (2) how to write a TurboModule-compatible NativeModule (for in house NativeModules, and library NativeModules). This may also require a description of the codegen and how to use it.
  • Implement the Android portion of the NativeModules codegen
  • Open source the NativeModules codegen. Some problems we'll have to think about:
    • How do we integrate the codegen scripts into Cocoapods, and gradle
    • How do libraries shipping NativeModules use the codegen
  • There are 3/4 crashes we know of with TurboModules. We need to fix them.
  • Push internal iOS and Android rollout to 100% and stabilize TurboModules (i.e: fix any problems we discover). This could take anywhere from two weeks to two months or more. It just depends on the type of problems we discover.

This list is by no means exhaustive, but I think it gives a good idea of at least some of the work ahead of us as we push for full rollout of TurboModules in H1 2020.

@RSNara
Copy link

RSNara commented Jan 30, 2020

Turbo Modules have a shared C++ layer. Is the expectation that authors will write significantly more shared code? Or will they still write mostly platform-specific code?

With the TurboModule system, we don't need to wrap C++ NativeModules in Java/ObjC classes. So, on the whole, developers will end up writing less platform-specific boilerplate for their apps. This makes writing C++ NativeModules arguably easier than writing two of the same platform-specific NativeModules. In general, you should share as much code as possible. So, if you can write one C++ NativeModule, you should do that, as opposed to writing the same NativeModule in Java and Objective C.

For platform-specific modules, all the C++ you'll use will be auto-generated by the codegen.

@andrei-datcu
Copy link

Over the past months I've been wrapping some C++ cross platform code using jsi thinking I will be able to use it as a RN TurboModule in a future release. I think this partially falls under the 2nd scenario. However, I do not plan to use any of the codegen logic.

All my native code exposes is a function:
void* install(jsi:: Runtime &r, std:: function<void(std:: function<void()>)> jsThreadDispatcher

Inside the implementation, I'm using the global object to set up some HostFunctions. The "dispatcher" is called to schedule a random function on the right js thread. From that random function I will basically call a js function (be it a Promise's resolve or some other callback)

Question: will the TurboModule architecture support that?

Right now, my approach is working on the RN windows's old C# implementation with a custom jsi::Runtime implementation that does not own or frees any js context. The only problem I've observed is the debugging experience: there's no jsi Runtime for the webjs debugging runtime.

@mauriciopf

This comment has been minimized.

@SudoPlz

This comment has been minimized.

@scarlac

This comment has been minimized.

@bojie-liu
Copy link

Will react-native-codegen support typescript before release? What is the consideration if not?

@anhtuank7c
Copy link

@bojie-liu I think the current behavior is to use babel to transform Typescript to ES5 and it won't affect the release?
Correct me if i'm wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🗣 Discussion This label identifies an ongoing discussion on a subject
Projects
None yet
Development

No branches or pull requests

9 participants