Avoid the Fear of Refactoring with Absolute Imports in React
Tags: javascript, programming, react, softwaredevelopment
Published: 2024-01-19 21:03:57

As soon as I started developing in [React](https://reactjs.org/), I noticed how easily refactoring can turn into a painful experience. Based on my expertise, **this can break most of your imports**.

If you have ever dealt with the fear of refactoring, then this tutorial is for you. Do not panic, because there is a solution!

In this tutorial, I will show you how to make your [`import` statements](https://reactjs.org/docs/code-splitting.html) way easier to refactor by using aliases, as shown below.

Before:

```javascript
import UserCard from "../../components/UserCard";
import userDefaultImage from "../../../assets/user-default-image.png";
import { UserAPI } from "../../apis/UserAPI";
import _ from "lodash";
```

After:

```javascript
import UserCard from "@components/UserCard";
import userDefaultImage from "@assets/user-default-image.png";
import { UserAPI } from "@apis/UserAPI";
```

As you can see, the proposed solution makes your imports look cleaner too, isn't it? What a great side effect!

Let's see how to import modules, API definitions, utilities, components, or assets with absolute path aliases in [webpack](https://webpack.js.org/) and React.

## Relative Imports vs Absolute Imports

By default, _relative paths_ are the supported way of importing files in React. They are called _relative_ because they use a path relative to the current file.

For small projects, they are a great solution. On the other hand, when it comes to large projects, dealing with _relative imports_ can turn into a nightmare. In fact, in a deeply hierarchical directory structure, you might end up with relative imports looking like this:

```javascript
import UserCard from "../../../components/UserCard";
```

Not only this does not look good, but r_elative imports_ are also affected by the following issues:

- They make your codebase hard to refactor

- They are not scalable to the size of your project

- They make creating an [npm module](https://docs.npmjs.com/about-packages-and-modules#about-modules) from your codebase complex

This is why you should use them sparingly. Ideally, only if you have closely related files that can be considered part of the same larger module. In any other case, **_absolute imports_ should represent your preferred approach**. They are called _absolute_ because they allow you to import files from absolute paths, unrelated to the current file. Thanks to them, you can turn the previous example into something like this:

```javascript
import UserCard from "@components/UserCard";
```

Better, right? Let's see how to achieve such a result.

## Defining Absolute Path Aliases in webpack

First of all, you need to add [`react-app-rewired`](https://www.npmjs.com/package/react-app-rewired) and [`react-app-rewire-alias`](https://www.npmjs.com/package/react-app-rewire-alias) to your project's dependencies. You can install both with the following command:

```shell
npm install react-app-rewired react-app-rewire-alias --save
```

To make absolute imports work you have to change to your [webpack configuration](https://webpack.js.org/configuration/). If you created your app by using [`create-react-app`](https://reactjs.org/docs/create-a-new-react-app.html) you might be forced to [eject your project](https://create-react-app.dev/docs/available-scripts/#npm-run-eject) — and this should be avoided if not strictly required.

This is where `react-app-rewired` comes into play!

Please, note that if your project already uses `react-app-rewired` you can skip the following two steps.

Thanks to it, you can easily tweak the `create-react-app` webpack config. In order to make everything work, you need to follow the next two steps:

1. Create a valid `config-overrides.js` file in your root directory

3. Change the existing references from `react-scripts` to `react-app-rewired` in the `scripts` section of your _package.json_ file

Before:

```json
{ 
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }
}
```

After:

```json
{ 
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-app-rewired eject"
  }
}
```

You have just rewired your React app, and you are now ready to declare your first absolute path aliases. Add the following lines to your `config-overrides.js` file:

```javascript
const { alias } = require("react-app-rewire-alias")

module.exports = {
    webpack: (config, env) => {
         
        alias({
             // define these based on your needs
            "@components": "./src/components",
            "@assets" : "./src/assets",
            "@apis" : "./src/apis"
        })(config)

      return config
    }
  
  // ...
  
}
```

First, you need to import `alias` from `react-app-rewire-alias`. Then, you can call it by passing an object with key-value pairs. The keys represent your aliases and the values represent the corresponding paths.

Et voilà! You can now use the three aliases defined above to import the files located in those folders absolutely as follows:

```javascript
import UserCard from "@components/UserCard";
import userDefaultImage from "@assets/user-default-image.png";
import { UserAPI } from "@apis/UserAPI";
```

Plus, `react-app-rewired` allows you to achieve other fantastic goals. For example, [keeping one dedicated build folder per environment](https://writech.run/blog/how-to-correctly-build-a-multi-environment-react-app-6ba4878e98ba).

## Bonus: Setting Up Your IDE to Deal with Absolute Paths

In order to make your IDE able to understand absolute paths, you need to do some extra operations.

### IntelliJ IDEA

Create a `webpack.config.alias.js` file in your root folder and define it as follows:

```javascript
const path = require('path');

module.exports = {
    resolve: {
        alias: {
             // define these based on your needs
            '@components': path.resolve(__dirname, 'src/components/'),
            "@assets" : path.resolve(__dirname, 'src/assets/'),
            "@apis" : path.resolve(__dirname, 'src/apis/'),
        }
    }
};
```

Then, _File > Settings… > Languages & Frameworks > JavaScript > Webpack_. Choose the _Manually_ option and select the file defined above.

![](https://writech.run/wp-content/uploads/2023/08/image-155.png)

### Visual Studio Code

Create a `jsconfig.js` and add the following lines to it:

```javascript
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
       // define these based on your needs
      "@components/*": ["src/components/*"],
      "@assets/*": ["src/assets/*"],
      "@apis/*": ["src/apis/*"]
    }
  },
  "exclude": ["node_modules"] 
}
```

## Conclusion

Here we looked at how to use absolute path aliases in React. They are a great way to avoid the fear of refactoring since they do not lead to broken imports as opposed to relative imports. This is why you should always use them, and this can be easily be achieved as shown in the article.

Thanks for reading! I hope that you found this article helpful.
  
***
_The post "[Avoid the Fear of Refactoring with Absolute Imports in React](https://writech.run/blog/avoid-the-fear-of-refactoring-with-absolute-imports-in-react-804bce61dc31/)" appeared first on [Writech](https://writech.run)._