【Nest源码系列】从Nest源码目录设计,你能学到什么?

2,049 阅读4分钟

前言

Nest中有兼容不同http服务的适配器、装饰器语法、中间件机制等等,那这些是如何体现在Nest源码文件结构上的呢,一起来看看。

从GitHub下载一份源码,执行:

git clone --depth=1 --single-branch https://github.com/nestjs/nest.git

--depth=1会下载最近的单个commit,--single-branch来取单个分支,这样速度就快很多了,拉源码看一般都这么干,我这里拉的是10.2.7版本。

顶级目录

去除一些不相关的目录文件和隐藏文件夹,这些文件的作用如下:

根目录
|————benchmarks     # 官方存放性能测试相关的代码和脚本
|————integration    # 官方存放集成测试相关的代码和脚本,用于测试多个模块和组件之间相互交互的测试
|————packages       # 包含ts配置文件和官方仓库中所有的package的源代码
|————sample         # 官方提供可直接运行的项目示例代码
|————scripts        # 各种工具链的脚本,比如项目build、supertest集成测试、deploy部署等
|————tools          # 存放gulp工具打包、文件移动相关脚本,同时还有性能测试相关脚本工具

另外需要补充一点:

sample中存放项目示例代码,官网演示的实例代码也是用这里的,后面我们也会通过调试里面的项目来讲解不同核心模块的原理;

packages目录我们会重点关注,它包含了所有Nest包源代码;

tools存放gulp构建工具,Nest在打包的时候会将packages下的文件移动到node_modules中,core文件夹最后会通过@nestjs/core来引入,同时发布到npm上的也是这种模块包。

image-20231214132607670.png

packages目录

来具体看看packages下面都有哪些文件

packages目录
|————common
|————core
|————microservices
|————platform-express
|————platform-fastify
|————platform-socket.io
|————platform-ws
|————websockets
|————testing

common 目录

Nest公共模块文件夹,如:

  • decorator装饰器
  • exceptions异常处理类
  • enums枚举类
  • utils工具类
  • ...

这些是全平台通用的API,比如装饰器、http状态码、http请求方式、异常处理等这些都是一样的,属于同一套抽象,不可能不同平台搞出不一样的抽象出来,下面先简单看看:

Request请求对象装饰器:

image-20231214001314460.png

http状态码枚举类:

image-20231214001419510.png

core 目录

Nest重头戏,包含基础架构和核心模块,是我们重点关注的文件夹,它里面有:

  • adapters适配器
  • discovery查找器
  • guards守卫
  • interceptors拦截器
  • router路由程序
  • middlewares中间件
  • services服务
  • ...

我们在写Nest项目时会高频使用到这些模块,后面会详细介绍,再来看看其他文件夹。

microservices目录

存放微服务模块,存放了用于创建客户端的Microservices Client,允许与Nest微服务甚至其他微服务(如Java、Python)进行通信交互,定义了Nest用于通信的各种协议接口,如gRPC、AMQP、NATS、Redis 等,还提供了与外部服务(如kafka、MQTT)进行消息通信。

如果不知道微服务,这就类比微前端,微前端就是借助这种思想衍生出来的,不同前端应用之间可以进行通信,Nest也可以。

接下来就是适配不同平台、不同场景的通信协议(框架)。

|————platform-express
|————platform-fastify
|————platform-socket.io
|————platform-ws
|————websockets

platform-express、platform-fastify

platform-express和platform-fastify是Nest中用于集成express和fastify服务器框架的,默认是使用Express作为基础框架,但Nest并不依赖他们之中任意一个。

而Fastify是一个更快速、低开销的 Web 框架,对性能要求高的应用场景会使用到它,Nest都兼容了,任开发者选择。

platform-socket.io、platform-ws

这两个模块都是为了在Nest中实现websocket通信而设计的,platform-socket.io是为了与Socket.IO 库进行集成,它提供了全双工通信的能力,一般应用在实时通信和推送的业务中,比如聊天室、实时数据更新这些。

另一方面,Nest也考虑了不使用Socket.IO库的场景,而是直接使用原生websocket进行通信,platform-ws可以支持对原生websocket的通信,一般应用在轻量级的双向通信场景,比如实时监控、实时数据交互等。

可以看到上面还有一个websockets文件夹,这个就是Nest实现websocket通信的核心逻辑,platform-socket.io和platform-ws这两个模块都需要依赖它。

image-20231214004932564.png

image-20231214005001863.png

小结

Nest核心的文件夹就这些,来总结一下从文件目录的设计上我们能看出什么:

  • 清晰一致性:文件夹结构应该清晰明了,遵循一致的命名规范
  • 分层结构:Nest中分层是做得很好的,如控制层、服务层、数据访问层
  • 模块化结构:代码按照功能模块组织,每个模块遵循单一职责原则并尽可能复用,如http状态码、程序关闭信号等,而在我们日常开发中,如订单流转状态、物流状态一样可以通过这种方式管理。
  • 遵循最佳实践:遵循特定的设计模式、代码风格,关于这点我们会在后面的讲解中逐步呈现Nest优雅之处。