NestJS入门之HelloWorld

在NodeJS编程语言中,Web服务框架排名第一非Express莫属。因为其结构清晰、用法简单易上手、扩展灵活(中间件)而被广泛使用。Javascript的先天优势同时又是一个非常重大的劣势就是弱类型,注定了不适合大规模的协作开发。为了解决这个问题,微软的TypeScript横空出世,而NestJS利用TypeScript的优势,将组件之间的解耦做到了一个新的高度。

特别值得一提的是,在Nest的官方文档中,一直在宣传他们的产品哲学:从Angular、React和Vue中得到的启发,在后端的开发中,面对大量优秀的类库,却没有一个有效解决架构问题的产品。而Nest的诞生,就是为了提供一个开箱即用的架构,实现了各种类库之间的松耦合。因此,严格意义上定义NestJS并不是一款Web服务框架,而是一个IoC容器(IoC Container ),关于更多的IoC以及相关的内容,有兴趣的同学可以参考我的另外一篇文章

NestJS并没有去重新发明轮子,而是利用现有优秀的轮子,例如Express、Fastify,将其抽象、定义接口和适配,使之成为应用程序架构中的功能实现,开发者可以很方便的替换之。除了Web框架,还有数据库、队列、缓存等的常用类库。NestJS将其一一重新定义,纳入自己的扩展矩阵中。

了解一个项目,需要从其项目的文件目录 结构入手。就如同了解人体构造,先脱衣服从其骨骼结构切入点,逐个分析其构成与关系,才能高效的学习与了解其设计用意以及最佳实践方法。

案例库准备

为了更好的学习,强烈建议下载两个库:

第一个是nest源代码库。在学习的时候,有些不明白的地方可以去找源代码中寻找的相关信息。另外,这个源代码库里还有29个案例,可以给一定的参考。但是千万别纠结,正如官方文档一样(的糟糕),仅仅是参考一下。

git clone github.com/nestjs/nest

Real world一个面向“真实”需求的学习项目,被人们用各种语言和框架实现。而NestJS作为一款后端框架,热门从程度仅次于.net core总排名四的项目。从这方面,可见其日渐受追捧的趋势。

git clone github.com/lujakob/nes…

创建项目

创建一个最简单的项目

  1. 全局安装NEST命令行工具(脚手架) npm i -g @nestjs/cli(留意权限)

  2. 在工作目录中创建一个项目 nest n -g project-name

此时已经获得一个最基本的NEST的服务器端应用

目录

  • dist TypeScript文件编译为JS后输出的目标目录;
  • node_modules 依赖组件和库文件
  • src 源代码文件

根目录下文件

  • .gitignore GIT忽略配置,通常忽略的有:
    • 日志文件 logs *.log
    • 系统配置文件 .DS_Store
    • 依赖库 node_modules
    • IDE配置文件 .idea
    • 项目配置文件
    • 输出目标代码 dist/*
  • .eslintrc.js eslint(代码格式化)配置文件
  • .prettierrc prettier(代码格式化)配置文件
  • nest-cli.json nest项目配置文件,标准模式下这个配置文件内容很简单,如果是monorepo模式,则内容较为复杂。
  • nodemon.json,监控程序配置文件,定义监控那些程序忽略那些程序以及启动入口(index.js)
  • tsconfig.json,ts配置文件,其中排除了对测试文件的编译

文件名后缀含义

  • *.middleware.ts 中间件
  • *.controller.ts 控制器
  • *.decorator.ts 自定义装饰器
  • *.entity.ts 数据对象实例(typeorm)
  • *.interface.ts 接口
  • *.module.ts NEST模块
  • *.service.ts NEST服务对象
  • *.pipe.ts NEST管道对象
  • *.dto.ts 数据传输对象
  • *.spec.ts 单元测试文件

运行脚本

通过分析一下package.json文件,可以看到有很多可以选择的脚本,以下所有的脚本,都可以npm run xxx或者yarn run xxx的方式运行,取决于你的包管理工具。例如,启动项目 npm run start

  • prebuild 删除dist目录,为重新完整构建做准备(每次构建时,nest会自动执行这个);
  • build 构建当前工作区nest项目,会产生一个dist目录,其中是经过编译的代码
  • format 使用prettier格式化当前项目的代码
  • start 启动当前项目
  • start:dev 以开发模式启动当前项目,相比上面的start,区别是你可以边开发边调试程序,当发生文件被改动(保存),nest会自动重新加载;
  • start:debug 开发模式下,输出更多的调试信息;
  • start:prod 以生产模式运行,此时项目不在运行再nest cli中,而是直接运行编译后的项目;
  • lint 格式化所有ts代码,并修正代码的格式问题;
  • test 运行jest进行测试;
  • test:watch 同上,程序文件变化后自动测试;
  • test:cov 输出测试覆盖信息;
  • test:debug 运行一个websocket是的在浏览器中可以直接调试;
  • test:e2e 根据配置文件进行测试;

回到上面我们刚刚创建的项目,建议在开发时,用start:debug的脚本启动项目,可以边开发边调试。默认情况下Nest会绑定本地地址的3000端口。

[1:56:37 PM] Starting compilation in watch mode...

[1:56:40 PM] Found 0 errors. Watching for file changes.

Debugger listening on ws://127.0.0.1:9229/99490139-0eda-41f4-9c3a-157a5b796364
For help, see: https://nodejs.org/en/docs/inspector
[Nest] 6861   - 01/01/2021, 1:56:41 PM   [NestFactory] Starting Nest application...
[Nest] 6861   - 01/01/2021, 1:56:41 PM   [InstanceLoader] AppModule dependencies initialized +31ms
[Nest] 6861   - 01/01/2021, 1:56:41 PM   [RoutesResolver] AppController {}: +10ms
[Nest] 6861   - 01/01/2021, 1:56:41 PM   [RouterExplorer] Mapped {, GET} route +4ms
[Nest] 6861   - 01/01/2021, 1:56:41 PM   [NestApplication] Nest application successfully started +3ms
复制代码

调试工具

一般情况下我们会以两种方式对Web应用进行调试,前后端分离和前后端混合模式(Html模板)。前者调试需要借助一些工具,后者则直接使用浏览器。

API调试方式

调试工具可以选择Postman或者curl命令。

浏览器调试

浏览器无外乎Chrome和Firefox。浏览器的开发者工具还是很有必要了解和掌握一下的,以Chrome的DeveloperTools为例,重点建议掌握使用Console和Network两个关键工具。

当以调试模式启动应用程序时,会有一个WebSocket的接口开放,此时可以利用调试工具,进行跟踪。

npm run start:debug
[11:53:37 AM] File change detected. Starting incremental compilation...
[11:53:37 AM] Found 0 errors. Watching for file changes.
Debugger listening on ws://127.0.0.1:9229/7b6002c0-cb14-4b07-9bcc-65b0f353732e
复制代码

打开Chrome,地址栏输入chrome://inspect

  1. 在界面中点"Configure..."按钮
  2. 输入启动Nest报告中的ws的地址,关键是那个端口
  3. 完成后,会在界面中多出一个目标(Target),并标记了Node的版本号,点inspect,即可打开调试窗口,前后台可以同时调试。

这个方式在本地开发情景下比较鸡肋(因为直接用VSCode也能看到调试信息),在远程开发的话就比较实用了。注意绑定的本机的IP地址。

NEST命令行工具

nest --help

可以列出命令行的主要命令以及帮助,简单翻译一下如下:

创建

  • new(简写n)[options] [name] :创建一个NEST应用,例如 nest n hello-world。选项中支持:
    • --directory 指定目标目录
    • -d或--dry-run 不输出创建过程中的报告
    • -g或--skip-git 不要初始化git仓库(默认是会在项目创建git仓库)
    • -s或--skip-install 不要安装依赖哭
    • -p或--package-manager [name] 指定包管理工具
    • -l或--language [lang] 指定语言JS或者TS
    • -c或--collection [name] 用特定的架构生成项目

构建

  • build [options] [app] : 构建项目,默认会将TS文件构建到项目的dist目录中;options有:
    • -c或--config [path] 用cli构建时特定的配置文件
    • -p或--path [path] tsconfig配置文件
    • -w或--watch 实时重加载,观察模式
    • --watchAssets 观察非ts文件模式
    • --webpackPath [path] webpack的配置文件
    • --tsc 使用tsc编译

运行

  • start [options] [app]:运行NEST项目,options有:
    • -c或--config [path] 用cli构建时特定的配置文件
    • -p或--path [path] tsconfig配置文件
    • -w或--watch 实时重加载,观察模式
    • --watchAssets 观察非ts文件模式
    • -d或--debug [hostport] 调试模式
    • --webpack用webpack编译
    • --webpackPath [path] webpack的配置文件
    • --tsc 使用tsc编译
    • -e或--exec [binary] 以二进制运行(默认用node)
    • --preserveWatchOutput tsc的观察模式

更新

  • update或u [options]:更新当前项目的依赖组件
    • -f或--force 强制重新安装依赖
    • -t或--tag 升级被打上(latest | beta | rc | next tag)的组件

生成

  • generate或g [options] <schematic> [name] [path] 创建一个Nest架构元素,其类型如下表:
名称 别名 说明
application application 在工作区中创建一个新的应用
class cl 新的类
configuration config 命令行的配置文件
controller co 控制器
decorator d 自定义装饰器
filter f 过滤器
gateway ga 请求的网关
guard gu 守卫
interceptor in 拦截器
interface interface 接口
middleware mi 中间件
module mo 模块
pipe pi 管道
provider pr 功能组
resolver r GraphQL处理器
service s 服务
library lib 单独库模式下创建一个库
sub-app app 子应用
resource res 一个数据模型的CRUD

以上这张表差不多囊括了NEST所有的元素定义,在这里给自己挖个大坑,未来一段时间,慢慢填上。

其他

  • add [options] <library> 添加对外部库的支持
  • info或i 获取当前NEST项目的详细情况