Nest项目(一)-项目概览及初始化项目
前言
前段时间接触了 nest 框架,并使用该框架搭建了一个前后台分离项目。 但是做过以后就忘记了,为了简化以后搭建项目的成本,特此梳理并记录一下项目的搭建过程,并进行分享。
项目概览
项目是这样设计的:
- 具体业务是从数据库中拿出一些数据,对数据进行处理,服务端渲染 html 并完成上线流程。
- 然后在此基础上,抽离数据逻辑,使用 ajax 的方式实现页面好数据分离。
- 再进一步,统一处理请求体和返回体结构。
- 登录和权限管理。
- 上传和下载。
初始化项目
Nest 是一个用于构建高效,可扩展的 Node.js 服务器端应用程序的框架。它使用渐进式 JavaScript,内置并完全支持 TypeScript(但仍然允许开发人员使用纯 JavaScript 编写代码)并结合了 OOP(面向对象编程),FP(函数式编程)和 FRP(函数式响应编程)的元素。
在底层,Nest使用强大的 HTTP Server 框架,如 Express(默认)和 Fastify。Nest 在这些框架之上提供了一定程度的抽象,同时也将其 API 直接暴露给开发人员。这样可以轻松使用每个平台的无数第三方模块。
一、安装 nest
# 安装 nest
$ npm i -g @nestjs/cli
# 查看 nest 版本
$ nest -v
# nest g --help 或 nest -h,可以查看所有的快捷命令
二、创建新的项目
创建项目的时候会询问需要哪个包管理工具,我这里用的是 pnpm。
如下提示则证明新建项目成功。
# 创建项目
$ nest new project-name
⚡ We will scaffold your app in a few seconds..
Nothing to be done.
? Which package manager would you ❤️ to use? pnpm
√ Installation in progress... ☕
🚀 Successfully created project nest-mental-whole
👉 Get started with the following commands:
$ cd nest-mental-whole
$ pnpm run start
Thanks for installing Nest 🙏
Please consider donating to our open collective
to help us maintain this package.
🍷 Donate: https://opencollective.com/nest
三、运行项目并关联git仓库
按照提示,进入项目,并执行 start 即可运行项目。
$ cd nest-mental-whole
$ pnpm start
# 提示信息
nest start
DeprecationWarning: 'getMutableClone' has been deprecated since v4.0.0. Use an appropriate `factory.update...` method instead, use `setCommentRange` or `setSourceMapRange`, and avoid setting `parent`.
[Nest] 104412 - 2022/11/29 18:43:16 LOG [NestFactory] Starting Nest application...
[Nest] 104412 - 2022/11/29 18:43:16 LOG [InstanceLoader] AppModule dependencies initialized +53ms
[Nest] 104412 - 2022/11/29 18:43:16 LOG [RoutesResolver] AppController {/}: +9ms
[Nest] 104412 - 2022/11/29 18:43:16 LOG [RouterExplorer] Mapped {/, GET} route +5ms
[Nest] 104412 - 2022/11/29 18:43:16 LOG [NestApplication] Nest application successfully started +3ms
可以看到是一个热更新状态的服务。
浏览器访问 http://localhost:3000/ ,页面能看到 Hello World!
即证明,服务启动正常。
提示:
- nest项目默认在3000端口启动,可以在src → main.ts中修改 app.listen(3000)
四、配置 pretier 和 eslint
进入项目以后,其实可以看到模板项目已经配置了 pretier 和 eslint,并初始化了 git 仓库。
五、认识模板项目
既然要基于这个模板项目进行功能集成,所以首先要了解一下模板项目。知道现在满足了哪些功才能进一步进行功能集成。
1.根目录
首先看到的是 .eslintrc.js .prettierrc .gitignore 这三大件,每个项目都会有。
初始化了一个 README.md,告诉项目怎么启动。
tsconfig.json 声明 ts 的自定义配置。tsconfig.build.json 则声明了 ts 在build 的时候的一些自定义配置。
详细看一下的就是package.json了:(我标注了一下几个不太常见的包)
{
"name": "nest-mental-whole",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^8.0.0",
"@nestjs/core": "^8.0.0",
"@nestjs/platform-express": "^8.0.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
},
"devDependencies": {
"@nestjs/cli": "^8.0.0",
"@nestjs/schematics": "^8.0.0",
"@nestjs/testing": "^8.0.0",
"@types/express": "^4.17.13",
"@types/jest": "27.5.0",
"@types/node": "^16.0.0",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "28.0.3", // 单元测试
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3", // 测试用例
"ts-jest": "28.0.1",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.0.0", // 别名设置
"typescript": "^4.3.5"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
其实看到这些依赖,我了解到了一点,nest 的底层其实是express。
2. 核心代码 src/*
这里总共有 5 个文件。
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();
可见,项目引入了 AppModule ,并使用 express 的方式就启动了这个服务。
然后跟着看 AppModule.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 {}
这里面 引入了 AppController 和 AppService 。这样就组成了整个项目。
问题1:Hello World 哪里来的呢?
查找了一下,在 AppService 里面有个 getHello 的方法,返回了这个字符串。
// app.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
问题2:getHello 这个方法怎么触发的?
看到 AppController 中有个 @Get
修饰符修饰的 getHello
的方法,里面调用了 service
里面的 getHello
方法。
// app.controler.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();
}
}
至此,结合我们访问 http://localhost:3000/ 就能看到返回的字符串。可以理解到,nest 是根据 /
这一层路由,经过 get 请求访问到接口返回的数据。
实际上也是这样的,nest里面的接口是按照模块进行划分的,每一层路由都是一个模块,由 controller 声明路由地址,并在 controller 中调用 service 中的具体业务逻辑,返回结果。
然后所有的业务逻辑都在 service 里面,
下一步计划
- 配置项目静态资源,混编 html,进一步抽离,使用 ajax 请求接口并返回数据。
- 连接 mysql,并从 数据库 获取数据。
参考文档
转载自:https://juejin.cn/post/7171403689029009438