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
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.