Guide For Nest JS
1. Getting Started - Create an Advanced Server
- Step 1: Create new project
Run the command:
nest new project-name
Followed by:
cd project-name
pnpm run start
You now have a running server on port 3000.
You can change the port number over at main.ts
.
You might wanna add the lines:
const PORT = process.env.PORT ?? 8000;
await app.listen(PORT, () => console.log(`server running on port ${PORT}`));
- Step 2: add dev script
In your package.json, add:
{
"dev": "nest start --watch",
}
- Step 3: Eslint
Nest is configured with the old eslint (v8), so you'll need to replace it with v9.
You'll need to uninstall all of these:
eslint
@typescript-eslint/eslint-plugin
@typescript-eslint/parser
eslint-config-prettier
eslint-plugin-prettier
and install these:
eslint
(latest)@eslint/js
eslint-plugin-perfectionist
eslint-plugin-react-compiler
globals
typescript-eslint
- Step 4: tsconfig.json
Copy the tsconfig from vs-vite-template
project, as it is more organized.
You'll need to manually change these however:
module
: set tocommonjs
instead ofESNEXT
noEmit
: set tofalse
instead oftrue
.emitDecoratorMetadata
: set totrue
instead offalse
.experimentalDecorators
: set totrue
instead offalse
.outDir
: set to "./dist"removeComments
: set totrue
instead offalse
.moduleResolution
: set toclassic
instead ofbundler
(or simply unset it).declaration
: set totrue
instead offalse
.
- Step 5: package.json type:commonjs
I'm 99% sure that nest can't work in esm. I tried to put "type": "module", and the dev server threw an esm related error. Therefore, make sure your package.json is set to:
{
"type": "commonjs"
}
- Step 6: use SWC
SWC (Speedy Web Compiler) is an extensible Rust-based platform that can be used for both compilation and bundling. Using SWC with Nest CLI is a great and simple way to significantly speed up your development process.
SWC is approximately x20 times faster than the default TypeScript compiler.
Install these packages:
p add -D @swc/cli @swc/core
And modify the nest-cli.json
:
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"builder": {
"type": "swc",
"options": {
"outDir": "dist",
"watch": false
}
},
"deleteOutDir": true,
"typeCheck": false // <--- in SWC, this defaults to false, and needs to be enabled manually.
}
}
SWC does not perform any type checking itself (as opposed to the default TypeScript compiler), so to turn it on, you need to use the --type-check flag, or you can just set the compilerOptions.typeCheck
property to true in your nest-cli.json.
SWC + Jest
To have support for jest in SWC, you first need to install:
p add -D jest @swc/core @swc/jest
Then update your package.json
:
{
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s?$": [
"@swc/jest"
]
},
"moduleNameMapper": {
"^@src/(.*)": "<rootDir>/$1"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
And add a .swcrc
file at the root of your project, with the following contents:
{
"$schema": "https://json.schemastore.org/swcrc",
"sourceMaps": true,
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true,
"dynamicImport": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"baseUrl": "./"
},
"minify": false
}
- Step 7: Configuration
- A. Installation
To be able to read .env
files, install the following:
p add @nestjs/config
The @nestjs/config package internally uses dotenv
.
Since @nestjs/config
relies on dotenv, it uses that package's rules for resolving conflicts in environment variable names. When a key exists both in the runtime environment as an environment variable (e.g., via OS shell exports like export DATABASE_USER=test) and in a .env file, the runtime environment variable takes precedence.
- B. Basic Usage
Once the installation process is complete, we can import the ConfigModule
in the root AppModule
and control its behavior using the .forRoot() static method:
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [ConfigModule.forRoot()],
})
export class AppModule {
// ...
}
What this does:
- It looks for a file named
.env
at the root of your project, reads it, and adds its contents toprocess.env
. - The forRoot() method registers the
ConfigService
provider, which provides a get() method for reading these parsed/merged configuration variables. For example:const nodeEnv = configService.get<EnvOptions>('nodeEnv');
console.log(nodeEnv);
You can also specify a different path/name for the .env
files like so:
ConfigModule.forRoot({
envFilePath: '.env.development.local',
});
You can also specify multiple paths for .env files like so:
ConfigModule.forRoot({
envFilePath: ['.env.development.local', '.env.development'],
});
If a variable is found in multiple files, the first one takes precedence.
- C. Disable env variables loading
If you don't want to load the .env
file, but instead would like to simply access environment variables from the runtime environment (as with OS shell exports like export DATABASE_USER=test), set the options object's ignoreEnvFile
property to true
.