Avoid the Fear of Refactoring with Absolute Imports in React
Antonello Zanini
Posted on January 19, 2024
As soon as I started developing in React, 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 way easier to refactor by using aliases, as shown below.
Before:
import UserCard from "../../components/UserCard";
import userDefaultImage from "../../../assets/user-default-image.png";
import { UserAPI } from "../../apis/UserAPI";
import _ from "lodash";
After:
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 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:
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 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:
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
and react-app-rewire-alias
to your project's dependencies. You can install both with the following command:
npm install react-app-rewired react-app-rewire-alias --save
To make absolute imports work you have to change to your webpack configuration. If you created your app by using create-react-app
you might be forced to eject your project — 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:
Create a valid
config-overrides.js
file in your root directoryChange the existing references from
react-scripts
toreact-app-rewired
in thescripts
section of your package.json file
Before:
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
}
After:
{
"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:
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:
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.
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:
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.
Visual Studio Code
Create a jsconfig.js
and add the following lines to it:
{
"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" appeared first on Writech.
Posted on January 19, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
January 19, 2024