This post was originally published on my blog.
Some days ago I included path aliases in my TypeScript Node.js projects. Since they make the code look much cleaner in my opinion I like to show you how to setup these in a project.
The problem
In Node.js (or TS/JS in general) you can import single modules into your code.
This might look the following:
import { User } from '../../user/model';
import { Article } from '../../article/model';
import { Cache } from '../../../../cache';
import { MongoDB } from '../../../../mongodb';
Noticed these dots ('../') to access upper modules?
The problem we have here is that the deeper your project tree is the more '../' are required to access modules in higher layers. Actually, this doesn't look very beautiful to be honest. Fortunately we can change that.
The solution: path aliases
What are path aliases?
In TypeScript you can avoid these "bad" looking imports with the help of path aliases. With path aliases you can declare aliases that map to a certain absolute path in your application.
Here a quick example:
import { User } from '@modules/user/model';
import { Article } from '@modules/article/model';
import { Cache } from '@services/cache';
import { MongoDB } from '@services/mongodb';
In this case our two aliases are
- @modules that maps to './src/rest/modules'
- @services that maps to './src/services'
Setup
Let's get into it and setup some path aliases. Note that I won't explain how to setup a TypeScript project in Node.js. I assume that you did this already.
Imagine we have the following project structure:
folder structure
└───src
│
└───rest
│ │
│ └───modules
│ │ │
│ │ └───article
│ │ │
│ │ └───user
│ │
│ │ server.ts
│
│
└───services
│ │ cache.ts
│ │ mongodb.ts
│
│ index.ts
Step 1: Update tsconfig.json
First of all, we have to declare the path aliases in our tsconfig file
"baseUrl": "./src",
"paths": {
"@modules/*": ["rest/modules/*"],
"@services/*": ["services/*"]
}
Now, you can use the new path aliases for module imports in your application. There occur any errors in your IDE (in my case VSC) or when you compile the code.
However, we are not done yet. When you try compile the TS code into JS you won't see any errors. But as soon as you run your compiled JS code you will get an error:
For example:
Error: Cannot find module '@modules/user'
That's because JS can't resolve the modules for the declared path aliases.
Step 2: Install module-alias package
Next, we'll install an npm package called module-alias
npm i --save module-alias
This module registers the path aliases in the compiled JS files. Therefor we need to make some changes to our package.json:
"_moduleAliases": {
"@modules": "dist/rest/modules",
"@services": "dist/services"
}
Note that 'dist' is the folder where the compiled JS files are located.
Last but not least we have to register the path aliases in our application.
Add the following line at the top of your startup file:
import 'module-alias/register';
Finally, when you compile and execute the code you shouldn't see any import errors.
Here you can find some examples for path aliases in a side project I'm currently working on.
Latest comments (34)
Thank you for sharing this, it was soo helpful.
for who wants using
@/*at importings, only insert:"""
"baseUrl": "./",
"paths": {
"@/": ["./src/"]
}
"""
Example: import { authenticateFromGithubCode } from "@/use-cases/authenticate-from-github-code";
I have setup of this with
tsconfig-pathsbut I am getting module not found error when I am running my dist file. Do you have any idea?Hello.
I don't understand how this solution is supposed to work in production.
We don't have a package.json file in production. So how the aliases will be recognized?
The path aliases only play a role during development since the TS code is compiled to JS.
I don't get any errors and I don't have to install any npm packages...
marked, thanks!
hi, thanks for your sharing. I've followed step-by-step from the article, but however I can't click to navigate to the path when using alias in my vscode. Normally when I click the path, it goes directly to the path... can you help me with this case? I'm not using typescript, so I can't add tsconfig
Did you have a situation where
sharedfolder has its own package.json with node_modules?During compilation
node_modulesare not included in the dist folder, and the compiler is complaining about missing npm modules from thesharedYou can use:
npmjs.com/package/tsconfig-paths
it much easier
you made my day, thx!
Thank you so much! I've probably spent like 6 hours in total trying to get this to work and I finally see the
listening on port 3000log 😁I also kept receiving module_not_found while running ts-node.
The way that worked for me (taken from stackoverflow.com/questions/566507...
In
tsconfig.jsonadd the following section:In order to make the script run on the compiled js (for production distribution), you can defined the following script in
package.json:Don't forget to run
npm i tsconfig-pathsFor anyone reading this, when updating the tsconfig file, you'll need to add the "baseUrl" and "paths" options inside the "compilerOptions" object :)
I couldn't get the aliases working without first building the project since they are registered using the dist folder. Feels hacky. Is there a way around this ?