30

I'm trying to use absolute import paths instead of relative paths with Expo and React Native.

I looked on the expo docs and couldn't find an answer... Searching for the subject in react community I found babel-plugin-module-resolver but it seems that Expo is already using it so I've changed my .babelrc to create some aliases:

{
  "presets": ["babel-preset-expo"],
  "env": {
    "development": {
      "plugins": [
        "transform-react-jsx-source",
        ["module-resolver", {
          "root": ["./app"],
          "alias": {
            "Components": "./app/components",
          }
        }]
      ]
    }
  }
}

But I got the following error:

    Unable to resolve module '@expo/vector-icons/glyphmaps/Entypo.json' 
    from '/Users/eduardoleal/Code/lua/rook/node_modules/@expo/vector-icons/Entypo.js': 
    Module does not exist in the module map or in these directories:   /Users/eduardoleal/Code/lua/rook/node_modules/@expo/vector-icons/node_modules/@expo/vector-icons/glyphmaps ,   /Users/eduardoleal/Code/lua/rook/node_modules/@expo/vector-icons/glyphmaps  This might be related to https://github.com/facebook/react-native/issues/4968 To resolve try the following:   
    1. Clear watchman watches: 'watchman watch-del-all'.   
    2. Delete the 'node_modules' folder: 'rm -rf node_modules && npm install'.   
    3. Reset packager cache: 'rm -fr $TMPDIR/react-*' or 'npm start --reset-cache'.
    ABI16_0_0RCTFatal -[ABI16_0_0RCTBatchedBridge stopLoadingWithError:] __34-[ABI16_0_0RCTBatchedBridge start]_block_invoke_2 _dispatch_call_block_and_release _dispatch_client_callout _dispatch_main_queue_callback_4CF __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ __CFRunLoopRun CFRunLoopRunSpecific GSEventRunModal UIApplicationMain main start 0x0 

Is there any easy way to import absolute paths?

jayqui
  • 1,882
  • 2
  • 20
  • 18
Eduardo Leal
  • 807
  • 2
  • 9
  • 18
  • Why would you want to use absolute paths? The code won't work on any other computer than yours. – vonovak May 05 '17 at 19:11
  • 2
    I prefer import things like `import A from '@components/A'` instead of `import A from '../../../A'`. Maybe "import absolute paths" was not what I meant... – Eduardo Leal May 10 '17 at 16:45
  • 7
    @VojtechNovak it's absolute in respect to the root folder of the project not the root hard drive – arcom Jul 19 '17 at 18:52

7 Answers7

34

Update: Expo v32.0.0 and up

Expo init is creating a babel.config.js for you. Just add the plugins key to your babel.config.js file and add your alias. The env key is not needed anymore.

module.exports = function(api) {
  api.cache(true)

  return {
    presets: ['babel-preset-expo'],
    plugins: [
      [
        'module-resolver',
        {
          alias: {
            assets: './assets',
            components: './src/components',
            modules: './src/modules',
            lib: './src/lib',
            types: './src/types',
            constants: './src/constants',
          },
        },
      ],
    ],
  }
}

Update: Changes for Expo.io SDK v20.0.0

Since SDK v20.0.0 you can use the normal Babel Expo presets

{
  "presets": ["babel-preset-expo"],
  "env": {
    "development": {
      "plugins": ["transform-react-jsx-source"]
    }
  },
  "plugins": [
    ["module-resolver", {
      "alias": {
        "alias-name": "./app",
      }
    }]
  ]
}

Expo.io SDK v19.0.0 and before

Without the root-element, separating plugins and changing presets to babel-preset-react-native-stage-0/decorator-support, an alias work for me.

Using Expo.io on Version 16.0.0
Found this in the Expo Forums here: https://forums.expo.io/t/relative-paths-with-expo/654/3

Can you verify that this works on your case too?

{
  "presets": ["babel-preset-react-native-stage-0/decorator-support"],
  "env": {
    "development": {
      "plugins": ["transform-react-jsx-source"]
    }
  },
  "plugins": [
    ["module-resolver", {
      "alias": {
        "alias-name": "./app",
      }
    }]
  ]
}
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Laszlo Schürg
  • 521
  • 3
  • 6
  • 3
    After making these changes, you might also need to run `expo r -c` (which is Expo's equivalent to `yarn start --reset-cache`) to have them take effect. – Brian Li May 18 '21 at 04:18
  • 1
    How would you configure an alias in order to be able to import a component like `import A from '@components/A'` ? – Nermin Jul 21 '21 at 10:32
  • @Nermin I think "@components" as alias-name, should make that effect. Please confirm. – sgClaudia98 Dec 23 '21 at 14:15
  • 1
    @sgClaudia98 I actually ended up creating an alias `"@": "./src"` so I could import everything under `src` with `@`. E.g. `import A from @/components/A`. – Nermin Dec 23 '21 at 14:58
  • thanks @Brian Li. after 2 days of struggle you saved me. – Sreenath Feb 19 '23 at 05:06
4

For latest expo users(sdk version >= 32).

Just add plugins property in your babel.config.js (find this file in project root directory).

module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: [
      [
        'module-resolver',
        {
          alias: {
            'alias-name': './src/assets/bla/bla',
          },
        },
      ],
    ],
  };
};
Bimal Grg
  • 7,624
  • 2
  • 24
  • 21
4

In adition to Laszlo Schurg's answer in case someone encounters the same problem with Typescript.

If you are using Typescript you also need to add this in your tsconfig

"compilerOptions": {
  ...
  "baseUrl": ".",
  "paths": {
    "@src/*": ["./src/*"],
    "@assets/*": ["./assets/*"]
  }
},

That's my config for this babel.config

plugins: [
  ...
  [
    "module-resolver",
    {
      alias: {
        "@assets": "./assets",
        "@src": "./src",
      },
    },
  ],
],
sgClaudia98
  • 236
  • 4
  • 14
2

After a while trying to get this working. I could resolve the problem with de following .babelrc:

{
  "presets": ["babel-preset-react-native-stage-0/decorator-support"],
  "env": {
    "development": {
      "plugins": ["transform-react-jsx-source"]
    }
  },
  "plugins": [
    ["module-resolver", {
      "alias": {
        "react-native-vector-icons": "@expo/vector-icons",
        "@expo/vector-icons/lib/create-icon-set": "react-native-vector-icons/lib/create-icon-set",
        "@expo/vector-icons/lib/icon-button": "react-native-vector-icons/lib/icon-button",
        "@expo/vector-icons/lib/create-icon-set-from-fontello": "react-native-vector-icons/lib/create-icon-set-from-fontello",
        "@expo/vector-icons/lib/create-icon-set-from-icomoon": "react-native-vector-icons/lib/create-icon-set-from-icomoon",
        "@expo/vector-icons/lib/icon-button": "react-native-vector-icons/lib/icon-button",
        "@expo/vector-icons/glyphmaps": "react-native-vector-icons/glyphmaps",
        "$components": "./app/components",
        "$config": "./app/config",
        "$helpers": "./app/helpers",
        "$navigators": "./app/navigators",
        "$reducers": "./app/reducers",
        "$screens": "./app/screens",
        "$images": "./assets/images",
        "$fonts": "./assets/fonts",
        "$icons": "./assets/icons",
        "$videos": "./assets/videos",
      }
    }]
  ]
}

I copied the content of babel-preset-expo to my .babelrc. It's not the best solution... but it works normally.

More details about it here

Eduardo Leal
  • 807
  • 2
  • 9
  • 18
2
./src
 |- package.json
 |- Bar/
 |   `- index.js
 `- Foo.js

package.json

{
  "name": "~" // whatever u want
}

then

import { Foo } from "~/Foo";
import { Bar } from "~/Bar";
// ...
uinz
  • 31
  • 2
0

I com with this suggestion:

In your tsconfig.json:

  <pre>
     <code>
{
  "compilerOptions": {
    "baseUrl": "./app",
    "paths": {
      "Components": ["components/*"]
    }
  },
  "include": ["app"]
}
     </code>
  </pre>

And vite.config.ts resolve might look like this:

 <pre>
    <code>
resolve: {
    alias: {
      "Components": "app/components",
    }
}
    </code>
 </pre>
jubajuba
  • 21
  • 1
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 03 '23 at 09:52
-2

Just simple make you .babelrc simple like this:

{
  "presets": ["babel-preset-expo"],
  "env": {
    "development": {
      "plugins": ["transform-react-jsx-source"]
    }
  }
}

And import like this:

import Entypo from '@expo/vector-icons/Entypo';
Dinesh Katwal
  • 930
  • 1
  • 14
  • 25