DEV Community

Cover image for How to Setup Path Alias in a React Native TypeScript App
Spencer Carli
Spencer Carli

Posted on • Originally published at reactnativeschool.com

How to Setup Path Alias in a React Native TypeScript App

So you've got a React Native app, you're using TypeScript, and you're being killing by long package imports. Let's fix that.

Take the project structure below - if I want to import CircleButton in components from my StopWatch.tsx in screens it's going to look like this:

import { CircleButton } from '../../components/buttons';

/Users/spencer/Dev/ClockApp
├── App.tsx
├── app.json
├── babel.config.js
├── package.json
├── src
|  ├── components
|  |  ├── buttons
|  |  |  ├── CircleButton.tsx
|  |  |  └── index.tsx
|  ├── index.tsx
|  └── screens
|     └── Clocks
|        └── StopWatch.tsx
├── tsconfig.json
└── yarn.lock
Enter fullscreen mode Exit fullscreen mode

Let's fix that so your import statement can look like

import { CircleButton } from 'components/buttons';

or better yet

import { CircleButton } from 'buttons';

To accomplish this you need to update two files.

TypeScript Path Alias

The first is tsconfig.json. This is for TypeScript to understand the path alias.

First set your baseUrl to ., which represents the root of the directory. Every path in your tsconfig will be relative to that.

You then add your path alias' to the paths object. I'm going to add one for the components directory (components/buttons) and a direct one to the button exports (buttons).

// tsconfig.json
{
  "extends": "expo/tsconfig.base",
  "compilerOptions": {
    "strict": true,
    // Path alias config
    "baseUrl": ".",
    "paths": {
      // This needs to be mirrored in babel.config.js
      // Components is a directory with sub directories
      "components/*": ["src/components/*"],

      // We want to expose the exports of the buttons index file
      "buttons": ["src/components/buttons/index"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

That will allow TypeScript to parse the following:

import { CircleButton } from "components/buttons"
import { CircleButton } from "buttons"
Enter fullscreen mode Exit fullscreen mode

React Native Path Alias

Now we need to handle React Native path alias so the packager knows where to actually grab the files.

First install the babel-plugin-module-resolver as a developer dependency

yarn add --dev babel-plugin-module-resolver
npm install babel-plugin-module-resolver --save-dev
Enter fullscreen mode Exit fullscreen mode

Now we can update the babel.config.js file to use the module-resolver plugin and point to our directories.

// babel.config.js

module.exports = function (api) {
  api.cache(true)
  return {
    presets: ["babel-preset-expo"],
    plugins: [
      [
        "module-resolver",
        {
          alias: {
            // This needs to be mirrored in tsconfig.json
            components: "./src/components",
            buttons: "./src/components/buttons",
          },
        },
      ],
    ],
  }
}
Enter fullscreen mode Exit fullscreen mode

And you're all set! Now you can shorten your imports, type less, ease refactoring, and make it easier to scan code.

Pro tip: Want to use absolute paths but don't want to add an alias for every directory? Add your root directory (such as src) to the alias config as well!

// tsconfig.json

{
  "extends": "expo/tsconfig.base",
  "compilerOptions": {
    "strict": true,
    // Path alias config
    "baseUrl": ".",
    "paths": {
      // This needs to be mirrored in babel.config.js
      "components/*": ["src/components/*"],
      "buttons": ["src/components/buttons/index"],
      "src/*": ["src/*"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
// babel.config.js

module.exports = function (api) {
  api.cache(true)
  return {
    presets: ["babel-preset-expo"],
    plugins: [
      [
        "module-resolver",
        {
          alias: {
            // This needs to be mirrored in tsconfig.json
            components: "./src/components",
            buttons: "./src/components/buttons",
            src: "./src",
          },
        },
      ],
    ],
  }
}
Enter fullscreen mode Exit fullscreen mode

Now you can use imports like import { CircleButton } from "src/components/buttons" as well.

Hope that helps!

Top comments (0)