## 工作空间
`Nest` 有两种组织代码的模式:
- **标准模式**: 用于构建具有自己的依赖项和设置、不需要优化共享模块或优化复杂,构建以项目为中心的应用程序。这是默认模式。
- **`monorepo`模式**: 该模式将代码工件作为轻量级 `monorepo` 的一部分,可能更适合开发团队或多项目环境。它自动化了构建过程的各个部分,使创建和组合模块化组件变得容易,促进了代码重用,使集成测试变得更容易,使共享项目范围内的工件(如 `tslint` 规则和其他配置策略)变得容易,并且比 `github` 子模块之类的替代方法更容易使用。`Monorepo` 模式采用了在 `nest-cli.json` 中表示工作区的概念,以协调 `monorepo` 组件之间的关系。
需要注意的是,实际上 `Nest` 的所有特性都与您的代码组织模式无关。此选择的惟一影响是如何组合项目以及如何生成构建构件。所有其他功能,从 `CLI` 到核心模块再到附加模块,在任何一种模式下都是相同的。
此外,您可以在任何时候轻松地从标准模式切换到 `monorepo` 模式,因此您可以延迟此决策,直到其中一种方法的好处变得更加明显。
### 标准模式
当您运行 `nest new` 时,将使用一个内置的示意图为您创建一个新项目。`Nest` 的做法如下:
1. 创建一个新文件夹,使用你提供给 `nest new` 的`name`相同的参数。
2. 用与最小的基础级 `Nest`应用程序对应的默认文件填充该文件夹。您可以在 [typescript-starter](https://github.com/nestjs/typescript-starter) 存储库中检查这些文件。
3. 提供其他文件,如 `nest-cli.json` 、 `package.json` 和 `tsconfig.json`。启用用于编译、测试和服务应用程序的各种工具。
从这里开始,你可以修改其他起始文件,添加新部件,添加依赖(例如`npm install`),或者依据本文指导进行开发。
### Monorepo模式
要启用 `monorepo` 模式,您可以从一个标准模式结构开始,然后添加 `project` 。 `project` 可以是一个完整的应用程序(使用 `nest generate app` 将一个应用程序添加到 `workspace` 中),也可以是一个库(使用 `nest generate lib` 将一个库添加到 `workspace` 中)。我们将在下面详细讨论这些特定类型的项目组件。现在要注意的关键点是将项目添加到现有的标准模式结构中,然后将其转换为 `monorepo` 模式。让我们看一个例子。
如果我们运行:
```bash
nest new my-project
```
我们已经构建了一个标准模式结构,其文件夹结构如下:
```bash
src
|_ app.controller.ts
|_ app.service.ts
|_ app.module.ts
|_ main.ts
node_modules
nest-cli.json
package.json
tsconfig.json
tslint.json
```
我们可以将其转换为一个 `monorepo` 模式结构如下:
```bash
cd my-project
nest generate app my-app
```
此时,`nest` 将现有结构转换为 `monorepo` 模式结构。 这导致一些重要的变化。 现在,文件夹结构如下所示:
```bash
apps
├──my-app
│ │──src
│ │ │── app.controller.ts
│ │ │── app.service.ts
│ │ │── app.module.ts
│ │ └── main.ts
│ └── tsconfig.app.json
└──my-project
│──src
│ │── app.controller.ts
│ │── app.service.ts
│ │── app.module.ts
│ └── main.ts
└──tsconfig.app.json
nest-cli.json
package.json
tsconfig.json
tslint.json
```
生成`generate app `重新组织了代码——将每个应用程序项目移到 `apps` 文件夹下,并添加一个特定于项目的 `tsconfig.app.json`文件。我们最初的 `my-project` 应用程序已经成为 `monorepo` 的默认项目,现在是刚刚添加的 `my-app` 的同级应用程序,位于 `apps` 文件夹下。我们将在下面讨论默认项目。
> 将标准模式结构转换为 `monorepo` 只适用于遵循标准 `Nest` 项目结构的项目。具体来说,在转换期间,`schematic` 尝试重新定位 `src` 和`test` 文件夹,它们位于根目录下的 `apps` 文件夹下的一个项目文件夹中。如果项目不使用这种结构,转换将失败或产生不可靠的结果。
### 工作区项目
`monorepo`使用工作区的概念来管理其成员实体。 工作区由项目组成。 一个项目可能是:
- 一个应用程序:一个完整的 `Nest` 应用程序,包括一个 `main.ts` 文件来引导应用程序。除了编译和构建之外,工作空间中的应用程序类型项目在功能上与标准模式结构中的应用程序相同。
- 库:库是一种打包一组通用功能(模块、提供程序、控制器等)的方法,这些功能可以在其他项目中使用。库不能独立运行,也没有 `main.ts` 文件。在这里阅读更多关于图书馆的信息。
所有工作空间都有一个默认项目(应该是应用程序类型的项目)。这是由 `nest-cli.json` 中的顶级“根”属性文件,它指向默认项目的根(有关详细信息,请参阅下面的 `CLI` 属性)。通常,这是您开始使用的标准模式应用程序,然后使用 `nest generate` 应用程序将其转换为 `monorepo`。
当没有提供项目名称时,`nest build` 和 `nest start` 等 `nest` 命令使用默认项目。
例如,在上面的 `monorepo` 结构中,运行
```bash
$ nest start
```
将启动 `my-project app` 。要启动 `my-app` ,我们将使用:
```bash
$ nest start my-app
```
### 应用
应用程序类型的项目,或者我们通常所说的”应用程序”,是可以运行和部署的完整的 `Nest` 应用程序。使用 `nest generate` 应用程序生成应用程序类型的项目。
该命令自动生成一个项目框架,包括来自 `typescript starter` 的标准 `src` 和测试文件夹。与标准模式不同,`monorepo` 中的应用程序项目不具有任何包依赖项( `package.json` )或其他项目配置构件,如 `.prettierrc` 和 `tslint.json` 。相反,使用单处理器范围的依赖项和配置文件。
然而,该示意图确实生成了特定于项目的 `tsconfig.app.json`。此配置文件自动设置适当的生成选项,包括正确设置编译输出文件夹。该文件扩展了顶级(monorepo) `tsconfig.json` 文件,因此您可以管理单点范围内的全局设置,但是如果需要,可以在项目级别覆盖它们。
### 库
如前所述,库类型的项目,或者简称“库”,是一些打包的Nest组件,可以集成在应用中来运行。可以使用`nest generate library`来生成库类型项目。决定哪些内容在一个库中是架构级别的决策。我们将在“库”一章深入讨论。
### CLI 属性
Nest在`nest-cli.json`文件中保留了组织、创建和部署标准项目和monorepo结构项目的元数据。Nest在你添加项目的项目时会自动添加和更新这些文件,因此一般来说你不需要考虑或者编辑它的内容。当然,有些设置我们可能需要手动修改,因此了解这个文件可能会有所帮助。
在运行上述指令来创建一个monorepo后,`nest-cli.json`文件看上去是这样:
```typescript
{
"collection": "@nestjs/schematics",
"sourceRoot": "apps/my-project/src",
"monorepo": true,
"root": "apps/my-project",
"compilerOptions": {
"webpack": true,
"tsConfigPath": "apps/my-project/tsconfig.app.json"
},
"projects": {
"my-project": {
"type": "application",
"root": "apps/my-project",
"entryFile": "main",
"sourceRoot": "apps/my-project/src",
"compilerOptions": {
"tsConfigPath": "apps/my-project/tsconfig.app.json"
}
},
"my-app": {
"type": "application",
"root": "apps/my-app",
"entryFile": "main",
"sourceRoot": "apps/my-app/src",
"compilerOptions": {
"tsConfigPath": "apps/my-app/tsconfig.app.json"
}
}
}
}
```
该文件被分为以下部分:
- 一个全局部分,包含用于控制标准和monorepo范围设置的顶层属性。
- 一个顶层属性(`projects`)包含每个项目的元数据。这部分仅仅在monorepo结构中包括。
顶层属性包括:
- "`collection`":用于配置生成部件的schematics组合的点;你一般不需要改变这个值。
- "`sourceRoot`":标准模式中单项目源代码根入口,或者monorepo模式结构中的默认项目。
- "`compilerOptions`":一个键值映射用于指定编译选项和选项的设置;详见后文。
- "`generateOptions`":一个键值映射用于指定全局生成的选项和选项的设置;详见后文。
- "`monorepo`":(仅用于monorepo)在monorepo结构中,该设置始终为`true`。
- "`root`":(仅用于monorepo)默认项目的项目根目录要点。
### 全局编译器选项
|属性名称 | 属性值类型 | 描述|
|---|---|---|
| `webpack` | `boolean` | 如果为`true`,使用`webpack compiler`。如果`false`或者不存在,使用`tsc`。在monorepo模式中,默认为`true`(使用webpack),在标准模式下,默认为`false`(使用`tsc`),详见如下|
| `tsConfigPath` | `string` | (仅用于monorepo)包含`tsconfig.json`文件设置的点,在使用`nest build`或者`nest start`而未指定`project`选项时将使用该设置(例如,默认项目在构建或启动时) |
| `webpackConfigPath` |`string`| webpack选项文件,如果不指定,Nest会查找`webpack.config.js`。详见后文。|
| `deleteOutDir` |`boolean`| 如果为`true`,无论编译器是否激活, 首先会移除汇编输出目录(在`tsconfig.json`中配置,默认`./dist`)。|
| `assets` |`array`| 当编译步骤开始时,使能非Typescript资源文件的自动部署(在--watch模式下,资源文件在增量编译时不会部署)。详见后文|
| `watchAssets`|`boolean`| 如果为`true`,在watch模式运行时,监视所有非Typescript资源文件(如果要更精确控制要监控的资源文件,见后续**资源文件**章节)。|
### 全局生成器选项
这些属性指定`nest generate`指令的默认生成选项:
|属性名称 | 属性值类型 | 描述|
|---|---|---|
| `spec` | `boolean`或`object` |如果该值是`boolean`,设置为`true`默认使能`spec`生成,设置为`false`禁用它。在`CLI`命令行传递一个`flag`来覆盖这一设置,和项目中`generateOptions`设置一样(见下)。如果该值是`object`,每个键代表一个`schematic`名称,而布尔值则代表是/否为特定`schematic`使能`spec`生成|
下列示例使用一个布尔值并指定默认在所有项目中禁用`spec`文件生成。
```typescript
{
"generateOptions": {
"spec": false
},
...
}
```
在下列示例中,`spec`文件生成仅仅在`service`的schematics被禁用(也就是`nest generate service...`):
```typescript
{
"generateOptions": {
"spec": {
"service": false
}
},
...
}
```
> 当指定`spec`作为对象时,生成schematic的键目前还不支持自动生成别名,这意味着例如要将一个键`service:false`通过别名`s`生成服务,`spec`仍然会被生成。要保证通常的schematic名称和别名都可以按意图工作,需要按如下来分别指定通常的名称和别名:
```typescript
{
"generateOptions": {
"spec": {
"service": false,
"s": false
}
},
...
}
```
### 项目生成选项
在全局生成器选项之外,你可能希望指定针对项目的生成器选项。项目级别的生成选项和全局生成选项格式完全一样,但是针对每个项目单独设置。
项目范围的生成选项会覆盖全局生成选项:
```typescript
{
"projects": {
"cats-project": {
"generateOptions": {
"spec": {
"service": false
}
},
...
}
},
...
}
```
> 生成选项的顺序如下。在CLI命令行中指定的选项优于项目级别选项。项目级别选项覆盖全局选项。
### 特定编译器
使用不同的默认编译器原因在于针对大型项目时(例如一个典型的monorepo项目),`webpack`在构建时间和生成一个将所有项目部件打包的单一文件时具有明显的优势。如果你希望生成独立的文件。设置`webpack`为`false`,这将使用`tsc`来实现编译过程。
### Webpack选项
webpack选项文件可以包含标准的[webpack配置选项](https://webpack.js.org/configuration/)。例如,要告诉webpack来打包`node_modules`(默认排除在外),添加下列内容到`webpack.config.js`:
```typescript
module.exports = {
externals: [],
};
```
因为`webpack`配置文件是一个JavaScript文件,你可以暴露出一个包含默认选项的函数,其返回一个编辑后的对象:
```typescript
module.exports = function(options) {
return {
...options,
externals: [],
};
};
```
### 资源文件
TypeScript编译器自动编译输出(`.js`和`.d.ts`文件)到指定的输出文件夹。对非TypeScript文件例如`.graphql`文件、`images`,`html`文件和其他资源文件也同样很方便。这允许你将`nest build`(以及其他编译初始化步骤)作为一个轻型的**开发构建**步骤,你可以编辑非TypeScript文件并进行迭代编译和测试。
`assets`关键字值是一个包含要处理的文件的数组,其元素可以是简单的字符串或者类似`glob`的文件说明,例如:
```typescript
"assets": ["**/*.graphql"],
"watchAssets": true,
```
为更好的控制,元素可以是包含如下键的对象:
- "include":指定的要处理的类似`glob`文件。
- "exclude":从`include`中排除的类似`glob`文件。
- "outDir":一个指定路径的字符串(相对根目录),用于放置资源文件。默认和编译器配置的输出路径一致。
- "watchAssets":布尔量,如果为`true`,将运行与watch模式来监控指定资源文件。
例如:
```typescript
"assets": [
{ "include": "**/*.graphql", "exclude": "**/omitted.graphql", "watchAssets": true },
]
```
> 在顶级的`compilerOptions`中设置`watchAssets`,覆盖`assets`中的`watchAssets`。
### 项目属性
该元素仅存在于monorepo模式结构中。你通常不需要编辑这些属性,因为它们是Nest用来在monorepo中定位项目和它们的配置选项的。
- 介绍
- 概述
- 第一步
- 控制器
- 提供者
- 模块
- 中间件
- 异常过滤器
- 管道
- 守卫
- 拦截器
- 自定义装饰器
- 基础知识
- 自定义提供者
- 异步提供者
- 动态模块
- 注入作用域
- 循环依赖
- 模块参考
- 懒加载模块
- 应用上下文
- 生命周期事件
- 跨平台
- 测试
- 技术
- 数据库
- Mongo
- 配置
- 验证
- 缓存
- 序列化
- 版本控制
- 定时任务
- 队列
- 日志
- Cookies
- 事件
- 压缩
- 文件上传
- 流式处理文件
- HTTP模块
- Session(会话)
- MVC
- 性能(Fastify)
- 服务器端事件发送
- 安全
- 认证(Authentication)
- 授权(Authorization)
- 加密和散列
- Helmet
- CORS(跨域请求)
- CSRF保护
- 限速
- GraphQL
- 快速开始
- 解析器(resolvers)
- 变更(Mutations)
- 订阅(Subscriptions)
- 标量(Scalars)
- 指令(directives)
- 接口(Interfaces)
- 联合类型
- 枚举(Enums)
- 字段中间件
- 映射类型
- 插件
- 复杂性
- 扩展
- CLI插件
- 生成SDL
- 其他功能
- 联合服务
- 迁移指南
- Websocket
- 网关
- 异常过滤器
- 管道
- 守卫
- 拦截器
- 适配器
- 微服务
- 概述
- Redis
- MQTT
- NATS
- RabbitMQ
- Kafka
- gRPC
- 自定义传输器
- 异常过滤器
- 管道
- 守卫
- 拦截器
- 独立应用
- Cli
- 概述
- 工作空间
- 库
- 用法
- 脚本
- Openapi
- 介绍
- 类型和参数
- 操作
- 安全
- 映射类型
- 装饰器
- CLI插件
- 其他特性
- 迁移指南
- 秘籍
- CRUD 生成器
- 热重载
- MikroORM
- TypeORM
- Mongoose
- 序列化
- 路由模块
- Swagger
- 健康检查
- CQRS
- 文档
- Prisma
- 静态服务
- Nest Commander
- 问答
- Serverless
- HTTP 适配器
- 全局路由前缀
- 混合应用
- HTTPS 和多服务器
- 请求生命周期
- 常见错误
- 实例
- 迁移指南
- 发现
- 谁在使用Nest?