🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 库 很多应用需要处理类似的问题,或者说是在不同上下文中重用模块化组件。Nest提供了一系列方法来实现这个,每个方法在不同层面上面向不同的架构或组织目标来解决问题。 `Nest` 模块对于提供执行上下文非常有用,它支持在单个应用程序中共享组件。模块还可以与 `npm` 打包,可以在不同项目中创建可重用库。这是一种分发可配置、可重用的库的有效方法,这些库可以由不同的、松散连接的或不可靠的组织使用(例如,通过分发/安装第三方库)。 对于在组织严密的组内共享代码(例如,在公司/项目边界内),使用更轻量级的方法来共享组件是很有用的。`Monorepo` 的出现是为了实现这一点,在 `Monorepo` 中,库以一种简单、轻量级的方式提供了一种共享代码的方式。在 `Nest monorepo` 中,使用库可以方便地组装共享组件的应用程序。事实上,这鼓励了对独立应用程序和开发过程的分解,将重点放在构建和组合模块化组件上。 ### Nest库 `Nest` 库是一个与应用程序不同的 `Nest` 项目,因为它不能独立运行。必须将库导入到包含它的应用程序中才能执行它的代码。本节中描述的对库的内置支持仅适用于 `monorepos` (标准模式项目可以使用 `npm` 包实现类似的功能)。 例如,组织可以开发一个 `AuthModule`,通过实现控制所有内部应用程序的公司策略来管理身份验证。 `monorepo` 可以将这个模块定义为一个库,而不是为每个应用程序单独构建那个模块,或者使用 `npm` 物理地打包代码并要求每个项目安装它。当以这种方式组织时,库模块的所有使用者在提交 `AuthModule` 时都可以看到它的最新版本。这对于协调组件开发和组装,以及简化端到端测试有很大的好处。 ### 创建库 任何适合重用的功能都可以作为库来管理。决定什么应该是库,什么应该是应用程序的一部分,是一个架构设计决策。创建库不仅仅是将代码从现有应用程序复制到新库。当打包为库时,库代码必须与应用程序解耦。这可能需要更多的预先准备时间,并迫使您做出一些设计决策,而这些决策可能不需要更紧密耦合的代码。但是,当库可以用于跨多个应用程序实现更快速的应用程序组装时,这种额外的努力就会得到回报。 要开始创建一个库,运行以下命令: ```typescript nest g library my-library ``` 当您运行该命令时,库示意图会提示您输入库的前缀(即别名): ```bash What prefix would you like to use for the library (default: @app)? ``` 这将在工作区中创建一个名为 `my-library` 的新项目。与应用程序类型项目一样,库类型项目使用示意图生成到指定文件夹中。库是在 `monorepo` 根目录的 `libs` 文件夹下管理的。`Nest` 在第一次创建库时创建 `libs` 文件夹。 为库生成的文件与为应用程序生成的文件略有不同。执行以上命令后,`libs` 文件夹的内容如下: ```bash libs └──my-library │──src │ │── my-library.service.ts │ │── my-library.module.ts │ └── index.ts └── tsconfig.lib.json ``` `nest-cli.json` 文件将在“项目”键下为库添加一个新条目: ```bash ... { "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` 文件导出它的函数。 与应用程序类型的项目一样,每个库都有其自己的 `tsconfig.lib.json` 文件,该文件扩展了根 `tsconfig.json` 文件。 您可以根据需要修改此文件,以提供特定于库的编译器选项。 您可以使用 `CLI` 命令构建库: ```bash nest build my-library ``` ### 使用库 有了自动生成的配置文件,使用库就很简单了。我们如何将 `MyLibraryService` 从 `my-library` 库导入 `my-project` 应用程序? 首先,注意使用库模块与使用其他 `Nest` 模块是一样的。`monorepo` 所做的就是以一种导入库和生成构建现在是透明的方式来管理路径。要使用 `MyLibraryService` ,我们需要导入它的声明模块。我们可以修改 `my-project/src/app.module` 。按照以下步骤导入`MyLibraryModule`。 ```typescript 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 {} ``` 请注意,上面我们在模块导入行中使用了 `@app` 的路径别名,这是我们在上面的 `nest g library` 命令中提供的前缀。`Nest` 通过 `tsconfig` 路径映射处理此问题。 添加库时,`Nest` 会更新全局(`monorepo`)`tsconfig.json`文件的 `“paths”` 键,如下所示: ```json "paths": { "@app/my-library": [ "libs/my-library/src" ], "@app/my-library/*": [ "libs/my-library/src/*" ] } ``` 因此,简单地说,`monorepo` 和库特性的组合使将库模块包含到应用程序中变得简单和直观。 这种机制也支持构建和部署组成库的应用程序。导入 `MyLibraryModule` 之后,运行 `nest build` 将自动处理所有的模块解析,并将应用程序与任何库依赖项捆绑在一起进行部署。`monorepo` 的默认编译器是 `webpack`,因此生成的分发文件是一个文件,它将所有转换后的 `JavaScript` 文件打包成一个文件。