philikon / ReactNativify

How to use node.js libraries in React Native
242 stars 23 forks source link

Maximum call stack exceeded when importing a node module #14

Open bitabs opened 6 years ago

bitabs commented 6 years ago

I'd like to import openbci-cyton module into my react native project. When I do so, it leads to

Maximum call stack size exceeded

I'm using ignite template. I call ReactNativeExamples in `App/containers/LaunchScreen.js

import ReactNativeExamples from "../../rn";

And heres the following files:

transformers.js

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

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

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

  try {

    switch (extension) {

      case '.js':
      case '.jsx':
        result = babelTransformer(src, filename);
        break;

      default:
        result = babelTransformer(src, filename);
        break;
    }

  } catch (e) {

    throw new Error(e);       // <== prints the error at the this line for openbci module
    return;
  }

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

babal-transformer.js

'use strict'

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

/**
 * This is your `.babelrc` equivalent.
 */
const babelRC = {
  presets: [require('babel-preset-react-native')],
  "sourceMaps": true,
  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: 'crypto-browserify',
        dns: 'node-libs-browser/mock/dns',
        domain: 'domain-browser',
        fs: 'node-libs-browser/mock/empty',
        http: 'stream-http',
        https: 'https-browserify',
        net: 'node-libs-browser/mock/net',
        os: 'os-browserify/browser',
        path: 'path-browserify',
        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: 'node-libs-browser/mock/tls',
        tty: 'tty-browserify',
        vm: 'vm-browserify',
        zlib: 'browserify-zlib',
        'openbci-cyton': 'openbci-cyton',        // <=== The node module that I want to use

        // You can add your own, much like webpack aliases:
        'corporate-lib': 'corporate-lib-react-native',

        // You can also mock any libraries that you don't need to support on
        // React Native, but have to be present for 3rd party code to work:
        'some-third-party-dependency': 'node-libs-browser/mock/empty',
      },
      throwForNonStringLiteral: true
    }]
  ]
};

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
  };
}

node.js

const cytonExample = require('./cyton_example');
process.on('exit', () => undefined);

Promise.all([
  cytonExample()
]).then(([cyton]) => {
  console.log('cyton: ' + cyton );
});

cyton_example.js

'use strict';
const Cyton = require('openbci-cyton');     // <== Error will start if this line is added
module.exports = function example() {
  return new Promise((resolve) => {
    process.nextTick(() => {
      let ourBoard = new Cyton();
      resolve(ourBoard.listPorts());
    });
  });
};

And here's the full error:

capture
bitabs commented 6 years ago

Ok, I so inserted console.log() in transformers.js just before the switch statement:

  try {

    console.log(extension);

    switch (extension) {

      case '.js':
      case '.jsx':
        result = babelTransformer(src, filename);
        break;

      default:
        result = babelTransformer(src, filename);
        break;
    }

  } catch (e) {

    throw new Error(e);
    return;
  }

Then When I did react-native run-android, it started printing continuously:

transform[stdout]: .js
transform[stdout]: .js
transform[stdout]: .js
transform[stdout]: .js
transform[stdout]: .js
transform[stdout]: .js
transform[stdout]: .js
transform[stdout]: .js
transform[stdout]: .js

and at one stage, it printed the following:

capture

Any ideas? @philikon @aschrijver

aschrijver commented 6 years ago

@NaseebullahSafi sorry, can't help you.. i had too many issues with nativifying my large nodejs project.. no longer using it.

instead running node on android directly on mobile in background thread, and react-native frontend ui :)

bitabs commented 6 years ago

Ah I see, It's OK.

I'm kind of desperate at the moment, is there any tutorial on how to do it directly in android in the background thread? @aschrijver

bitabs commented 6 years ago

As in, what framework might you be using to host the nodejs in Android? and how do you link your nodejs in android to your react native? I'd really appreciate if you could create a README for this because the demand is actually high. @aschrijver

aschrijver commented 6 years ago

I can give you some pointers. It has been some time ago that I was using this. Also running NodeJS on Android should be considered very experimental (and very interesting :D).

First on ReactNativify I wrote a number of SO questions + answers:

I don't know if there is anything there for you.. you should investigate :)

Then on running NodeJS on Android I wrote this article, that provides a summary of options.. the README :)

bitabs commented 6 years ago

This is such a big problem, because the reason why I need nodejs (or if there is an alternative) is so that I can be able to transfer data from a microcontroller to an android device.