前言
这是关于如何搭建后端服务的实战类文章,其实在写这类文章之前,也了解了其它的 Node 服务端框架,比如 egg.js、koa.js 等框架,经过比对我更倾向于使用 Nest 框架,因此有了该系列文章,借此总结和梳理自己在项目搭建和开发的过程。
本文所提及的技术栈以及部分案例都是从本人的毕业设计项目中抽取出来的,具体内容可传送至:
- 项目介绍:基于Vue和Nest搭建的Web3D汽车组装演示系统
- 项目仓库地址:github.com/Lewage59/ca…
框架介绍
Nest 是一个用于构建高效,可扩展的 Node.js 服务器端应用程序的框架。旨在成为一个与平台无关的框架。 由于平台无关性,我们以创建可重用的逻辑组件,开发人员可以跨越多种不同类型的应用程序来使用这些组件。
目前来说 Nest 在国外的开发者社区中是一款比较火热的 Node 服务端框架,更新频繁,社区活跃,使用渐进式 JavaScript,内置并完全支持 TypeScript。
Nest 框架 Nest.js 是一个开箱即用的 Node.js 服务器端应用程序的框架,有着相对完善的生态系统,该框架有着灵活且易于维护的特点为开发者和团队提供了便利。
Nest 的底层默认是基于 Express 框架实现的。由于 Nest 是采用 MVC 模式进行开发的,因此在一定程度上降低了项目的维护成本并且提高了代码可读性。Nest 中的模块可以通过 Monorepo 来实现在单个应用程序以更简单、轻量级的方式来共享组件。
前期准备
开发环境
- 数据库:MySQL 5.6
- 服务器:Node.js v10.15.3 (>= 10.13.0)
- 代码管理工具:Git(任意版本)
安装教程及地址:
- MySQL 安装教程
- Node 安装教程
- Git 安装教程
相关技术栈
TypeScrip
:JavaScript 类型的超集;Redis 数据库
:跨平台非关系型数据库;MySQL 数据库
:关系型数据库系统;TypeORM
:对象关系映射器(ORM)框架;JWT 认证技术
:跨域认证解决方案;
项目搭建
前期准备完成之后,就可以开始项目搭建啦,这里我们直接使用 Nest CLI 官方脚手架进行构建。(如果 npm
镜像源比较慢也可以更改镜像源或者使用 yarn
)
npm i -g @nestjs/cli
nest new nest-demo
复制代码
根据提示完成构建后,会得到一个基础的项目结构,其中src
文件夹中包含几个核心文件。
src
├── app.controller.spec.ts // 对于基本控制器的单元测试样例
├── app.controller.ts // 提供路由的基本控制器
├── app.module.ts // 应用程序的根模块
├── app.service.ts // 提供的基本服务
└── main.ts // 创建 Nest 应用程序的入口文件
复制代码
然后只需要在命令行窗口执行如下命令即可启动项目,当您更改任何源文件时,应用程序将自动重新编译和重新加载。
代码语言:javascript复制cd nest-demo
npm run start:dev
复制代码
此命令会启动 HTTP 服务监听定义在 src/main.ts
文件中定义的端口号。在应用程序运行后, 打开浏览器并访问 http://localhost:3000/ ,即可看到Hello world!
输出结果。
Monorepo模式
到目前我们完成了项目的构建并能够成功运行项目,并且在当前目录结构的基础下,我们也可以完成一些接口服务的开发工作,添加新的组件,这样的项目结构称为标准模式。而接下来将重点介绍的是 Nest 提供的另一种模式,Monorepo模式。
(说明:这里提到的标准模式只是 Nest 组织代码的一种模式,当我们把每个项目都对应单独的一个代码仓库时,这就是MultiRepo模式)
1. 什么是Monorepo模式?
Monorepos 只能算是一个新的名词,因为他的概念已经存在很长时间了。
简单的说,Monorepo 是将多个项目放在同一个工作空间(仓库)中,通过工作区的概念统一管理工作区内的所有项目,这些项目之间可能存在关联,但它们通常在逻辑上是独立的,并且可以由不同的团队编写和运行。而这种模式大致归纳有以下优点:
- 规范统一:代码库集中,方便控制代码质量及风格。
- 基建成本低:项目共享一套基建设施。
- 易协作:代码透明,方便跨团队协作。
注意:Nest 的所有特性都与代码组织模式无关。不同的组织模式唯一影响是如何组合项目以及如何生成构建构件,所有其他功能,从 CLI 到核心模块再到附加模块,在任何一种模式下都是相同的。
2. Nest 中的项目实践
在 Nest 中可以在任何时候轻松地从标准模式切换到 Monorepo 模式,因此您可以延迟此决策,直到其中一种方法的好处变得更加明显。
上面我们已经成功构建了标准模式,这里我们直接将其切换到 Monorepo 模式
代码语言:javascript复制nest generate app my-app
复制代码
此时的目录结构将如下所示:
代码语言:javascript复制apps
├──my-app
│ │──src
│ │ │── app.controller.ts
│ │ │── app.service.ts
│ │ │── app.module.ts
│ │ └── main.ts
│ └── tsconfig.app.json
└──nest-demo
│──src
│ │── app.controller.ts
│ │── app.service.ts
│ │── app.module.ts
│ └── main.ts
└──tsconfig.app.json
nest-cli.json
package.json
tsconfig.json
tslint.json
复制代码
Nest 库它不能独立运行,因此必须将库导入到包含它的应用程序中才能执行它的代码。接下来顺势构建项目之间进行模块共享的库。
代码语言:javascript复制nest g library my-library
复制代码
库是在 Monorepo 根目录的 libs 文件夹下管理的,将会生成如下目录结构,可以看到构建的文件与应用程序生成的文件略有差异。
代码语言:javascript复制libs
└──my-library
│──src
│ │── my-library.service.ts
│ │── my-library.module.ts
│ │── lib.service.spec.ts
│ └── index.ts
└── tsconfig.lib.json
复制代码
在库中的模块我们只需要引入到项目中的根模块即可使用,此时我们只需要在项目根目录的src/app.module
文件引入即可
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MyLibraryModule } from '@libs/my-library'; // 引入libs中的模块
@Module({
imports: [MyLibraryModule], // 导入模块
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
复制代码
上面的@libs
前缀是别名是我们在构建库时自己设置的路径别名,默认时@app
,这里为了区分是属于库中的模块还是应用程序的模块,设置了@libs
作为路径别名。
What prefix would you like to use for the library (default: @app)?
复制代码
这些模块的路径别名统一在项目根目录下的tsconfig.json
文件中
"paths": {
"@libs/my-library": [
"libs/my-library/src"
],
"@libs/my-library/*": [
"libs/my-library/src/*"
]
}
复制代码
由于使用了 Monorepo 模式,因此我们需要使用以下命令启动服务
代码语言:javascript复制// nest-demo 为要运行的项目名称
nest start nest-demo -w
复制代码
写在最后
那么到这里我们就完成了项目的基础构建工作,接下来也将会围绕【汽车组装演示系统】项目中的模块功能搭建来介绍具体。其实这个服务端项目无需这么大费周章的使用 Monorepo 模式去构建,都可以实现项目所需要的功能,毕竟只是个人项目,但是我还是希望以更加实际的角度去完成这个项目。
【汽车组装演示系统】这个项目的服务端系统其实将前台服务和后台服务独立分开进行开发,同时共享了一些通用模块,比如:身份鉴权、日志模块、数据库连接模块等等。在这个项目开始之前其实也借鉴了很多 GitHub 上的其它项目,学习如何更加优雅的方式构建这个项目,所以这整个过程都可以说是学习的过程,如有不足的地方还希望大佬指点,感谢!!