学完这篇 Nest.js 实战,还没入门的来锤我!(长文预警)

大厂技术  高级前端  Node进阶

点击上方 程序员成长指北,关注公众号

回复1,加入高级Node交流群

前言

最近一直比较忙, 而且自己工作中做的事也不适合写文章,所以一直没有更文..

最近接到一个小需求,需要自己全干(前端+后端),看到群里大家对Nest.js热情都很高,自己也心痒痒,所以就走上了Nest.js的不归路~

我会将自己做这个小项目过程记录下来,同时也分享一些踩坑的经验,给想学的小伙伴一点参考吧。文章是循序渐进的, 并不是一上来就是深入Nest.js难点, 但是每一章都有一些开发注意点和自己的思考, 欢迎大佬们指点一二。

为什么选择Nest.js

前面也说了, 大家都说香啊~

其次,我之前也使用过Egg.js,19年使用的时候,感觉egg约束性比较强,但是对于内部统一规范还是有好处的,但现在2021了, 已经习惯了TS,但Egg.js没有原生提供的TypeScript支持, 开发时可使用egg-ts-helper 来帮助自动生成 d.ts 文件,这样第三方库的支持完全不受控制, 风险还是很大, 所有选择放弃了

说了这么多,接下来开始吧!文章主要包含以下内容:

fa6275d4403438e53635fcf29f9badee.png
image.png

初识 Nest.js

Nest.js官网介绍:

Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架。它利用JavaScript 的渐进增强的能力,使用并完全支持 TypeScript (仍然允许开发者使用纯 JavaScript 进行开发),并结合了 OOP (面向对象编程)、FP (函数式编程)和 FRP (函数响应式编程)。

在底层,Nest 构建在强大的 HTTP 服务器框架上,例如 Express (默认),并且还可以通过配置从而使用 Fastify !

Nest 在这些常见的 Node.js 框架 (Express/Fastify) 之上提高了一个抽象级别,但仍然向开发者直接暴露了底层框架的 API。这使得开发者可以自由地使用适用于底层平台的无数的第三方模块。

上面这段话刚开始并不能完全理解, 但是简单可以解读出来Nest.js的几个特点:

  • 原生支持TypeScript的框架

  • 可以基于Express也可以选择fastify, 如果你对Express非常熟练, 直接用它的API也是没问题的

至于其他看不懂,就暂时放一边, 因为不影响我们入门,后面深入学习后会再来分析。

项目创建

首先确定你已经安装了Node.js, Node.js 安装会附带npx和一个npm 包运行程序。要创建新的Next.js 应用程序,请在终端上运行以下命令:

npm i -g @nestjs/cli  // 全局安装Nest
nest new project-name  // 创建项目

执行完创建项目, 会初始化下面这些文件, 并且询问你要是有什么方式来管理依赖包:

7b53338534be1acb3eb67d587bf7981f.png
image.png

如果你有安装yarn,可以选择yarn,能更快一些,npm在国内安装速度会慢一些,我这里就用npm下载了。这里省略一个漫长的等待过程~, 终于看到了它成功了(然后我又删除了,使用yarn,确实速度快了很多)

c3d07555b0656795e055aaff862be0dd.png
image.png

接下来按照提示运行项目:

5b42ac9d8e56234a2a9e695332644a1e.png
image.png

这里说一下我安装的环境,Next.js版本不同有些API会有差异

版本
Node.js v12.16.1
npm 6.13.4
nest.js 8.1.4
typescript 4.3.5

注意:Nest.js 要求 Node.js(>= 10.13.0,v13 除外), 如果你的Node.js 版本不满足要求,可以通过nvm包管理工具安装符合要求的Node.js版本

项目结构

进入项目,看到的目录结构应该是这样的:

ade49996f689c1d67946e10604b5e3b5.png
image.png

这里简单说明一下这些核心文件:

src
├── app.controller.spec.ts
├── app.controller.ts
├── app.module.ts
├── app.service.ts
├── main.ts


app.controller.ts 单个路由的基本控制器(Controller)
app.controller.spec.ts 针对控制器的单元测试
app.module.ts 应用程序的根模块(Module)
app.service.ts 具有单一方法的基本服务(Service)
main.ts 应用程序的入口文件,它使用核心函数 NestFactory 来创建 Nest 应用程序的实例。

第一个接口

前面我们已经启动了服务, 那我们怎么查看呢, 首先就是找到入口文件main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

内容比较简单, 使用Nest.js的工厂函数NestFactory来创建了一个AppModule实例,启动了 HTTP 侦听器,以侦听main.ts 中所定义的端口。

监听的端口号可以自定义, 如果3000端口被其他项目使用,可以更改为其他的端口号 因为我的3000端口有别的项目在用, 所以修改成:9080,重新启动项目

我们打开浏览器访问http://localhost:9080地址:

cfebeaa74f8e1987845639f665e6d08f.png
image.png

这里看到的Hello World就是接口地址http://localhost:9080返回的内容, 不信我们也可以使用常用 Postman看看:

52a2b8cb341bfac6edc58b0c4e074b1a.png
image.png

说明Nest.js创建项目默认就给写了一个接口例子,那就通过这个接口例子来看,我们应该怎么实现一个接口。

前边看到mian.ts中也没有别的文件引入, 只有AppModule, 打开src/app.module.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

AppModule是应用程序的根模块,根模块提供了用来启动应用的引导机制,可以包含很多功能模块。

.mudule文件需要使用一个@Module() 装饰器的类,装饰器可以理解成一个封装好的函数,其实是一个语法糖(对装饰器不了解的,可以看走近MidwayJS:初识TS装饰器与IoC机制)。@Module() 装饰器接收四个属性:providerscontrollersimportsexports

  • providers:Nest.js注入器实例化的提供者(服务提供者),处理具体的业务逻辑,各个模块之间可以共享(注入器的概念后面依赖注入部分会讲解);

  • controllers:处理http请求,包括路由控制,向客户端返回响应,将具体业务逻辑委托给providers处理;

  • imports:导入模块的列表,如果需要使用其他模块的服务,需要通过这里导入;

  • exports:导出服务的列表,供其他模块导入使用。如果希望当前模块下的服务可以被其他模块共享,需要在这里配置导出;

如果你是Vue或者React技术栈,初次接触Nest.js,可能会觉得很面生啊, 其实很正常,Nest.js的思维方式一开始确实不容易理解,但假如你接触过AngularJS,就会感到熟悉,如果你用过 Java 和 Spring 的话,就可能会想,这不是抄的 Spring boot嘛!

确实AngularJSSpringNest.js都是基于控制反转原则设计的,而且都使用了依赖注入的方式来解决解耦问题。如果你觉得一头雾水, 别急,这些问题后面深入学习都会一一讲解的。这里我们还是照葫芦画瓢,学一下Nest究竟怎么使用的。

app.module.ts中,看到它引入了app.controller.tsapp.service.ts,分别看一下这两个文件:

// app.controller.ts
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();
  }
}

使用@Controller装饰器来定义控制器, @Get是请求方法的装饰器,对getHello方法进行修饰, 表示这个方法会被GET请求调用。

// app.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService { 
  getHello(): string {
    return 'Hello World!';
  }
}

从上面,我们可以看出使用@Injectable修饰后的 AppService, 在AppModule中注册之后,在app.controller.ts中使用,我们就不需要使用new AppService()去实例化,直接引入过来就可以用。

至此,对于http://localhost:9080/接口返回的Hello World逻辑就算理清楚了, 在这基础上我们再详细的学习一下Nest.js中的路由使用。

路由装饰器

Nest.js中没有单独配置路由的地方,而是使用装饰器。Nest.js

  • 14
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值