bozzmob
bozzmob

Reputation: 12574

How to allow react-native to enable support for JSX (extension) files

React Native app fails to resolve components.

I am trying to import & render Test.jsx inside of App.js.

I get the following error-

error: bundling failed: Error: Unable to resolve module `./screens/Test` from App.js`:
The module `./screens/Test` could not be found from App.js. Indeed, none of these files exist

Project Manager(or rather files) look like this-

Files

Code of Test.js-

import React, { Component } from 'react';
import {View, Text, StyleSheet} from 'react-native'

export default class Test extends Component {
    render() {
      return (
        <View style={styles.container}>
          <Text>Hello World?</Text>
        </View>
      );
    }
  }


const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  }
});

Code of App.js-

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View
} from 'react-native';

import Test from "./screens/Test";

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
  android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

type Props = {};
export default class App extends Component<Props> {
  render() {
    return (
      <View style={styles.container}>
        <Test />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

I've literally tried every solution mentioned - react-native#4968 and none of them seem to work. I've also referred to this, but, the solution is for css and nowhere close to what would fix this issue.

I've looked at lot more issues and SO's with no clue what else I have to do. I've also created a new project(screenshot and code is from the new project).

What am I missing?

UPDATE: I realised that the issue was because I have .jsx extension. Imports are working fine for .js file. Any pointers on how to enable the project to accept .jsx for imports?

Upvotes: 29

Views: 24594

Answers (5)

Shivam
Shivam

Reputation: 851

If someone doesn't want to load the default config and spread it, then they can simply use this

In metro.config.js

module.exports = {
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
  resolver: {
    sourceExts: [
      'js', // note this has to be defined first or you get an error
      'json',
      'jsx',
      'mjs',
      // required because the react-native cli ignores `resolverMainFields`
      'ts',
      'tsx',
    ],
  },
};

Upvotes: 5

tobius
tobius

Reputation: 855

This works in ReactNative v0.63

// metro.config.js
const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
  const { resolver: { sourceExts } } = await getDefaultConfig();
  return { resolver: { sourceExts: [...sourceExts, 'jsx'] } };
})();

Note: This approach will not overwrite existing settings.

Upvotes: 4

aravind_reddy
aravind_reddy

Reputation: 5466

update: for RN >0.59 as @RedGaint pointed in https://stackoverflow.com/a/55134051/8034782 you need to configure metro.config.js in the root level.

  module.exports = {
  resolver: {
    /* resolver options */
   sourceExts: ['jsx','js'] //add here 
  },
  transformer: {
    /* transformer options */
  },
  serializer: {
    /* serializer options */
  },
  server: {
    /* server options */
  }

  /* general options */
};

For RN < 0.57: Inside of the root of your project add a file named rn-cli.config.js and place the following code into it.

// ./rn-cli.config.js
module.exports = {
  /// @description Allows you to enable support for JSX files
  /// The `index.js` file in the root of your project has to be `.js`. 
  getSourceExts: () => [ 'jsx', 'js' ],
}

For RN > 0.57:

  module.exports = {
  resolver: {
    sourceExts: ['jsx', 'js'],
    },
  };

for more reference look into this there is already an issue opened:

https://github.com/facebook/react-native/pull/5233#issuecomment-382083236

Upvotes: 48

RedGiant
RedGiant

Reputation: 4748

I am using react-native 0.59 and metro-react-native-babel-preset": "^0.53.0",.

The ./rn-cli.config.js file no longer works in the IOS release build. RN 0.59 requires a config file called metro.config.js in the root level. I have to use it to enable JSX support instead of rn-cli.config.js. Check out the documentation for the config file: https://facebook.github.io/metro/docs/en/configuration.html

/**
 * Metro configuration for React Native
 * https://github.com/facebook/react-native
 *
 * @format
 */

module.exports = {
    transformer: {
        getTransformOptions: async () => ({
            transform: {
                experimentalImportSupport: false,
                inlineRequires: false,
            },
        }),
    },
    resolver: {
        sourceExts: ['jsx','js', 'json', 'ts', 'tsx']
    }
};

Upvotes: 26

quboo
quboo

Reputation: 61

It seems that the config schema was changed in 0.57 version: #248

Try this:

// ./rn-cli.config.js
module.exports = {
  resolver: {
    sourceExts: ['jsx', 'js'],
  },
};

Upvotes: 6

Related Questions