Search code examples
reactjsreact-nativereact-navigationreact-navigation-stack

Unable to resolve module from 'index.js' for custom component


I'm kinda new to react-native and I'm currently trying to add a stack-navigator to my app:

// import React from 'react';
import {Text, View, AppRegistry} from 'react-native';
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';

// class HomeScreen extends React.Component {
//   static navigationOptions = {
//     title: 'Welcome',
//   };
//   render() {
//     return (
//       <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
//         <Text>Home Screen</Text>
//       </View>
//     );
//   }
// }

const MainNavigator = createStackNavigator({
  Home: {screen: HomeScreen}
}, {
  initialRouteName: 'Home'
})

const NavigationApp = createAppContainer(MainNavigator);

AppRegistry.registerComponent('ReactNativeApp', () => NavigationApp)

export default NavigationApp

If I uncomment the commented code in the above example, everything works fine, now I'm trying to move the HomeScreen component to its own file so I tried this:

HomeScreen.js

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>Home Screen</Text>
      </View>
    );
  }
}

index.js

import HomeScreen from './components'
import {AppRegistry} from 'react-native';
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';

const MainNavigator = createStackNavigator({
  Home: {screen: HomeScreen}
}, {
  initialRouteName: 'Home'
})

const NavigationApp = createAppContainer(MainNavigator);

AppRegistry.registerComponent('ReactNativeApp', () => NavigationApp)

export default NavigationApp

But I keep getting this error:

error: bundling failed: Error: Unable to resolve module `./components` from `index.js`: 

None of these files exist:
  * components(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
  * components/index(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
    at ModuleResolver.resolveDependency (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:163:15)
    at ResolutionRequest.resolveDependency (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:52:18)
    at DependencyGraph.resolveDependency (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/node-haste/DependencyGraph.js:282:16)
    at Object.resolve (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/lib/transformHelpers.js:267:42)
    at /Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:426:31
    at Array.map (<anonymous>)
    at resolveDependencies (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:423:18)
    at /Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:275:33
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (/Users/myuser/git/POC/ReactNativeApp/ReactNativeApp/node_modules/metro/src/DeltaBundler/traverseDependencies.js:87:24)

In the past I've been able to import them the same way as I did, but somehow react-navigation is giving me problems with it.

The folder structure that I have is as follows:

/
    index.js
    components/
        HomeScreen.js

I have seen similar questions but all of them involved third-party components from react but not ones made by oneself.

I have tried to npm start --reset-cache as suggested in this answer

I'm using these versions if it matters.

react-native-cli: 2.0.1
react-native: 0.61.2

How to fix this error?


After following @Vencovsky proposed solution (with and without .js extension):

import HomeScreen from './components/HomeScreen.js'

I get this new error:

The component for route 'Home' must be a React component. For example:

import MyScreen from './MyScreen';
...
Home: MyScreen,
}

You can also use a navigator:

import MyNavigator from './MyNavigator';
...
Home: MyNavigator,
}

The way I'm calling this React app is through a Swift bridge in this way:

import Foundation
import UIKit
import React

class ButtonController: UIViewController  {
    @IBOutlet weak var button: UIButton!

    @IBAction func buttonClicked(_ sender: Any) {
        if let jsBundleLocation = URL(string: "http://X.X.X.X:8081/index.bundle?platform=ios") {
            //The data is used as initialProperties to React Native App.
            let data:NSDictionary = ["onNavigationStateChange": "{handleNavigationChange}",
                                     "uriPrefix":"/app"]; //We can use this parameter to pass the data to the React native App from the Native App.
            //The RCTRootView is a native view used to host React-managed views within the app. Can be used just like any ordinary UIView.
            let rootView = RCTRootView(
                bundleURL: jsBundleLocation,
                moduleName: "ReactNativeApp",
                initialProperties: data as [NSObject : AnyObject],
                launchOptions: nil)
            let viewController = UIViewController()
            viewController.view = rootView
            self.present(viewController, animated: true, completion: nil)
        }
    }
}

Solution

  • You need to import it as

    import HomeScreen from './components/HomeScreen.js'
    

    If you only import it as './components', it will try to get ./components.js or ./components/index.js (and the same but with other extensions), but you don't have any of that.

    And if you take a look at the error, it says it tried to get these files but didn't find.

    None of these files exist:
      * components(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
      * components/index(.native|.ios.js|.native.js|.js|.ios.json|.native.json|.json|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx)
    

    First line with * - Trying to get ./components.js and other extensions
    Second line with * - Trying to get ./components/index.js and other extensions