likes
comments
collection
share

Nest项目(一)-项目概览及初始化项目

作者站长头像
站长
· 阅读数 11

前言

前段时间接触了 nest 框架,并使用该框架搭建了一个前后台分离项目。 但是做过以后就忘记了,为了简化以后搭建项目的成本,特此梳理并记录一下项目的搭建过程,并进行分享。

项目概览

项目是这样设计的:

  1. 具体业务是从数据库中拿出一些数据,对数据进行处理,服务端渲染 html 并完成上线流程。
  2. 然后在此基础上,抽离数据逻辑,使用 ajax 的方式实现页面好数据分离。
  3. 再进一步,统一处理请求体和返回体结构。
  4. 登录和权限管理。
  5. 上传和下载。

初始化项目

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项目(一)-项目概览及初始化项目

即证明,服务启动正常。

提示

  1. 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 里面,

下一步计划

  1. 配置项目静态资源,混编 html,进一步抽离,使用 ajax 请求接口并返回数据。
  2. 连接 mysql,并从 数据库 获取数据。

参考文档