mirror of
https://github.com/facebook/react-native.git
synced 2024-11-21 22:10:14 +00:00
Make NativeModules.foo also load turbo modules (#47598)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47598 ## Changes Now: - in bridgeless, NativeModules.foo will also return turbo modules. And, global.__turboModuleProxy no longer exists. - in bridge, nothing changes. | **JS API** | **Bridge** | ***[Before]* Bridgeless** | ***[Before]* Bridgeless w/ Interop**| ***[After]* Bridgeless** | global.__turboModuleProxy | turbo modules | turbo modules | turbo modules |**deleted** | global.nativeModuleProxy | legacy modules | error | legacy modules | turbo + legacy modules ## Justification This reduces the cost for adopting the new architecture: - Prior, you had to migrate the module itself, **and** all its callsites: NativeModules.foo -> NativeFoo - Now, you have to migrate the module itself **only**. This simplifies the interop layer logic in bridgeless: all modules come from the same thing. Changelog: [General][Breaking] Bridgeless: Make NativeModules.foo load turbomodules (unset turboModuleProxy in bridgeless). Reviewed By: javache Differential Revision: D65896934 fbshipit-source-id: 10883c292b78759fceac5bd984e0cdf8a679fc67
This commit is contained in:
parent
d1b0e9a30b
commit
cc5f17d5a2
@ -16,9 +16,6 @@ const NativeModules = require('../BatchedBridge/NativeModules');
|
||||
|
||||
const turboModuleProxy = global.__turboModuleProxy;
|
||||
|
||||
const useLegacyNativeModuleInterop =
|
||||
global.RN$Bridgeless !== true || global.RN$TurboInterop === true;
|
||||
|
||||
function requireModule<T: TurboModule>(name: string): ?T {
|
||||
if (turboModuleProxy != null) {
|
||||
const module: ?T = turboModuleProxy(name);
|
||||
@ -27,8 +24,11 @@ function requireModule<T: TurboModule>(name: string): ?T {
|
||||
}
|
||||
}
|
||||
|
||||
if (useLegacyNativeModuleInterop) {
|
||||
// Backward compatibility layer during migration.
|
||||
if (
|
||||
global.RN$Bridgeless !== true ||
|
||||
global.RN$TurboInterop === true ||
|
||||
global.RN$UnifiedNativeModuleProxy === true
|
||||
) {
|
||||
const legacyModule: ?T = NativeModules[name];
|
||||
if (legacyModule != null) {
|
||||
return legacyModule;
|
||||
|
@ -17,11 +17,25 @@ using namespace facebook;
|
||||
namespace facebook::react {
|
||||
|
||||
class BridgelessNativeModuleProxy : public jsi::HostObject {
|
||||
std::unique_ptr<TurboModuleBinding> binding_;
|
||||
TurboModuleBinding turboBinding_;
|
||||
std::unique_ptr<TurboModuleBinding> legacyBinding_;
|
||||
|
||||
public:
|
||||
BridgelessNativeModuleProxy(std::unique_ptr<TurboModuleBinding> binding)
|
||||
: binding_(std::move(binding)) {}
|
||||
BridgelessNativeModuleProxy(
|
||||
jsi::Runtime& runtime,
|
||||
TurboModuleProviderFunctionType&& moduleProvider,
|
||||
TurboModuleProviderFunctionType&& legacyModuleProvider,
|
||||
std::shared_ptr<LongLivedObjectCollection> longLivedObjectCollection)
|
||||
: turboBinding_(
|
||||
runtime,
|
||||
std::move(moduleProvider),
|
||||
longLivedObjectCollection),
|
||||
legacyBinding_(
|
||||
legacyModuleProvider ? std::make_unique<TurboModuleBinding>(
|
||||
runtime,
|
||||
std::move(legacyModuleProvider),
|
||||
longLivedObjectCollection)
|
||||
: nullptr) {}
|
||||
|
||||
jsi::Value get(jsi::Runtime& runtime, const jsi::PropNameID& name) override {
|
||||
/**
|
||||
@ -42,14 +56,19 @@ class BridgelessNativeModuleProxy : public jsi::HostObject {
|
||||
return jsi::Value(false);
|
||||
}
|
||||
|
||||
if (binding_) {
|
||||
return binding_->getModule(runtime, moduleName);
|
||||
auto turboModule = turboBinding_.getModule(runtime, moduleName);
|
||||
if (turboModule.isObject()) {
|
||||
return turboModule;
|
||||
}
|
||||
|
||||
throw jsi::JSError(
|
||||
runtime,
|
||||
"Tried to access NativeModule \"" + name.utf8(runtime) +
|
||||
"\" from the bridge. This isn't allowed in Bridgeless mode.");
|
||||
if (legacyBinding_) {
|
||||
auto legacyModule = legacyBinding_->getModule(runtime, moduleName);
|
||||
if (legacyModule.isObject()) {
|
||||
return legacyModule;
|
||||
}
|
||||
}
|
||||
|
||||
return jsi::Value::null();
|
||||
}
|
||||
|
||||
void set(
|
||||
@ -79,44 +98,46 @@ void TurboModuleBinding::install(
|
||||
TurboModuleProviderFunctionType&& moduleProvider,
|
||||
TurboModuleProviderFunctionType&& legacyModuleProvider,
|
||||
std::shared_ptr<LongLivedObjectCollection> longLivedObjectCollection) {
|
||||
runtime.global().setProperty(
|
||||
runtime,
|
||||
"__turboModuleProxy",
|
||||
jsi::Function::createFromHostFunction(
|
||||
runtime,
|
||||
jsi::PropNameID::forAscii(runtime, "__turboModuleProxy"),
|
||||
1,
|
||||
[binding = TurboModuleBinding(
|
||||
runtime, std::move(moduleProvider), longLivedObjectCollection)](
|
||||
jsi::Runtime& rt,
|
||||
const jsi::Value& thisVal,
|
||||
const jsi::Value* args,
|
||||
size_t count) {
|
||||
if (count < 1) {
|
||||
throw std::invalid_argument(
|
||||
"__turboModuleProxy must be called with at least 1 argument");
|
||||
}
|
||||
std::string moduleName = args[0].getString(rt).utf8(rt);
|
||||
return binding.getModule(rt, moduleName);
|
||||
}));
|
||||
// TODO(T208105802): We can get this information from the native side!
|
||||
auto isBridgeless = runtime.global().hasProperty(runtime, "RN$Bridgeless");
|
||||
|
||||
if (runtime.global().hasProperty(runtime, "RN$Bridgeless")) {
|
||||
bool rnTurboInterop = legacyModuleProvider != nullptr;
|
||||
auto turboModuleBinding = legacyModuleProvider
|
||||
? std::make_unique<TurboModuleBinding>(
|
||||
runtime,
|
||||
std::move(legacyModuleProvider),
|
||||
longLivedObjectCollection)
|
||||
: nullptr;
|
||||
auto nativeModuleProxy = std::make_shared<BridgelessNativeModuleProxy>(
|
||||
std::move(turboModuleBinding));
|
||||
defineReadOnlyGlobal(
|
||||
runtime, "RN$TurboInterop", jsi::Value(rnTurboInterop));
|
||||
defineReadOnlyGlobal(
|
||||
if (!isBridgeless) {
|
||||
runtime.global().setProperty(
|
||||
runtime,
|
||||
"nativeModuleProxy",
|
||||
jsi::Object::createFromHostObject(runtime, nativeModuleProxy));
|
||||
"__turboModuleProxy",
|
||||
jsi::Function::createFromHostFunction(
|
||||
runtime,
|
||||
jsi::PropNameID::forAscii(runtime, "__turboModuleProxy"),
|
||||
1,
|
||||
[binding = TurboModuleBinding(
|
||||
runtime,
|
||||
std::move(moduleProvider),
|
||||
longLivedObjectCollection)](
|
||||
jsi::Runtime& rt,
|
||||
const jsi::Value& /*thisVal*/,
|
||||
const jsi::Value* args,
|
||||
size_t count) {
|
||||
if (count < 1) {
|
||||
throw std::invalid_argument(
|
||||
"__turboModuleProxy must be called with at least 1 argument");
|
||||
}
|
||||
std::string moduleName = args[0].getString(rt).utf8(rt);
|
||||
return binding.getModule(rt, moduleName);
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
defineReadOnlyGlobal(runtime, "RN$UnifiedNativeModuleProxy", true);
|
||||
defineReadOnlyGlobal(
|
||||
runtime,
|
||||
"nativeModuleProxy",
|
||||
jsi::Object::createFromHostObject(
|
||||
runtime,
|
||||
std::make_shared<BridgelessNativeModuleProxy>(
|
||||
runtime,
|
||||
std::move(moduleProvider),
|
||||
std::move(legacyModuleProvider),
|
||||
longLivedObjectCollection)));
|
||||
}
|
||||
|
||||
TurboModuleBinding::~TurboModuleBinding() {
|
||||
|
Loading…
Reference in New Issue
Block a user