8

I want to use node js as a backend in react native project .

Vinit Mehta
  • 449
  • 4
  • 13
  • If you have in mind to build a WebService, you can do everything because Your App and its backend will communicate through http... – Hitmands Nov 16 '16 at 10:37
  • Thanks for reply , please look into this link(http://www.w3resource.com/node.js/nodejs-sqlite.php) I want exactly same but in react native. – Vinit Mehta Nov 16 '16 at 10:41
  • I don't want to go with separate code for web services, I want to use node js code in react native project. so it is possible? – Vinit Mehta Nov 16 '16 at 10:44

2 Answers2

4

The ReactNativify Github project does/did* just this, add a NodeJS runtime into React-Native (RN) projects.

*currently not working in RN v0.43.3 onwards, April 2017.

Also see (as of May 2018):

Big Rich
  • 5,864
  • 1
  • 40
  • 64
  • The nodejs-mobile-react-native seems to be the best approach today, it embbeds a nodejs runtime into a React-Native app as said. – Juanpa Jul 06 '19 at 20:53
4

Yes you can use packages written for Node by using ReactNativify as Big Rich rightfully states. Some things to consider though:

1) I followed the advice I found in the issue list and split up transformer.js in 2 parts:

transformers.js (in /config and invoked from rn-cli.config.js):

const babelTransformer = require('./babel-transformer');

module.exports.transform = function(src, filename, options) {

    const extension = String(filename.slice(filename.lastIndexOf('.')));
    let result;

    try {

    result = babelTransformer(src, filename);

    } catch (e) {

    throw new Error(e);
    return;
    }

    return {
    ast: result.ast,
    code: result.code,
    map: result.map,
    filename
    };
};

babel-transformer.js (also in /config):

'use strict'

const babel = require('babel-core');

/**
 * This is your `.babelrc` equivalent.
 */
const babelRC = {
    presets: ['react-native'],
    plugins: [

    // The following plugin will rewrite imports. Reimplementations of node
    // libraries such as `assert`, `buffer`, etc. will be picked up
    // automatically by the React Native packager.  All other built-in node
    // libraries get rewritten to their browserify counterpart.

    [require('babel-plugin-rewrite-require'), {
        aliases: {
            constants: 'constants-browserify',
            crypto: 'react-native-crypto',
            dns: 'mock/dns',
            domain: 'domain-browser',
            fs: 'mock/empty',
            http: 'stream-http',
            https: 'https-browserify',
            net: 'mock/net',
            os: 'os-browserify/browser',
            path: 'path-browserify',
            pbkdf2: 'react-native-pbkdf2-shim',
            process: 'process/browser',
            querystring: 'querystring-es3',
            stream: 'stream-browserify',
            _stream_duplex: 'readable-stream/duplex',
            _stream_passthrough: 'readable-stream/passthrough',
            _stream_readable: 'readable-stream/readable',
            _stream_transform: 'readable-stream/transform',
            _stream_writable: 'readable-stream/writable',
            sys: 'util',
            timers: 'timers-browserify',
            tls: 'mock/tls',
            tty: 'tty-browserify',
            vm: 'vm-browserify',
            zlib: 'browserify-zlib'
        },
        throwForNonStringLiteral: true
    }],

    // Instead of the above you could also do the rewriting like this:

    ["module-resolver", {
      "alias": {
        "mock": "./config/mock",
        "sodium-universal": "libsodium"
      }
    }]
    ]
};

module.exports = (src, filename) => {

    const babelConfig = Object.assign({}, babelRC, {
    filename,
    sourceFileName: filename
    });

    const result = babel.transform(src, babelConfig);
    return {
    ast: result.ast,
    code: result.code,
    map: result.map,
    filename
    };
}

2) As you can see in the code above, I also demonstrated using the babel-plugin-module-resolver.

Note, I will use this plugin instead of the one ReactNative uses. It allows you to reference local files, and written with proper quotes allows non-JS-compliant names like 'sodium-universal'

Note2 Or go for .babelrc solution (maybe cleanest) as outlined in this comment: https://github.com/philikon/ReactNativify/issues/4#issuecomment-312136794

3) I found that I still needed a .babelrc in the root of my project to make my Jest tests work. See this issue for details: https://github.com/philikon/ReactNativify/issues/8

Arnold Schrijver
  • 3,588
  • 3
  • 36
  • 65
  • PS The packages I was trying to port where heavily Node-bound, so I am now also investigating a different approach: [Compiling NodeJS as native library on Android](https://stackoverflow.com/q/45459909/8295283) – Arnold Schrijver Aug 03 '17 at 12:52
  • @ArnoldSchrijver Thanks for the summary, I tried to adopt your approach, but I get `error: bundling failed: TypeError: Cannot read property 'slice' of undefined` in transform.js. Specifically `const extension = String(filename.slice(filename.lastIndexOf('.')));` Any reason why? – S. Nas Jan 24 '18 at 19:57
  • Not sure @S.Nas why your `filename` is undefined.. either an issue in your code, or change in babel stuffz.. afraid I can't help. – Arnold Schrijver Jan 25 '18 at 11:39