likes
comments
collection
share

nestjs初体验及配置介绍

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

对于nestjs这个框架来说很早之前都想学习了。可是一直没有时间,最近时间比较充裕,就开启了nestjs的学习之路,也可以让自己以后向后端开发靠近。毕竟这个框架和其他后端语言的框架更贴切,而不像Koa. Express, Egg.js写起来那么随意。

nestjs同其他nodejs框架的优势

  • 基础环境无需花时间准备,有CLI工具,开发效率高
  • 无惧技术选型,更容易找到行业内的标杆或成熟方案
  • 由于采用比较优秀的架构,扩展性更好,较低成本重构逻辑
  • 代码架构合理,装饰器语法,概念比较多;
  • TS原生支持,体验好,项目的代码质量高;
  • 对于代码人员的要求更高,上手有难度(Egg.js/Express/koa)

nestjs架构

默认是通过express提供http服务的,也可以选择高性能的fastify。 nestjs初体验及配置介绍

Nodejs框架特点对比

  • koa实现web服务的特点

只实现了web服务,路由,日志,请求拦截器等需要自己实现。该库逻辑轻量,容易理解。

  • eggjs实现web服务的特点

实现了路由和分层架构及CMD规范,但是它非ts编写,不利于大型项目的维护开发。

  • nestjs实现web服务的特点

实现了路由和逻辑分层,并原生支持ts,内部封装了很多装饰器(注解)类似Java,可以让项目更健壮。

总结:

  • Koa&Express本身只实现了HTTP服务,中间逻辑需自己实现。
  • Egg.js有合理的逻辑分层,但TS支持不好。
  • Nest.js生态最好,使用TS+注解的方式更便捷。并且官方提供了一个好用的脚手架,可以快速创建对应的层级模板,初始化一个完整的项目。

后端服务涉及的内容

nestjs初体验及配置介绍

nestjs初体验及配置介绍

nestjs初体验

创建项目

npm i -g @nestjs/cli
nest new <project-name>

利用nest提供的脚手架命令创建对应的功能模板

nestjs初体验及配置介绍

学习nestjs模板demo项目

这里是一些功能性demo案例

npm install -g deget

deget 克隆仓库时,不会将git历史依赖克隆下来。

deget gitPath <dirname>

工程目录

命名规则可以查看这里

代码调试

我们知道,在开发前端应用程序时只需要卸载debugger,即可在浏览器中进行debugger,但是对于后端程序来说,我们只能在编辑器中进行调试。

nestjs初体验及配置介绍

nestjs初体验及配置介绍

nestjs初体验及配置介绍

或者我们直接运行yarn start:debug脚本,可以在浏览器中直接调试。

nestjs初体验及配置介绍

一些常见的编程名词

OOP 面向对象编程

将一个具体的事物拆分成一个个独立的对象,通过调用其中的方法去解决问题。有三种特性:封装,继承,多态。

FP 函数式编程

确定的输入有确定的输出,没有副作用。也是一种声明式编程,现在主流的前端框架都是这种方式。只关注结果不关注过程。

AOP 面向切面编程

扩展功能的一种方式,不影响原有功能。逻辑集中管理,更有利于代码复用。即能在不破坏封装功能的前提下额外增加新功能。

IOC 控制反转

将强依赖的内容抽离成一个参数传入,从而进行解耦。

DI 依赖注入

一种用于实现IOC的设计模式,他允许在类外创建依赖对象,并通过不同的方式将这些对象提供给类。

DTO 数据传输对象,DAO 数据访问对象

nestjs初体验及配置介绍

nestjs生命周期

nestjs初体验及配置介绍

nestjs初体验及配置介绍

核心概念

nestjs初体验及配置介绍

开发配置介绍

环境变量配置

  • dotenv: 只能在配置文件中填写key=value形式,对于嵌套格式数据,不方便开发。更适合前端项目中多环境的配置。这个也是nestjs内部读取环境变量集成的库。
  • config: 可以在config/*中写yaml,json等格式的配置文件,解析时可以直接读取嵌套结构属性。更适合后端项目中多环境的配置。

nestjs内部环境配置

  • 安装@nestjs/config
  • 文件根目录下配置环境变量文件.env.*
  • app.module.ts中使用
import { ConfigModule } from '@nestjs/config';

@Module({
  // 导入模块
  // ConfigModule.forRoot 加载环境变量
  imports: [
    ConfigModule.forRoot({
      // 将环境变量在全部文件模块中导入
      isGlobal: true,
    }),
    UserModule,
  ],
  // 注册控制器
  controllers: [AppController, UserController],
  // 依赖注入,在控制器中自动实例化该服务
  providers: [AppService, UserService],
})
  • 使用
import { ConfigService } from '@nestjs/config';
// 依赖注入,自动实例化
 constructor(
    private userService: UserService,
    private config: ConfigService,
  ) {}
  
  const envConfig = this.config;
  console.log('db, db_url', envConfig.get('DB'), envConfig.get('DB_URL'));

根据运行环境来加载不同配置文件。

  • 我们需要借助cross-env库来帮助我们修改nodejs运行的环境变量。
  • 通过process.env去读取NODE_ENV变量,当前运行的是哪个环境。
  • 通过nestjsconfig配置属性envFilePath来设置对应的环境变量文件路径。
import { ConfigModule } from '@nestjs/config';

const envFilePath = `.env.${process.env.NODE_ENV || 'development'}`;
@Module({
  // 导入模块
  // ConfigModule.forRoot 加载环境变量
  imports: [
    ConfigModule.forRoot({
      // 将环境变量在全部文件模块中导入
      isGlobal: true,
      // 设置读取的环境变量文件
      envFilePath,
    }),
    UserModule,
  ],
  // 注册控制器
  controllers: [AppController, UserController],
  // 依赖注入,在控制器中自动实例化该服务
  providers: [AppService, UserService],
})
  • 修改运行的脚本命令
"start:dev": "cross-env NODE_ENV=development nest start --watch",
"start:prod": "cross-env NODE_ENV=production node dist/main",

提取通用配置,否则在一些特定配置需要写多次。

  • 安装dotenv包来加载.env文件并解析。
  • 通过nestjsconfig配置属性load来加载自定义环境变量。
import { ConfigModule } from '@nestjs/config';
import * as dotEnv from 'dotenv';

const envFilePath = `.env.${process.env.NODE_ENV || 'development'}`;
@Module({
  // 导入模块
  // ConfigModule.forRoot 加载环境变量
  imports: [
    ConfigModule.forRoot({
      // 将环境变量在全部文件模块中导入
      isGlobal: true,
      // 设置读取的环境变量文件
      envFilePath,
      // 加载自定义配置文件数组。这里可以加载提取出的相同配置文件属性
      load: [() => dotEnv.config({ path: '.env' })],
    }),
    UserModule,
  ],
  // 注册控制器
  controllers: [AppController, UserController],
  // 依赖注入,在控制器中自动实例化该服务
  providers: [AppService, UserService],
})

以上就是在开发中使用最多的读取配置环境的情况了。

嵌套设置环境变量,减少代码冗余。这种只适合配置文件特别复杂的情况下。

  • 可以通过js-yaml库解析yaml文件,然后加入到nestjsconfig配置属性load来加载自定义环境变量。
  • 也可以直接使用第三方零配置库config进行读取。

nestjs初体验及配置介绍 使用,他会根据NODE_ENV环境的不同去合并default.json和对应环境的json文件。并且他也会自动解析yaml后缀的文件。

import * as config from 'config';
console.log('====config', config.get('db.db_url')); // 类似于lodash的get方法

验证配置参数

其实这块也不需要校验啥,配置都是开发者自己设置的,一般不会改动。为了项目更健壮,做一些校验也未尝不可。

官方推荐使用joi库进行校验。结合nestjsconfig配置属性validationSchema进行校验。 注意他只能验证envFilePath加载的配置文件,不能验证load加载的配置。

import { ConfigModule } from '@nestjs/config';
import * as dotEnv from 'dotenv';
import * as Joi from 'joi';

const envFilePath = `.env.${process.env.NODE_ENV || 'development'}`;
@Module({
  // 导入模块
  // ConfigModule.forRoot 加载环境变量
  imports: [
    ConfigModule.forRoot({
      // 将环境变量在全部文件模块中导入
      isGlobal: true,
      // 设置读取的环境变量文件
      envFilePath,
      // 加载自定义配置文件数组。这里可以加载提取出的相同配置文件属性
      load: [() => dotEnv.config({ path: '.env' })],
      // 验证环境变量(只能验证特定环境的配置文件,不能验证load中加载的)
      validationSchema: Joi.object({
        // 验证DB_PORT变量,并设置默认值为3306
        DB_PORT: Joi.number().valid(3306),
      }),
    }),
    UserModule,
  ],
  // 注册控制器
  controllers: [AppController, UserController],
  // 依赖注入,在控制器中自动实例化该服务
  providers: [AppService, UserService],
})

以上就是nestjs开发的简单总结,这里需要感谢Brian老师。