Get rid of relative import path hell by adding absolute imports to your Typescript project

Typing long and error-prone paths to your Typescript modules can be a frustrating task

Tien
Level Up Coding

--

If you don’t know how to set up a TypeScript project, check out this article.

Have you ever seen an import statement like this?

import { formatName }  from '../../helpers/format-name'

These inconsistent relative paths look ugly and make code maintenance a nightmare!

Imagine one day you have to update the directory structure meaning part of or all of the relative paths must be changed. While most of IDEs can try their best to update the references, it doesn’t always do it correctly…

Don’t worry, this guide comes to the rescue.

Overview

We would like to shorten this kind of code:

import { formatName }  from '../../helpers/format-name'

to this:

import { formatName }  from '~/helpers/format-name'

Where the ~ denotes the src directory.

Step 1

Let’s create a dummy User model class and a formatName function. At the root of project:

touch src/app/models/User.ts src/helpers/format-name.ts

Add the following code in src/app/models/User.ts:

And following in src/helpers/format-name.ts :

In src/handlers.ts, import the User model:

import { User } from "./app/models/user";

And modify rootHandler function as follow:

export const rootHandler = (_req: Request, res: Response) => {  const user = new User();  return res.send(`Hi ${user.fullName}, API is working 🤓`);};

Now run yarn dev, you should see this error:

The TS compiler doesn’t understand what the heck ~ stands for so we have to let it know in the next step.

Step 2

We’re gonna make a minor change in tsconfig.json. Under the paths property, add another path definition indicate src folder:

...
"paths": {
... "~/*": ["src/*"] },...

Execute yarn dev, and it works! Keep going, run yarn build && yarn start for production. But oops, an error is thrown again:

The explanation is that you only let the TS compiler know the ~ symbol, but node runner still doesn’t understand what it is. Once again, we will let this guy know.

Step 3

To make it work in production, we will need help of link-module-alias package:

yarn add link-module-alias

Add this property into package.json:

...
"_moduleAliases": {
"~": "dist" }...

Basically the idea here is that we use link-module-alias for initializing a symlink to dist directory.

In the start script, execute link-module-alias command:

"start": "link-module-alias && node dist/index.js",

Now run yarn dev again, and it should work. Run yarn build && yarn start, and the console should not throw any errors too. Let’s see whether it works in the browser:

If you are using VS Code (as I also highly recommend when working with TS), the aliases will appear in the autocomplete dropdown:

Conclusion

Module alias will save you time and the frustration of dealing with ../ splattered everywhere. Another big advantage of using this package is that it doesn’t need runtime hooks to your app’s entry point like most solutions. Runtime hooks may modify the default import behavior, add a level of unnecessary computation and complexity to the application, and should be used cautiously.

--

--