Nest JS Module aliasing using module-alias
A Simple Way To Use Path Aliases in NestJS
I am talking about this
Original:
import CatModule from '../../cat/cat.module.ts'
Alias Path:
import CatModule from '@/cat/cat.module.ts'
whenever we write code most of teh times we end up using whole path which is pain as we have to traverse the whole path Solution for that is module-alias and we will us ethat with nestjs app, i hope you already know hoe to create basic nestjs app using CLI
Nest.js Application Let’s continue with NestJS! We are going to install the NestJS CLI, so open the terminal of your choice and type:
$ npm i -g @nestjs/cli
We initialize a new NestJS project with its CLI. That might take up to a minute. The “-p npm” flag means, that we going to choose NPM as our package manager. If you want to choose another package manager, just get rid of this flag.
$ nest new nest-alias -p npm
Furthermore, we’re creating a PlayerModule, PlayerController, and a helper function in a different destination.
$ nest g mo player && nest g co player --no-spec
$ mkdir src/common && mkdir src/common/helper
$ touch src/common/helper/utils.helper.ts
After this command is done you can open your project in your code editor. Since I use Visual Studio Code, I gonna open the project by typing:
$ cd nest-alias
$ code .
Now lets follow what all you need to have module-path alaising
Step-1
Looks at this NPM package npmjs.com/package/module-alias Install
npm i --save module-alias
Usage Add your custom configuration to your package.json (in your application's root)
// Aliases
"_moduleAliases": {
"@root" : ".", // Application's root
"@deep" : "src/some/very/deep/directory/or/file",
"@my_module" : "lib/some-file.js",
"something" : "src/foo", // Or without @. Actually, it could be any string
}
// Custom module directories, just like node_modules
but with your private modules (optional)
"_moduleDirectories": ["node_modules_custom"],
Then add this line at the very main file of your app, before any code
require('module-alias/register')
And you're all set! Now you can do stuff like:
require('something')
const module = require('@root/some-module')
const veryDeepModule = require('@deep/my-module')
const customModule = require('my_private_module') // module from `node_modules_custom` directory
// Or ES6
import 'something'
import module from '@root/some-module'
import veryDeepModule from '@deep/my-module'
import customModule from 'my_private_module'
we can do the same for our project npm i --save module-alias
Step-2
Update your tsconfig file to have path mapping there
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es2017",
"allowJs": true,
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"strict": true,
"skipLibCheck": true,
"paths": {
"@app/*": ["src/app/*"],
"@auth/*": ["src/app/auth/*"],
"@domain/*": ["src/app/domain/*"]
"@test/*": ["test/*"]
}
},
}
Step-3
Add same path level configuration to jest.config.ts and jest.config-e2e.js as tests also needs to resolve module using path alias jest.config.js
module.exports = {
setupFiles: ['<rootDir>/test/setEnvVars.js'],
silent: false,
moduleFileExtensions: ['js', 'ts'],
rootDir: '.',
testRegex: '[.](spec|test).ts$',
transform: {
'^.+\\.(t|j)s$': 'ts-jest',
},
coverageDirectory: './coverage',
testEnvironment: 'node',
roots: ['<rootDir>/'],
moduleNameMapper: {
"^@app(.*)$": "<rootDir>/src/app/$1",
"^@auth(.*)$": "<rootDir>/src/app/auth/$1",
"^@domain(.*)$": "<rootDir>/src/app/domain/$1",
},
};
jest-config.e2e.js
// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html
module.exports = {
"setupFiles": ["./test/setEnvVars.js"],
moduleFileExtensions: ["js", "json", "ts"],
rootDir: ".",
maxWorkers: 1,
testEnvironment: "node",
testRegex: ".e2e-spec.ts$",
transform: {
"^.+\\.(t|j)s$": "ts-jest",
},
moduleNameMapper: {
"^@app(.*)$": "<rootDir>/src/app/$1",
"^@auth(.*)$": "<rootDir>/src/app/auth/$1",
"^@domain(.*)$": "<rootDir>/src/app/domain/$1",
},
globals: {
"ts-jest": {
tsconfig: "tsconfig.e2e.json",
},
},
};
Step-4
now we can introduce this path alsing to our package JSON which is important as our application need to resolve @config, @domain, @app using path-aliasing
"_moduleAliases": {
"@app": "dist/src/app",
"@auth": "dist/src/app/auth",
"@domain": "dist/src/app/domain"
},
"devDependencies": {
}
Finally how to let application know about loading all these alsing using module-alias module
Step-5
require("module-alias/register");
require('dotenv').config();
Now i can use these aliasing everywhere in project inside src/ or tests
Step-6
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { TerminusModule } from '@nestjs/terminus';
import { LoggerModule } from 'nestjs-rollbar';
import { ConfigModule } from '@config/config.module';
import { DbModule } from '@db/db.module';
import { KafkaModule } from '@kafka/kafka.module';
import { AppLoggerModule } from '@logger/logger.module';
Conclusion
Module aliasing is useful and you must use this in your project, to follow this just use all these steps and you should be able to use alising for custom modules, you can addyour own path just add new module path entry in all files