logologo
文档仓库
文档仓库
logologo
开始

概述

第一步
控制器
提供者
模块
中间件
异常过滤器
管道
守卫
拦截器
自定义装饰器

基础

自定义提供程序
异步提供者
动态模块
注入作用域
循环依赖
模块引用
懒加载模块
执行上下文
生命周期事件
发现服务
平台无关
单元测试

技术

配置
SQL
Mongo
验证
缓存
序列化
版本控制
任务调度
队列
日志
Cookies
事件
压缩
文件上传
文件流
HTTP 模块
Session
MVC
性能(Fastify)
SSE

安全

认证
授权
加密与哈希
Helmet
CORS
CSRF
速率限制

GraphQL

快速开始
解析器
变更
订阅
标量
指令
接口
联合与枚举
字段中间件
类型映射
插件
复杂度
扩展
CLI 插件
生成SDL
共享模型
其他功能
联邦

WebSocket

网关
异常过滤器
管道
守卫
拦截器
适配器

微服务

基础
Redis
MQTT
NATS
RabbitMQ
Kafka
gRPC
自定义传输
异常过滤器
管道
守卫
拦截器
部署
独立应用程序

CLI

概述
工作区
库
用法
脚本

OpenAPI

介绍
装饰器
类型映射
操作
其他特性
安全
类型与参数
CLI 插件

实用示例

REPL
CRUD生成器
SWC
Passport(认证)
热重载
MikroORM
TypeORM
Mongoose
Sequelize
路由模块
Swagger
健康检查
CQRS
Compodoc
Prisma
Sentry
静态资源
Commander
异步本地存储
Necord
套件(原Automock)

常见问题

Serverless
HTTP 适配器
长连接
全局前缀
原始请求体
混合应用
HTTPS & 多服务器
请求生命周期
错误

开发工具

概述
CI/CD
迁移指南
API参考(官方)

生态与案例

谁在用
精彩资源

支持

支持

社区

贡献者

最后更新于: 2025/11/18 02:11:37

上一页工作区
下一页用法

#库

许多应用程序需要解决相同的通用问题,或在多种不同场景中复用模块化组件。Nest 提供了几种解决方式,每种方式在不同层面上处理问题,以满足不同的架构和组织目标。

Nest 模块能为组件共享提供执行上下文,适用于单一应用内部。这些模块还可通过 npm 打包,创建可复用的库并安装到不同项目中。这是分发可配置、可复用库的有效方式,适用于松散关联或无关联的不同组织(例如通过分发/安装第三方库)。

在组织严密的群体(如公司/项目内部)中共享代码时,采用更轻量级的组件共享方式会很有帮助。为此出现了 monorepo 这种结构,而在 monorepo 中, 库提供了一种简单轻便的代码共享方式。在 Nest monorepo 中,使用库可以轻松组装共享组件的应用程序。实际上,这鼓励了将单体应用和开发流程分解,专注于构建和组合模块化组件。

#Nest 库

Nest 库是一种不同于应用程序的 Nest 项目,它无法独立运行。库必须被导入到容器应用程序中才能执行其代码。本节描述的内置库支持仅适用于 monorepo(标准模式项目可以通过 npm 包实现类似功能)。

例如,一个组织可以开发一个 AuthModule 模块,通过实施管理所有内部应用的公司策略来处理认证。与其为每个应用单独构建该模块,或通过 npm 物理打包代码并要求每个项目安装它,monorepo 可以将此模块定义为一个库。这样组织时,库模块的所有使用者都能看到 AuthModule 提交时的最新版本。这对协调组件开发与组装、简化端到端测试具有显著优势。

#创建库

任何适合复用的功能都可以考虑作为库来管理。决定哪些部分应该成为库、哪些应该保留在应用中,这是一个架构设计决策。创建库不仅仅是简单地将代码从现有应用复制到新库中。当被打包为库时,库代码必须与应用解耦。这可能需要更多前期时间,并强制做出一些在紧密耦合代码中可能不会遇到的设计决策。但当该库能够用于跨多个应用实现更快速的应用组装时,这些额外努力将得到回报。

要开始创建库,请运行以下命令:

$ nest g library my-library

运行该命令时,library 原理图会提示您输入库的前缀(又称别名):

您希望为该库使用什么前缀(默认:@app)?

这会在您的工作空间中创建一个名为 my-library 的新项目。库类型项目与应用类型项目一样,使用原理图生成到指定文件夹中。库在 monorepo 根目录的 libs 文件夹下管理。Nest 在首次创建库时会创建 libs 文件夹。

为库生成的文件与为应用生成的文件略有不同。执行上述命令后,libs 文件夹的内容如下:

libs
my-library
src
index.ts
my-library.module.ts
my-library.service.ts
tsconfig.lib.json

nest-cli.json 文件将在 "projects" 键下新增一个库的条目:

...
{
    "my-library": {
      "type": "library",
      "root": "libs/my-library",
      "entryFile": "index",
      "sourceRoot": "libs/my-library/src",
      "compilerOptions": {
        "tsConfigPath": "libs/my-library/tsconfig.lib.json"
      }
}
...

库与应用程序在 nest-cli.json 元数据中有两处不同:

  • "type" 属性设置为 "library" 而非 "application"
  • "entryFile" 属性设置为 "index" 而非 "main"

这些差异决定了构建过程如何正确处理库。例如,库通过 index.js 文件导出其函数。

与应用类型项目类似,每个库都有自己扩展自根目录(整个 monorepo 范围内)tsconfig.json 文件的 tsconfig.lib.json 文件。如有需要,您可以修改此文件以提供库特定的编译器选项。

您可以使用 CLI 命令构建该库:

$ nest build my-library

#使用库

有了自动生成的配置文件后,使用库就变得简单直接。我们该如何将 MyLibraryService 从 my-library 库导入到 my-project 应用中呢?

首先要注意,使用库模块与使用其他 Nest 模块相同。monorepo 的作用是以透明化的方式管理路径,使得导入库和生成构建现在变得直观。要使用 MyLibraryService,我们需要导入其声明模块。我们可以修改 my-project/src/app.module.ts 如下所示来导入 MyLibraryModule。

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MyLibraryModule } from '@app/my-library';

@Module({
  imports: [MyLibraryModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

注意上面我们在 ES 模块的 import 语句中使用了 @app 路径别名,这是我们之前执行 nest g library 命令时提供的 prefix。在底层,Nest 通过 tsconfig 路径映射来处理这一点。当添加库时,Nest 会像这样更新全局(monorepo)tsconfig.json 文件中的 "paths" 键:

"paths": {
    "@app/my-library": [
        "libs/my-library/src"
    ],
    "@app/my-library/*": [
        "libs/my-library/src/*"
    ]
}

简而言之,monorepo 与库功能的结合使得将库模块集成到应用程序中变得简单直观。

同样的机制支持构建和部署由库组成的应用程序。一旦导入 MyLibraryModule 后,运行 nest build 会自动处理所有模块解析,并将应用程序与库依赖项打包以供部署。monorepo 的默认编译器是 webpack,因此生成的发布文件会将所有转译后的 JavaScript 文件打包成单一文件。您也可以按照此处说明切换至 tsc 编译器。