Skip to content

Commit 5504747

Browse files
authored
Merge pull request #417 from cyber-copy/fix
Fix: fix some url && code block format
2 parents fcebe5d + 0bcb650 commit 5504747

File tree

18 files changed

+34
-39
lines changed

18 files changed

+34
-39
lines changed

docs/cli/workspaces.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ Nest 有两种代码组织模式:
2727

2828
```bash
2929
$ nest new my-project
30-
```typescript
30+
```
31+
3132
我们已经构建了一个*标准模式*结构,其文件夹结构如下所示:
3233

3334
<div class="file-tree">

docs/faq/errors.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Nest 无法解析 <provider> 的依赖项(?)。请确保索引 [<index>] 处
2222
})
2323
```
2424

25-
导致此错误最常见的原因是没有将 `<provider>` 放入模块的 `providers` 数组中。请确保该提供者确实位于 `providers` 数组中,并遵循[标准 NestJS 提供者实践](./fundamentals/custom-providers#di-基础)
25+
导致此错误最常见的原因是没有将 `<provider>` 放入模块的 `providers` 数组中。请确保该提供者确实位于 `providers` 数组中,并遵循[标准 NestJS 提供者实践](./fundamentals/dependency-injection#di-基础)
2626

2727
有几个常见的陷阱需要注意。其中之一是将提供者放入了 `imports` 数组中。如果是这种情况,错误消息中会在 `<module>` 应该出现的位置显示提供者的名称。
2828

@@ -32,7 +32,7 @@ Nest 无法解析 <provider> 的依赖项(?)。请确保索引 [<index>] 处
3232

3333
如果上方的 `<unknown_token>` 显示为 `Object`,说明您正在使用没有提供者令牌的类型/接口进行注入。要解决此问题,请确保:
3434

35-
1. 您已导入类引用或使用带有 `@Inject()` 装饰器的自定义令牌。请阅读[自定义提供者页面](./fundamentals/custom-providers),以及
35+
1. 您已导入类引用或使用带有 `@Inject()` 装饰器的自定义令牌。请阅读[自定义提供者页面](./fundamentals/dependency-injection),以及
3636
2. 对于基于类的提供者,您导入的是具体类而不仅仅是 [`import type ...`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export) 语法引入的类型。
3737

3838
同时请确保没有出现提供者自我注入的情况,因为 NestJS 不允许自我注入。当发生这种情况时,`<unknown_token>` 很可能会等于 `<provider>`

docs/fundamentals/async-components.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
```
1616

1717
:::info 提示
18-
了解更多关于自定义提供者语法的信息,请点击[此处](/fundamentals/custom-providers)
18+
了解更多关于自定义提供者语法的信息,请点击[此处](/fundamentals/dependency-injection)
1919
:::
2020

2121
#### 注入

docs/fundamentals/dependency-injection.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
### 自定义提供程序
1+
# 自定义提供程序
22

33
在前面的章节中,我们简要介绍了**依赖注入(DI)** 及其在 Nest 中的应用。其中一个例子就是通过[基于构造器](../overview/providers#依赖注入)的方式将实例(通常是服务提供者)注入到类中。您应该不会感到意外,依赖注入实际上是 Nest 核心功能的基石。目前为止我们只探讨了其中一种主要模式。随着应用程序日益复杂,您可能需要充分利用 DI 系统的全部功能,下面让我们深入探索这些特性。
44

@@ -63,7 +63,7 @@ export class AppModule {}
6363
constructor(private catsService: CatsService)
6464
```
6565

66-
3.`app.module.ts` 中,我们将 `CatsService` 令牌与来自 `cats.service.ts` 文件的 `CatsService` 类进行关联。我们将在[下文](/fundamentals/custom-providers#标准提供者)看到这种关联(也称为*注册* )具体是如何发生的。
66+
3.`app.module.ts` 中,我们将 `CatsService` 令牌与来自 `cats.service.ts` 文件的 `CatsService` 类进行关联。我们将在[下文](/fundamentals/dependency-injection#标准提供者)看到这种关联(也称为*注册* )具体是如何发生的。
6767

6868
当 Nest IoC 容器实例化 `CatsController` 时,它首先查找所有依赖项\*。当找到 `CatsService` 依赖项时,容器会对 `CatsService` 令牌执行查找操作,根据注册步骤(上面的#3 步骤)返回 `CatsService` 类。假设是 `SINGLETON` 作用域(默认行为),Nest 将创建 `CatsService` 实例并缓存后返回,或者如果已有缓存实例则直接返回现有实例。
6969

@@ -136,7 +136,7 @@ export class AppModule {}
136136

137137
#### 基于非类的提供者令牌
138138

139-
到目前为止,我们一直使用类名作为提供者令牌(即 `providers` 数组中列出的提供者里 `provide` 属性的值)。这与[基于构造函数的注入](../overview/providers#依赖注入)使用的标准模式相匹配,其中令牌也是类名。(如果这个概念不完全清楚,请回顾 [DI 基础](/fundamentals/custom-providers#di-基础)以复习令牌相关知识)。有时,我们可能需要使用字符串或符号作为 DI 令牌的灵活性。例如:
139+
到目前为止,我们一直使用类名作为提供者令牌(即 `providers` 数组中列出的提供者里 `provide` 属性的值)。这与[基于构造函数的注入](../overview/providers#依赖注入)使用的标准模式相匹配,其中令牌也是类名。(如果这个概念不完全清楚,请回顾 [DI 基础](/fundamentals/dependency-injection#di-基础概念)以复习令牌相关知识)。有时,我们可能需要使用字符串或符号作为 DI 令牌的灵活性。例如:
140140

141141
```typescript
142142
import { connection } from './connection';

docs/fundamentals/dynamic-modules.md

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
### 动态模块
1+
# 动态模块
22

3-
[模块章节](/modules)介绍了 Nest 模块的基础知识,并简要提及了[动态模块](../overview/modules#动态模块) 。本章将深入探讨动态模块的主题。学习完成后,您将充分理解它们的概念、使用方法及适用场景。
3+
[模块章节](/overview/modules)介绍了 Nest 模块的基础知识,并简要提及了[动态模块](/overview/modules#动态模块) 。本章将深入探讨动态模块的主题。学习完成后,您将充分理解它们的概念、使用方法及适用场景。
44

55
#### 介绍
66

7-
文档**概述**部分中的大多数应用代码示例都使用常规(静态)模块。模块定义了如[提供者](/providers)[控制器](/controllers)等组件的集合,这些组件作为整体应用的模块化部分协同工作。它们为这些组件提供了执行上下文或作用域。例如,模块中定义的提供者对该模块的其他成员可见,无需显式导出。当提供者需要在模块外部可见时,需先从其宿主模块导出,再导入到消费模块中。
7+
文档**概述**部分中的大多数应用代码示例都使用常规(静态)模块。模块定义了如[提供者](/overview/providers)[控制器](/overview/controllers)等组件的集合,这些组件作为整体应用的模块化部分协同工作。它们为这些组件提供了执行上下文或作用域。例如,模块中定义的提供者对该模块的其他成员可见,无需显式导出。当提供者需要在模块外部可见时,需先从其宿主模块导出,再导入到消费模块中。
88

99
让我们通过一个熟悉的示例来说明。
1010

@@ -53,31 +53,29 @@ export class AuthService {
5353

5454
我们将这称为**静态**模块绑定。Nest 连接模块所需的所有信息都已经在宿主模块和消费模块中声明完毕。让我们解析这个过程发生了什么。Nest 通过以下方式使 `UsersService``AuthModule` 中可用:
5555

56-
1. 实例化 `UsersModule`,包括递归导入 `UsersModule` 自身消费的其他模块,并递归解析所有依赖项(参见[自定义提供者](../fundamentals/dependency-injection) )。
56+
1. 实例化 `UsersModule`,包括递归导入 `UsersModule` 自身消费的其他模块,并递归解析所有依赖项(参见[自定义提供者](/fundamentals/dependency-injection) )。
5757
2. 实例化 `AuthModule`,并使 `UsersModule` 导出的提供者可用于 `AuthModule` 中的组件(就像它们原本就是在 `AuthModule` 中声明的一样)。
5858
3.`AuthService` 中注入 `UsersService` 的实例。
5959

6060
#### 动态模块使用场景
6161

62-
使用静态模块绑定时,消费模块无法**影响**主机模块中提供者的配置方式。为什么这一点很重要?考虑这种情况:我们有一个通用模块需要在不同使用场景中表现出不同行为。这与许多系统中的"插件"概念类似,通用功能需要先进行某些配置才能被消费者使用。
62+
使用静态模块绑定时,消费模块无法**影响**提供者在宿主模块中的配置方式。为什么这一点很重要?考虑这种情况:我们有一个通用模块需要在不同使用场景中表现出不同行为。这与许多系统中的"插件"概念类似,通用功能需要先进行某些配置才能被消费者使用。
6363

64-
Nest 框架中的一个典型示例是**配置模块**许多应用程序发现通过使用配置模块来外部化配置细节非常有用。这使得在不同部署环境中动态更改应用设置变得简单:例如为开发者使用开发数据库,为预发布/测试环境使用预发布数据库等。通过将配置参数的管理委托给配置模块,应用程序源代码得以与配置参数保持独立。
64+
Nest 框架中的一个典型示例是**配置模块**许多应用程序发现,通过使用配置模块将配置细节外部化非常有用。这使得在不同部署环境中动态更改应用设置变得简单:例如为开发者使用开发数据库,为预发布/测试环境使用预发布数据库等。通过将配置参数的管理委托给配置模块,应用程序源代码得以与配置参数保持独立。
6565

66-
挑战在于配置模块本身是通用的(类似于"插件"),需要由使用它的模块进行定制。这正是*动态模块*发挥作用的地方。利用动态模块特性,我们可以使配置模块**动态化** ,这样使用模块就能通过 API 控制在导入时如何定制配置模块。
66+
挑战在于配置模块本身是通用的(类似于"插件"),需要由使用它的模块进行定制。这正是**动态模块**发挥作用的地方。利用动态模块特性,我们可以使配置模块**动态化** ,这样使用模块就能通过 API 控制在导入时如何定制配置模块。
6767

6868
换句话说,动态模块提供了一个 API 用于将一个模块导入另一个模块,并在导入时定制该模块的属性和行为,这与我们目前所见的静态绑定方式形成对比。
6969

70-
<app-banner-devtools></app-banner-devtools>
71-
7270
#### 配置模块示例
7371

74-
我们将使用[配置章节](../techniques/configuration#服务)中示例代码的基础版本作为本节内容。本章节完成后的最终版本可在此处获取[完整示例](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules)
72+
我们将使用[配置章节](/techniques/configuration#服务)中示例代码的基础版本作为本节内容。本章节完成后的最终版本可在此处获取[完整示例](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules)
7573

7674
我们的需求是让 `ConfigModule` 能够接收一个 `options` 对象来实现自定义功能。以下是我们要支持的特性:基础示例中将 `.env` 文件的位置硬编码为项目根目录。假设我们希望使其可配置,这样您就可以将 `.env` 文件存放在任意选择的文件夹中。例如,您可能希望将各种 `.env` 文件存储在项目根目录下名为 `config` 的文件夹中(即与 `src` 文件夹同级)。您希望在不同项目中使用 `ConfigModule` 时能够选择不同的文件夹。
7775

7876
动态模块使我们能够向导入的模块传递参数,从而改变其行为。让我们看看这是如何实现的。如果从消费模块的角度出发,先设想最终效果,再逆向推导实现方式,会更有帮助。首先,快速回顾一下*静态*导入 `ConfigModule` 的示例(即无法影响被导入模块行为的传统方式)。请特别注意 `@Module()` 装饰器中 `imports` 数组的写法:
7977

80-
```typescript
78+
```typescript title="app.module.ts"
8179
import { Module } from '@nestjs/common';
8280
import { AppController } from './app.controller';
8381
import { AppService } from './app.service';
@@ -93,7 +91,7 @@ export class AppModule {}
9391

9492
现在让我们思考一下*动态模块*导入(传入配置对象的情况)会是什么样子。比较这两个示例中 `imports` 数组的区别:
9593

96-
```typescript
94+
```typescript title="app.module.ts"
9795
import { Module } from '@nestjs/common';
9896
import { AppController } from './app.controller';
9997
import { AppService } from './app.service';
@@ -211,7 +209,7 @@ export class ConfigService {
211209

212210
现在我们的 `ConfigService` 已经知道如何在 `options` 中指定的文件夹里找到 `.env` 文件。
213211

214-
我们剩下的任务是如何将 `register()` 步骤中的 `options` 对象注入到 `ConfigService` 中。当然,我们会使用*依赖注入*来实现这一点。这是关键点,请务必理解。我们的 `ConfigModule` 提供了 `ConfigService`,而 `ConfigService` 又依赖于仅在运行时提供的 `options` 对象。因此,在运行时,我们需要先将 `options` 对象绑定到 Nest IoC 容器,然后让 Nest 将其注入到 `ConfigService` 中。记得在**自定义提供者**章节中提到的,提供者可以[包含任何值](../fundamentals/dependency-injection#非基于服务的提供者) ,而不仅仅是服务,所以我们可以放心使用依赖注入来处理简单的 `options` 对象。
212+
我们剩下的任务是如何将 `register()` 步骤中的 `options` 对象注入到 `ConfigService` 中。当然,我们会使用*依赖注入*来实现这一点。这是关键点,请务必理解。我们的 `ConfigModule` 提供了 `ConfigService`,而 `ConfigService` 又依赖于仅在运行时提供的 `options` 对象。因此,在运行时,我们需要先将 `options` 对象绑定到 Nest IoC 容器,然后让 Nest 将其注入到 `ConfigService` 中。记得在**自定义提供者**章节中提到的,提供者可以[包含任何值](/fundamentals/dependency-injection#非基于服务的提供者) ,而不仅仅是服务,所以我们可以放心使用依赖注入来处理简单的 `options` 对象。
215213

216214
我们先解决将选项对象绑定到 IoC 容器的问题。这需要在静态的 `register()` 方法中完成。注意我们正在动态构建一个模块,而模块的属性之一就是它的提供者列表。因此我们需要将选项对象定义为一个提供者,这样它就能被注入到 `ConfigService` 中(下一步会用到这个特性)。在下面代码中,请特别注意 `providers` 数组:
217215

@@ -237,7 +235,7 @@ export class ConfigModule {
237235
}
238236
```
239237

240-
现在我们可以通过向 `ConfigService` 注入 `'CONFIG_OPTIONS'` 提供者来完成整个过程。注意当使用非类令牌定义提供者时,需要按照[这里的说明](../fundamentals/dependency-injection#非基于类的提供者令牌)使用 `@Inject()` 装饰器。
238+
现在我们可以通过向 `ConfigService` 注入 `'CONFIG_OPTIONS'` 提供者来完成整个过程。注意当使用非类令牌定义提供者时,需要按照[这里的说明](/fundamentals/dependency-injection#非基于类的提供者令牌)使用 `@Inject()` 装饰器。
241239

242240
```typescript
243241
import * as dotenv from 'dotenv';

docs/fundamentals/provider-scopes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { Injectable, Scope } from '@nestjs/common';
2929
export class CatsService {}
3030
```
3131

32-
同样地,对于[自定义提供者](/fundamentals/custom-providers) ,在提供者注册的长格式中设置 `scope` 属性:
32+
同样地,对于[自定义提供者](/fundamentals/dependency-injection) ,在提供者注册的长格式中设置 `scope` 属性:
3333

3434
```typescript
3535
{
@@ -240,7 +240,7 @@ import { Injectable, Scope } from '@nestjs/common';
240240
export class CatsService {}
241241
```
242242

243-
同理,对于[自定义提供者](/fundamentals/custom-providers) ,需要在提供者注册的长格式中设置 `durable` 属性:
243+
同理,对于[自定义提供者](/fundamentals/dependency-injection) ,需要在提供者注册的长格式中设置 `durable` 属性:
244244

245245
```typescript
246246
{

docs/fundamentals/unit-testing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ catsService = await moduleRef.resolve(CatsService);
114114
了解更多模块引用特性请[点击此处](/fundamentals/module-ref)
115115
:::
116116

117-
您可以用[自定义提供者](/fundamentals/custom-providers)覆盖任何生产环境的提供者实现来进行测试。例如,可以模拟数据库服务而非连接真实数据库。我们将在下一节讨论覆盖机制,该功能同样适用于单元测试场景。
117+
您可以用[自定义提供者](/fundamentals/dependency-injection)覆盖任何生产环境的提供者实现来进行测试。例如,可以模拟数据库服务而非连接真实数据库。我们将在下一节讨论覆盖机制,该功能同样适用于单元测试场景。
118118

119119
#### 自动模拟
120120

docs/graphql/subscriptions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ type Subscription {
271271

272272
#### PubSub
273273

274-
我们在上面实例化了一个本地 `PubSub` 实例。推荐的做法是将 `PubSub` 定义为 [provider](/fundamentals/custom-providers) 并通过构造函数注入(使用 `@Inject()` 装饰器)。这样我们就可以在整个应用程序中重用该实例。例如,按如下方式定义一个 provider,然后在需要的地方注入 `'PUB_SUB'`。
274+
我们在上面实例化了一个本地 `PubSub` 实例。推荐的做法是将 `PubSub` 定义为 [provider](/fundamentals/dependency-injection) 并通过构造函数注入(使用 `@Inject()` 装饰器)。这样我们就可以在整个应用程序中重用该实例。例如,按如下方式定义一个 provider,然后在需要的地方注入 `'PUB_SUB'`。
275275

276276
```typescript
277277
{

docs/microservices/basics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ constructor(
246246
`ClientsModule``ClientProxy` 类是从 `@nestjs/microservices` 包中导入的。
247247
:::
248248

249-
有时,您可能需要从其他服务(如 `ConfigService`)获取传输器配置,而不是在客户端应用中硬编码。为此,您可以使用 `ClientProxyFactory` 类注册[自定义提供者](/fundamentals/custom-providers) 。该类提供了静态方法 `create()`,该方法接收传输器选项对象并返回一个定制化的 `ClientProxy` 实例。
249+
有时,您可能需要从其他服务(如 `ConfigService`)获取传输器配置,而不是在客户端应用中硬编码。为此,您可以使用 `ClientProxyFactory` 类注册[自定义提供者](/fundamentals/dependency-injection) 。该类提供了静态方法 `create()`,该方法接收传输器选项对象并返回一个定制化的 `ClientProxy` 实例。
250250

251251
```typescript
252252
@Module({

docs/overview/exception-filters.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ export class AppModule {}
279279
```
280280

281281
:::info 注意
282-
使用此方法执行过滤器依赖注入时,需注意无论在哪一个模块中使用该构造,过滤器实际上是全局性的。应该在哪里进行操作呢?应选择过滤器(如上例中的 `HttpExceptionFilter`)被定义的模块。同时,`useClass` 并非处理自定义提供者注册的唯一方式。了解更多[请点击此处](/fundamentals/custom-providers)
282+
使用此方法执行过滤器依赖注入时,需注意无论在哪一个模块中使用该构造,过滤器实际上是全局性的。应该在哪里进行操作呢?应选择过滤器(如上例中的 `HttpExceptionFilter`)被定义的模块。同时,`useClass` 并非处理自定义提供者注册的唯一方式。了解更多[请点击此处](/fundamentals/dependency-injection)
283283
:::
284284

285285

0 commit comments

Comments
 (0)