DEV Community

Cover image for How to Import Files from Outside of Root directory in React Native
Dan Petre
Dan Petre

Posted on

How to Import Files from Outside of Root directory in React Native

Many projects do not use a specific tool to manage multiple packages from the same repository, and this is not necessarily a problem. However, one of the trickiest issues in medium to large react-native projects is importing files outside of the root directory with Metro Bundler.

In fact, even in the React Native official documentation, you will not find a solution for this.

Consider the following project structure:

root
node_modules
src
  -- components
  -- views
  -- theme
  -- …others
web
  -- node_modules
  -- index.js
  -- …others
native
  -- node_modules
  -- android
  -- ios
  -- index.js
  -- App.jsx
  -- metro.config.js
  -- babel.config.js
  -- …others
Enter fullscreen mode Exit fullscreen mode

This project uses react-native-web, so the code can be developed once and then run on web, iOS, and Android.

Let’s say you have an Example component in src.

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

export const Example = () => {
 return (
   <View style={style.container}>
     <Text style={style.title}>Hello from Root: /src</Text>
   </View>
 );
};

const style = StyleSheet.create({
 container: {
   alignItems: 'center',
   backgroundColor: 'yellow',
   height: 200,
   justifyContent: 'center',
   width: 200,
 },
 title: {
   fontSize: 18,
 },
});
Enter fullscreen mode Exit fullscreen mode

To import the Example component from src in your native App.js, you would do this:

import {Example} from '../src/components';
Enter fullscreen mode Exit fullscreen mode

Or, you could use an alias called @components:

import {Example} from '@components';
Enter fullscreen mode Exit fullscreen mode

However, the Metro Bundler would give you the following error:

BUNDLE  ./index.js 
error: Error: Unable to resolve module ../src/components from /…route_to_project_directory/rn-import-files-outside-root/native/App.js:
Enter fullscreen mode Exit fullscreen mode

Solution

  • To solve this issue, you will need to modify the Metro configuration in your native/metro.config.js file:
const path = require('path');

module.exports = {
 transformer: {
   getTransformOptions: async () => ({
     transform: {
       experimentalImportSupport: false,
       inlineRequires: true,
     },
   }),
 },
 resolver: {
   sourceExts: ['js', 'json', 'ts', 'tsx', 'jsx'],
 },
 watchFolders: [
   path.resolve(__dirname, '../node_modules'),
   path.resolve(__dirname, '../src'),
   path.resolve(__dirname, '..'),
 ],
 projectRoot: path.resolve(__dirname),
};
Enter fullscreen mode Exit fullscreen mode
  • Add the babel-plugin-module-resolver to your development dependencies. Navigate to your React Native project directory and run:
yarn add -D babel-plugin-module-resolver
Enter fullscreen mode Exit fullscreen mode
  • Then, modify your native/babel.config.js file as follows:
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: [
    [
      'module-resolver',
      {
        root: ['../src'],
        alias: {
          '@components': '../src/components',
          'react-native': './node_modules/react-native',
          react: './node_modules/react',
        },
      },
    ],
  ],
};
Enter fullscreen mode Exit fullscreen mode

Note: the exact contents of this file will depend on the specific configuration of your project.

To see the changes, stop the Metro Bundler in your terminal and start it again with the reset cache flag:

npx react-native start --reset-cache
Enter fullscreen mode Exit fullscreen mode

This should allow you to import files from outside the root directory in your React Native project.

Here are some additional resources that may be helpful:

Top comments (1)

Collapse
 
turtle_rizz profile image
Anurag Srivastava

Worked, thank you