GithubHelp home page GithubHelp logo

staltz / react-native-node Goto Github PK

View Code? Open in Web Editor NEW
1.1K 33.0 33.0 6.5 MB

Run a separate Node.js process behind a React Native app

License: MIT License

Java 67.71% JavaScript 23.55% Python 8.73%

react-native-node's Introduction

React Native Node

Run a real Node.js process in the background, behind a React Native app.

DEPRECATED. Please use Node.js Mobile by Janea Systems instead. It has the same purpose as this library, but is more updated, and supports iOS. This library still works as documented, but I'm not committed to maintaining it anymore.


Using this package you can: run http servers in Android, use Node streams, interface with the filesystem, off load some heavy processing out of the JS thread in React Native, and more! Running the real Node.js in Android, you can do everything that Node.js on desktop can.

Example app

Install

npm install --save react-native-node
react-native link react-native-node

Usage

  1. Develop the background Node.js project under some directory

    • e.g. ./background
  2. In your React Native JavaScript source files, spawn the background process:

+import RNNode from "react-native-node";

 class MyApp extends Component {
   // ...
   componentDidMount() {
+    RNNode.start();
+    // or specify arguments to the process:
+    RNNode.start(['--color', 'red', '--port', '3000'])
   }

   componentWillUnmount() {
+    RNNode.stop();
   }
   // ...
 }
  1. Bundle and insert the background application into the mobile app using the command
./node_modules/.bin/react-native-node insert ./background
  • Compresses your background app into ./android/app/src/main/res/raw/rnnodebundle
  • Updates AndroidManifest.xml to include a Service class
  1. (Re)build the mobile app
react-native run-android

Tip 1

If you want to bundle and insert the background app always before building the mobile app, make a prestart package.json script (assuming you use the start script):

 "scripts": {
+  "prestart": "react-native-node insert ./background",
   "start": "node node_modules/react-native/local-cli/cli.js start",

Tip 2

You can reduce the size of the bundle file rnnodebundle by using a tool like noderify to create a single js file.

Tip 3

To debug, use adb logcat with the nodejs tag. For example with react:

adb logcat *:S nodejs:V ReactNative:V ReactNativeJS:V

These additional logging tags are used by react-native-node:

  • RNNodeThread - will tell you if your process has started/terminated/errored
  • RNNodeService - debug tar/untar, node binary preparation etc.
  • RNNode

FAQ

How is this possible?

Node.js v7.1.0 (with V8, not JavaScriptCore) was compiled to a binary bin_node_v710 following the approach used by "NodeBase". This binary is prebuilt and included in this library. If you are concerned about security, you shouldn't use the prebuilt binary, but compile it yourself.

What about iOS support?

We can't run V8 Node.js on iOS since that violates Apple's policy around Just-In-Time compilation, but ChakraCore Node.js can run on iOS. We are depending on this project by Janea Systems to open source their methods and include a proper open source license.

Does it support packages with native bindings?

Yes, in theory, but that's the job of individual libraries having native bindings for android. Most packages don't have. I believe sodium-native has. Hint: if you want to compile the native part of packages, I recommend not trying to cross-compile. Instead, install termux on an Android device and compile from the phone directly.

Why did you build this?

I am bringing the Scuttlebutt ecosystem to mobile, and I built the package react-native-scuttlebot which uses this tool as dependency. These are in turn used by the mobile app project mmmmm.

react-native-node's People

Contributors

jsdario avatar soyuka avatar staltz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-node's Issues

Weird behavior with livereload

This needs a more thorough investigation.

  1. Followed the readme, added this on a "already built app" (ie run-android ran at least once before)
  2. Had issue with cannot require index.js`
  3. Removed app (uninstall), run-android, put live reload back and node app was terminated right when launched
  4. Removed again (uninstall), now it's fine can run http server and request

I think that there's something going on when I launch run-android a second time, the node app isn't updated?
I'll let you know if I can reproduce this or improve DX somehow.

Run on Android 4.4.2 error

error info:

CANNOT LINK EXECUTABLE: cannot locate symbol "sigfillset" referenced by "/data/data/com.XXXXX.XXXX

Bundle again on app reload

Hello,
is there some way to run react-native-node insert ./background on app reload? Because as things stand I have to test my code in a separate project before using it in the background folder.

It's not an issue per se, but a substantial improvement that could be made.

Thank you.

And please continue working on IOS support, I tested nodejs-mobile and it's just bad... (awfully slow)

Bunch'o questions

Hi I'm really amazed by the project.

Anyways:

  • Can it run child processes?
  • Can it execute another process as node too?

I know this isn't stackoverflow but I'm really clueless about the posaibility, or if so, how.

Thank you.

Approaches to running Node on Android

Hi,

This is just a FYI, feel free to close.

I just found your project after I created a SO question on pro's / con's of different approaches: : Compiling NodeJS as native library on Android

I am not familiar to the native linking, compiling techniques in bringing Node to android, so find it hard to choose between options, but your project looks like it is exactly what I am looking for! Thank you.

PS I updated the SO question with react-native-node link.

method does not override or implement a method from a supertype Error

While using this library for a simple fs.readFile method in ./background, I am getting this error while building the project. I followed all the instruction.

C:\path\to\project\node_modules\react-native-node\android\src\main\java\com\staltz\reactnativenode\RNNodePackage.java:23: error: method does not overr
ide or implement a method from a supertype
    @Override                                                  
    ^
1 error
:react-native-node:compileReleaseJavaWithJavac FAILED

Project specs

"react": "^16.0.0-alpha.12",
"react-native": "^0.47.1",
"react-native-node": "^1.1.2"

Any clue ?

NodeJS doesn't rebuild with new insert

I'm running a simple express server like the example, and it works. But after changing the nodejs server and rebuilding with cd server && npm i && cd .. && react-native-node insert ./server the changes don't take effect any more.

I've tried deleting node_modules on both the nodejs and the react-native apps, tried deleting the rnbundle that gets saved to the raw folder. Nothing changes the express app once it's been built for the first time.

package com.staltz.reactnativenode does not exist

Hi there,

I've followed the readme and have applied what has been told, but build fails everytime.

android\build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
        classpath 'com.google.gms:google-services:3.1.2'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        maven {
            url 'https://maven.google.com'
        }
    }
}

app\build.gradle

...
def enableProguardInReleaseBuilds = false
android {
    compileSdkVersion 25
    buildToolsVersion '26.0.2'

    defaultConfig {
        applicationId "com.heartfailure"
        minSdkVersion 16
        multiDexEnabled true
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
        ndk {
            abiFilters "armeabi-v7a", "x86"
        }
    }
...
    buildTypes {
        release {
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
...
}

dependencies {
    compile(project(':react-native-firebase')) {
        transitive = false
    }
    compile project(':react-native-config')
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:25.2.0"
    compile "com.facebook.react:react-native:+"  // From node_modules
    compile "com.google.android.gms:play-services-base:11.6.0"
    compile "com.google.firebase:firebase-core:11.6.0"
    compile "com.google.firebase:firebase-database:11.6.0"
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

apply plugin: 'com.google.gms.google-services'

MainApplication.java

package com.heartfailure;
import com.staltz.reactnativenode.RNNodePackage;
...

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
            new RNNodePackage(),
        new ReactNativeConfigPackage(),
        new RNFirebasePackage(),
        new RNFirebaseDatabasePackage()
      );
    }

Error

\MyApp\android\app\src\main\java\com\heartfailure\MainApplication.java:6: error: package com.staltz.reactnativenode does not exist
import com.staltz.reactnativenode.RNNodePackage;
                                 ^
C:\King's_College_London\Final_Year_Project\HeartFailure\android\app\src\main\java\com\heartfailure\MainApplication.java:29: error: cannot find symbol
            new RNNodePackage(),
                ^
  symbol: class RNNodePackage
2 errors


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

BUILD FAILED in 23s
68 actionable tasks: 65 executed, 3 up-to-date

Running example code results in network error at RN fetch()

First of all: Thanks for this project!

I am checking out the /example code and when running as described in the README and without modifications I get following error:

TypeError: Network request failed
    at XMLHttpRequest.xhr.onerror (fetch.js:441)
    at XMLHttpRequest.dispatchEvent (event-target.js:172)
    at XMLHttpRequest.setReadyState (XMLHttpRequest.js:546)
    at XMLHttpRequest.__didCompleteResponse (XMLHttpRequest.js:381)
    at XMLHttpRequest.js:485
    at RCTDeviceEventEmitter.emit (EventEmitter.js:181)
    at MessageQueue.__callFunction (MessageQueue.js:260)
    at MessageQueue.js:101
    at MessageQueue.__guard (MessageQueue.js:228)
    at MessageQueue.callFunctionReturnFlushedQueue (MessageQueue.js:100)

I will look into this further, but maybe there is something obvious I am overlooking..

(Versions: yarn 0.24.6, npm 4.2.0, ubuntu 16.04, (local) node: 7.10.1)

PS I will try again with downgraded node on ubuntu system

Running timers on server

Hello again,
I am trying to run a timer on the server that executes a certain function every x seconds.
Something like:

setTimeout(function() {
  // work
}, delay);

and notifies the main thread each time. However, seeing as the server in your example relies on Express, each request receives an answer once, and I have to fetch the URL again to execute it, and I'm kinda reluctant here as every bit of performance is crucial in this particular project.

What I'm aiming at really is something along the lines of a Worker, something like:

worker.onmessage = message => {
  switch(message) {
    case 'periodicAction':
    // Execute a function, return the result
    worker.postMessage('My result')
    default
    worker.postMessage('Do nothing...')
  }
};

What I'm getting at really is: Is there a way to get rid of Express and replace the node thread with a fullblown worker?
And if not, is there some way to have it perform some kind of task periodically and notify the main thread when it's done each time? Something like:

RNNode.sendMessage('a message')

I apologize for creating an issue, as this is not really one
Again, thank you

es7 support

Hello,
Is there some way to add es7 support to the background folder? Porting code from other projects that rely of async/await is proving challenging

Considerations for choosing NodeBase instead of J2V8?

This is a follow-up to #2

For my stackoverflow question on 4 possible solutions, I receive an answer from the NodeBase creator, basically stating that his project is a 'plaything' and J2V8 the best approach.

To me J2V8 (created by @irbull) looks like the most stable implementation currently, leading to my question: Why did you opt for NodeBase?

It seems to me with J2V8 you'd gain:

  • a much more active project
  • support for newer Node versions (currently 7.6.0, but 8.x just PR'ed)
  • additional features:
    • 2-way js-to-java bridge (call java from script and vice versa)
    • 2-way integrated error / exception handling
    • chrome debugging support
    • full build environment with docker-based cross-compile for unix, mac, windows and android
    • more smaller stuff ...

Unclear FAQ explanation on compiling native libraries

The README at the FAQ section has some text I do not fully understand:

Does it support packages with native bindings?

Yes, in theory, but that's the job of individual libraries having native bindings for android. Most packages don't have. I believe sodium-native has. Hint: if you want to compile the native part of packages, I recommend not trying to cross-compile. Instead, install termux on an Android device and compile from the phone directly.

I assume you mean node packages having native libraries, that require extra care to include. And not the native Java in react-native Gradle projects?

So not these kind of projects in the settings.gradle:

include ':react-native-maps'
project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/android')
include ':react-native-randombytes'
project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android')
include ':react-native-i18n'
project(':react-native-i18n').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-i18n/android')

It would be nice if there was an example that e.g. included the native parts of sodium-native as a demonstration of how to bundle / use that in a project (besides compiling it). Apart from that an explanation or pointer to more compilation instruction would be great.

PS I am looking into node-as-native-libray projects to avoid having to use termux. You can't offer that to end-users. But it is just needed for compilation purposes, not for installing app, right?

Thanks!

nodejs-mobile

This project links to a couple other projects at the top of the readme, but there's no mention of nodejs-mobile which at first glance appears to do the same thing but also for ios?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.