Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potentially Path issues #16

Open
dittmarconsulting opened this issue Mar 30, 2022 · 6 comments
Open

Potentially Path issues #16

dittmarconsulting opened this issue Mar 30, 2022 · 6 comments

Comments

@dittmarconsulting
Copy link

dittmarconsulting commented Mar 30, 2022

Hi all,

I have used this package before and it worked like a treat. Thanks for maintaining this repo. 🙏

Right now I'm using this package in a mono-repo with the following file structure

mono-repo
|- packages
|   |- nodetestapp (RN)
|   |   |- android
|   |   |- ios
|   |   |- nodejs-assets
|   |   |   |- nodejs-project
|   |   |       |- nodejs-project
|   |   |          |- main.js
|   |   |          |- package.json
|   |   |          |- node_modules
|   |   |- src (all the RN stuff)
|   |   |- index.js
|   |- web
|- node_modules

and I'm using that setup

node: v16.14.2
react: 17.0.2
react-native: 0.67.0
nodejs-mobile-react-native: 0.8.0

I have updated all the paths to the node_modules in the script files in the Build Phases and everything builds and runs fine in ios (I'm not worried about Android yet)

My entry component looks like that. Very basic for testing:

import React, { ReactElement, useEffect } from 'react';
import { View, Text } from 'react-native';
import nodejs from 'nodejs-mobile-react-native';

const App = (): ReactElement => {
  useEffect(() => {
    nodejs.start('main.js');
  });

  return <View><Text>App</Text></View>;
};

export default App;

When I run the app without the line nodejs.start('main.js'); I have no errors and I can see the App text on the screen but as soon as I run it with the above command, I can see this error in XCode.

2022-03-30 15:43:44.589685+1100 nodetestapp[24155:2166769] [javascript] Invariant Violation: Module HMRClient is not a registered callable module (calling setup). A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
2022-03-30 15:43:44.591609+1100 nodetestapp[24155:2166769] [javascript] Invariant Violation: No callback found with cbID 2 and callID 1 for module <unknown>. Args: '[{"app_state":"active"}]'
2022-03-30 15:43:44.592940+1100 nodetestapp[24155:2166769] [javascript] Invariant Violation: Module RCTDeviceEventEmitter is not a registered callable module (calling emit). A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
2022-03-30 15:43:44.593771+1100 nodetestapp[24155:2166769] [javascript] Invariant Violation: Module RCTLog is not a registered callable module (calling logIfNoNativeHook). A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
2022-03-30 15:43:44.595324+1100 nodetestapp[24155:2166769] [javascript] Invariant Violation: Module AppRegistry is not a registered callable module (calling runApplication). A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.

Any hint on how I can resolve this problem would be much appreciated. Perhaps a path that is somehow hardcoded that would prevent me to run this app in a mono-repo or something?

Cheers

@dittmarconsulting dittmarconsulting changed the title Potentially Hermes issues Potentially Path issues Mar 30, 2022
@dittmarconsulting
Copy link
Author

dittmarconsulting commented Mar 30, 2022

I can confirm that is a path issue. I just created a fresh app with this setup

|- nodetestapp (RN)
   |- android
   |- ios
   |- nodejs-assets
   |   |- nodejs-project
   |       |- nodejs-project
   |          |- main.js
   |          |- package.json
   |          |- node_modules
   |- src (all the RN stuff)
   |- index.js
   |- node_modules

and it works as expected as the node_modules folder is inside the RM app.

Unfortunately, I have to get it to work in a yarn workspaces (aka mono-repo) environment.

@staltz
Copy link
Member

staltz commented Mar 30, 2022

@dittmarconsulting Thanks for the thorough report with details. It seems indeed that it is a configuration issue involving yarn, metro (the bundler React Native uses) and potentially other tools. I don't see this as being specific to nodejs-mobile-react-native

@dittmarconsulting
Copy link
Author

Thanks for the fast reply @staltz

I tried to log out some paths from the RNNodeJsMobile.m file.

I could see that the method file was indeed invoked with the working app and it printed out the paths but for the RN app in the mono-repo, this file didn't even run nor did the index.js file at the root of the RN app.

It seems the pre-compiler doesn't even start metro if the nodejs object is present in the code.

@dittmarconsulting
Copy link
Author

dittmarconsulting commented Mar 31, 2022

UPDATE

I found the culprit for the compiler error. I always used @carimus/metro-symlinked-deps in all my mono-repos to link to other projects within the packages folder.

Once I removed that I can run the RN app in the mono-repo with this metro setup

const path = require('path');

const extraNodeModules = {
  'react-native': path.resolve(__dirname, '../../node_modules/react-native'),
  src: path.resolve(__dirname, '../../node_modules/'),
};

module.exports = {
  projectRoot: __dirname,
  watchFolders: [path.resolve(__dirname, '../../node_modules')],
  transformer: {
    sourceExts: ['.native.ts', '.native.tsx', '.ts', '.tsx', '.js'],
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
  resolver: {
    extraNodeModules: new Proxy(extraNodeModules, {
      get: (target, name) =>
        name in target
          ? target[name]
          : path.join(process.cwd(), `node_modules/${name}`),
    }),
  },
};

But there is one thing I don't understand and maybe you can help me to figure it out.

I added a console.log in the start function of this file node_modules/nodejs-mobile-react-native/index.js and I can see that this function gets invoked and the log is been printed to the console.

Then I logged out the nodejsThread at the end of the method startNodeProject of the file RNNodeJsMobile.mm and I get this output

<NSThread: 0x6000021d9a40>{number = 11, name = main}

I assume the thread is running now. The startNodeProject method will invoke the startEngineWithArguments method of the file NodeRunner.mm, which it does. I have been logging the node path and I get this output

/Users/td/Library/Developer/CoreSimulator/Devices/6C445AA9-17C1-403B-93A7-03C76404D79E/data/Containers/Bundle/Application/8775A9CD-F2F2-4AF4-9950-A63D548E2978/nodetestapp.app/nodejs-project:/Users/td/Library/Developer/CoreSimulator/Devices/6C445AA9-17C1-403B-93A7-03C76404D79E/data/Containers/Bundle/Application/8775A9CD-F2F2-4AF4-9950-A63D548E2978/iotnative.app/builtin_modules

I believe though, the node_start function at the end of the startEngineWithArguments doesn't get invoked but I can't test that as this function has been bundled within a Framework.

//Start node, with argc and argv.
node_start(argument_count, argv);

@staltz Do you have a clue what else I can do?

@dittmarconsulting
Copy link
Author

dittmarconsulting commented Apr 2, 2022

UPDATE 2

This is crazy. The entire time I thought NODE is not working as I didn't get any events back from the main.js file.

The fact is, I just send an IoT message and it worked. That means I can successfully send a msg from RN to main.js like that

import nodejs from 'nodejs-mobile-react-native';

nodejs.channel.post('some-listener-name', someData);

but any event sent from the main.js back to RN doesn't come through. 🤯

I tried rn_bridge.channel.send('some msg') or rn_bridge.channel.post('some-listener-name', 'some msg');

Maybe that is something you might help me with? @staltz

@dittmarconsulting
Copy link
Author

dittmarconsulting commented Apr 2, 2022

UPDATE 3

I tried to add the NativeAppEventEmitter directly into my RN app and it works

NativeAppEventEmitter.addListener('nodejs-mobile-react-native-message', e => {
  console.log('Data received !!!!', e);
});

So, for some reason, the nodejs.channel.addListener() doesn't pick up the events in a mono-repo environment. 🤯🤯🤯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants