react-native-dom icon indicating copy to clipboard operation
react-native-dom copied to clipboard

NativeModules bootstrap example

Open peacechen opened this issue 6 years ago • 6 comments

Spectacular work leveraging custom components, web assembly and the gamut of technologies in creating react-native dom 👏

I'm trying this out on our production app which uses a number of native packages such as react-native-device-info. I noticed mention of native modules in the bootstrap file:

const ReactNativeDomOptions = {
  enableHotReload: false,
  nativeModules: []
};

For the time being, I'd like to shim the native modules as empty fillers to get past the first wave of errors. What's the best way to use the nativeModules feature?

peacechen avatar May 18 '18 05:05 peacechen

I just put up the source to the movie demo on github and it uses a basic native module for loading fonts that may be of some guidance.

I'm reluctant to create any concrete documentation on it just yet as it is an aspect of this lib that is going to change fairly soon. It currently uses the deprecated decorators spec and I'm waiting for 1) React Native to officially support Babel 7 and 2) the babel transform for the newer spec to be finished so that I can give bridge decorators a well-deserved overhaul.

vincentriemer avatar May 20 '18 17:05 vincentriemer

Thanks for posting the demo. rn-dom's built-in native modules are also a good reference.

Since I'm not using ES7 decorators, it's been a challenge finding the right equivalent ES6 syntax. I've tried wrapping my native module like this (oversimplified example):

class myClass {
  myNativeClassMember: ...
}

export default RCT_EXPORT_MODULE("myNativeClassName")(myClass)

It's loading into nativeModules, but under an empty string key name. Result looks something like:

{
  "": { myNativeClassMember: ...},
  "RCTAppState": { ... },
  etc...
}

peacechen avatar May 20 '18 21:05 peacechen

After futzing around with desugaring ES7 decorators to ES6, I found this to work:

class myClass {
  constantsToExport() {
    return {
      "someConstant": "someValue",
      // ...
    }
  }
}

RCT_EXPORT_MODULE("myClass")(myClass);

export default myClass;

Initially I had tried exporting the result of RCT_EXPORT_MODULE("myClass")(myClass) which is undefined. The export must be the class itself, not the wrapped version.


Desugaring class methods is even uglier:

import { RCT_EXPORT_MODULE, RCT_EXPORT_METHOD, RCTFunctionTypeNormal, RCTEventEmitter } from "react-native-dom";

class myClass extends RCTEventEmitter {
  myMethod() {}
}

let _myMethod;
_myMethod = RCT_EXPORT_METHOD(RCTFunctionTypeNormal)(myClass.prototype, 'myMethod',
  _myMethod = Object.getOwnPropertyDescriptor(myClass.prototype, 'myMethod')) || _myMethod;
if (_myMethod) Object.defineProperty(myClass.prototype, "myMethod", _myMethod);

RCT_EXPORT_MODULE("myClass")(myClass);

export default myClass;

This was a useful resource https://github.com/wycats/javascript-decorators

peacechen avatar May 21 '18 18:05 peacechen

Yeah that's my bad, I've since pushed out an update that should allow you to do what you did before, but your workaround should also still work.

vincentriemer avatar May 21 '18 19:05 vincentriemer

Thanks @vincentriemer

This now works:

export default RCT_EXPORT_MODULE("myNativeClassName")(myClass)

peacechen avatar May 21 '18 19:05 peacechen

Hey @peacechen, can you please post a detailed example of what you did and how you made it work?

I'm trying real hard to implement a native module for SVG but can't find RCT_EXPORT_MODULE anywhere.

My stack is [email protected] and [email protected]

Update

Turns out there's no need for RCT_EXPORT_MODULE anymore.

dutzi avatar Feb 17 '19 07:02 dutzi