---
tags: nestjs, typescript
---
# 什麼是 Nestjs
## 定義
[Nestjs](https://docs.nestjs.com/) 是一套 Nodejs 語言的後端開發框架
## 特性
1. 支援 [Typescript](https://www.typescriptlang.org/) 的作為開發語法
2. 底層 HTTP Server 預設使用 [Express](https://expressjs.com/),也可以更換為另一個 HTTP Server 框架 [Fastify](https://github.com/fastify/fastify)
3. 效法 [Angular](https://angular.io/) 框架概念,提供了 DI container 概念。 設計了以 Module 作為邏輯內聚的基礎單位
4. 如同 [Angular](https://angular.io/) 框架,提供建制專案的良好 cli 工具,節省配置複雜設定的時間
# 為何用 Nestjs(可能想用的原因)
1. 想利用 DI Container 簡化程式耦合度,方便用來做測試隔離
2. 透過 cli tool 減少配置專案設定的時間,假設部手動亂改配置的話
3. 想透過已存在的功能元件加速開發時間,專注於真正核心業務的邏輯
4. ~~主流~~
# Nestjs 最重要概念(個人認為)
## 1. 元件架構
### 最基礎單位是 Module

### 透過 Provider 來使用共用服務或是元件
app.module.ts:
```typescript=
import { Module } from '@nestjs/common';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [],
providers: [AppService],
exports: []
})
export class AppModule {}
```
透過 Injectable 關鍵字讓 Service 可以被 provide
app.service.ts
```typescript=
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
```
### controllers 用來放置與 HTTP 互動的邏輯
app.module.ts:
```typescript=
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
```
app.controller.ts:
```typescript=
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
```
### imports 用來引入外部非全域的 Module
### exports 用來分享需要提供出去的服務
## 2. 建制運行
### 建立 新的專案
```shell=
nest new ${project_name}
```
### 建立 公用 lib
```shell=
cd ${project_name}; nest g lib ${library_name}
```
### 建立 Resource
```shell=
cd ${project_name}; nest g resource ${resource_name}
```
### 執行並且 hot-reload
```shell=
cd ${project_name}; yarn start:dev
```
### 建制可執行 js 檔案
```shell=
cd ${project_name}; yarn build ${project_name}
```
## 3. 測試隔離
透過 DI container 可以在測試中引入所需要測試的部份
來達到其測試的效果
```typscript=
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});
```