## 工作空間
`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?