• Stars
    star
    118
  • Rank 299,923 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A safe way to consume React Native NativeModules

react-native-safe-module

A safe way to consume React Native NativeModules

npm Version License Build Status

Motivation

React Native enables a new aspect of mobile development: "Code Push". Code Push provides developers a way to push updates to their JS code base to mobile clients without going through the app store.

Since you can code push to older versions of the native client app, this type of deployment creates a new point of failure though: JavaScript code that is incompatible with the native version of the app it's running on.

React Native JS interacts with the Native code entirely through "Native Modules", which are injected at run-time onto the ReactNative.NativeModules namespace. As a result, having code that interacts with these modules directly can result in run-time errors. This library allows you to more safely interact with native modules, and provide version-specific overrides for the module, as well as mocks to use in the case that the method or module is entirely absent. The result is more robust code that can be code pushed to more users, as well as code that can be tested in an environment without a host app (e.g, Node).

Installation

npm i --save react-native-safe-module

Usage

Importing SafeModule is as simple as:

import SafeModule from 'react-native-safe-module';

Basic Usage

If you were using a Native Module before, such as NativeModules.FooModule like this:

import { NativeModules } from 'react-native';
const { FooModule } = NativeModules;

// ...

FooModule.doSomething().then(...)

You can instead do:

import SafeModule from 'react-native-safe-module';
const FooModule = SafeModule.create({
  moduleName: 'FooModule',
  mock: {
    doSomething: () => Promise.resolve(...),
  },
});

// ...

FooModule.doSomething().then(...)

Version-Specific Overrides

By default, SafeModule assumes that you are exporting a constant VERSION with each Native Module that can be used to identify which version of the native module it is. If you would like to specify the version a different way, you are able to add a getVersion option to the SafeModule configuration which is a function expected to return the correct version of the module.

Often times you may need to make a breaking change to the API of your Native Module, but it can be made backwards compatible with SafeModule very easily.

For example, imagine we have a Scrolling module with a scrollTo(...) method.

In version "7" of the module, the method signature of scrollTo looked something like scrollTo(x: number, y: number, animated: true).

In the latest version of the module, we have changed the method signature to look something like: scrollTo(options: {x: number, y: number, animated: true}).

This is a breaking change, but we can make it backwards compatible with SafeModule:

// Scrolling.js
import SafeModule from 'react-native-safe-module';

module.exports = SafeModule.create({
  moduleName: 'MyCustomScrollingModule',
  mock: {
    scrollTo: () => { /* do nothing */},
  },
  overrides: {
    7: {
      // overrides are defined as higher-order functions which are first
      // called with the real module's method, and are expected to return
      // a new function with the current API.
      scrollTo: oldScrollTo => options => {
        return oldScrollTo(options.x, options.y, !!options.animated);
      },
    },
  },
});

Module Name Changes

Sometimes we want to change the name of a Native Module. In this case, we need to support both versions of the name. SafeModule allows you to specify moduleName as an array of names. It will use the first name it finds.

For example, consider the case where we have a module named FooExperimentalModule, and we want to change the name of it to be just FooModule.

// FooModule.js
import SafeModule from 'react-native-safe-module';

module.exports = SafeModule.create({
  moduleName: ['FooModule', 'FooExperimentalModule'],
  mock: {
    ...
  },
});

In this case, SafeModule will look for FooModule first, and then FooExperimentalModule if it is not found. Finally, it will fall back to the mock implementation if none is found.

API

SafeModule.create(options)

Parameters:

  • options.moduleName: (required, string | Array<string>) the name, or array of names, to look for the module at on the NativeModules namespace.
  • options.mock: (required, mixed) The mock implementation of the native module.
  • options.getVersion: ((module) => string|number) Optional. A function that returns the version of the native module. Only needed if you are specifying overrides and not exporting a VERSION property on your native module. Defaults to x => x.VERSION.
  • options.overrides: ({[version: string]: mixed) Optional. A map of version numbers to overridden implementations of the corresponding property/method. If an overridden property or method is a function, it will be called during SafeModule.create(...) with two arguments, the original value of that property on the original module, and the original module itself. The return value of this function will be put on the return value of SafeModule.create(...).
  • options.isEventEmitter: (bool) Optional. A flag indicating that the native module is expected to be an EventEmitter. Puts the EventEmitter instance on the emitter property of the resulting module. Defaults to false.

TODO

  • Implement onInit lifecycle method
  • Implement onNoModuleFound lifecycle method
  • Implement onVersionFound lifecycle method
  • Implement onOverrideUsed lifecycle method
  • Implement onOverrideCalled lifecycle method

More Repositories

1

react-primitives

Primitive React Interfaces Across Targets
JavaScript
3,085
star
2

redux-pack

Sensible promise handling and middleware for redux
JavaScript
1,333
star
3

react-native-parallax-view

Parallax view for vertical scrollview/listviews with a header image and header content
JavaScript
1,284
star
4

redux-injectable-store

Redux store with injectable reducers for use with bundle splitting, large apps, and SPAs.
JavaScript
230
star
5

react-native-segmented-view

Segmented View for React Native (with animation)
JavaScript
187
star
6

redux-entity

WIP. An abstraction layer around handling normalized entity storage and data fetching with redux
JavaScript
187
star
7

compose-dogfooding

Code written during the Compose Dogfooding streams
Kotlin
183
star
8

react-native-pan-controller

A react native component to help with common use cases for scrolling/panning/etc
JavaScript
181
star
9

recoil

Swift and Kotlin ports of React (Prototype)
Swift
180
star
10

dolla

A light-weight jQuery clone just cuz
JavaScript
140
star
11

enzyme-example-mocha

Example project with React + Enzyme + Mocha
JavaScript
132
star
12

enzyme-example-react-native

Example project with React Native + Enzyme
Objective-C
87
star
13

native-navigation-boilerplate

Objective-C
82
star
14

enzyme-example-karma-webpack

Example project with React + Enzyme + Karma + Webpack
JavaScript
82
star
15

react_native_animation_examples

JavaScript
80
star
16

react-native-in-depth

Courseware and material for a class on React Native
Objective-C
74
star
17

react-native-future

Some thoughts on future directions and APIs for React Native
67
star
18

enzyme-example-jest

Example project with React + Enzyme + Jest
JavaScript
45
star
19

BQL

BQL: A Better Query Language, SQL Superset
C#
43
star
20

react-image-magnifier

A react component that accepts a high-res source image and produces a magnifier window on mouse hover over the part of the image the cursor is over
JavaScript
39
star
21

LukeMapper

Lucene.Net Document to Object ORM Mapper inspired by Dapper
C#
36
star
22

react-validators

Enhanced React Shape PropType Validators
JavaScript
36
star
23

knockout-react

A wrapper / bridge for using React.js with Knockout and Knockout with React.js
JavaScript
25
star
24

gestio

Declarative DOM-Based Gesture Responder System
JavaScript
21
star
25

style-equal

An efficient equality algorithm for React Native inline styles
JavaScript
20
star
26

astrobin-compose

Kotlin
20
star
27

knockout-components

A components library for Knockout.js (3.0 and above)
JavaScript
18
star
28

knockout-paged

Knockout Extension/Plugin for common paged-data scenarios
CSS
16
star
29

knuckles.js

A web application framework built on top of Knockout.js
JavaScript
13
star
30

react-native-animated-navigator

React Native's Navigator implemented with the Animated API
JavaScript
9
star
31

thinking-in-react

Courseware and material for a class on React
JavaScript
9
star
32

understanding-javascript

Courseware and material for a class on JavaScript
JavaScript
9
star
33

knockout-oftype

Some Extensions and Helpers for handling the Constructor pattern in Knockout
JavaScript
8
star
34

react-primitives-art

Cross-platform interface for react ART library
JavaScript
8
star
35

lucene-fluent-query-builder

A convenient Fluent-API around building Lucene.Net queries
C#
7
star
36

shallow-element-equals

Efficient shallow equality algorithm that also allows checks for react element equality of children props
JavaScript
7
star
37

babel-preset-react-native

Babel preset for react native... with a few tweaks
JavaScript
6
star
38

enzyme-example-karma

Example project with React + Enzyme + Karma
JavaScript
5
star
39

react-blogger

minimal isomorphic blog engine built on react
JavaScript
3
star
40

mixinjs

A small library to create factories with useful mixins-based inheritence. Inspired by React's createClass method.
JavaScript
3
star
41

murmur2js

An optimized JavaScript implementation of the MurmurHash algorithm.
JavaScript
3
star
42

MiniBlog

Low-Profile blogging framework built in ASP.Net WebPages Framework
JavaScript
3
star
43

keynote-highlight

Tiny web app to help with syntax highlighting code in keynote
HTML
2
star
44

sivi

Automation Software for Siempre Viva Remote Observatory
C++
2
star
45

lelandrichardson.github.io

Source code for intelligiblebabble.com
JavaScript
2
star
46

viki

Viki - The Visual Wiki Platform
JavaScript
2
star
47

funky.js

A functional programming library for JavaScript
JavaScript
1
star
48

gift-wrap

An asset bundler and minifier (CSS, JS, LESS) for ASP.Net MVC projects
C#
1
star
49

native-navigator

A fully "native" and cross platform Navigator for React Native
Objective-C
1
star
50

leap-gesto

JavaScript Gesture API for Leap Motion
JavaScript
1
star
51

Talks

JavaScript
1
star
52

react-native-windowed-listview

Windowed ListView for React Native (experimental)
1
star
53

module-dep-graph

Automatically track a dependency graph of all commonjs modules in an application
JavaScript
1
star
54

relay-global-immutable-store

playing around with a concept of a global store, similar to Relay, with some offline & eventually-consistent features
JavaScript
1
star