Skip to content

Commit e7a1c9b

Browse files
committed
docs: add OSS update mode docs and enable local search plugin
1 parent 73e9290 commit e7a1c9b

8 files changed

Lines changed: 1092 additions & 74 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,6 @@ FakesAssemblies/
199199
# Generated extensions directory
200200
**/extensions/
201201
.DS_Store
202+
203+
# Reasonix local tool state
204+
.reasonix/

website/docs/doc/Core-flow.md

Lines changed: 109 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ sidebar_label: Core 执行流程
3131
8. [Chain→Full 回退机制](#8-chainfull-回退机制)
3232
9. [IPC 通信协议](#9-ipc-通信协议)
3333
10. [UpdateStrategy:Upgrade 进程的执行流程](#10-updatestrategyupgrade-进程的执行流程)
34-
11. [Silent Mode:延迟升级机制](#11-silent-mode延迟升级机制)
35-
12. [OS 策略的平台差异](#12-os-策略的平台差异)
36-
13. [错误恢复全景](#13-错误恢复全景)
37-
14. [关键代码路径索引](#14-关键代码路径索引)
34+
11. [OSS 模式:对象存储更新执行流程](#11-oss-模式对象存储更新执行流程)
35+
12. [Silent Mode:延迟升级机制](#12-silent-mode延迟升级机制)
36+
13. [OS 策略的平台差异](#13-os-策略的平台差异)
37+
14. [错误恢复全景](#14-错误恢复全景)
38+
15. [关键代码路径索引](#15-关键代码路径索引)
3839

3940
---
4041

@@ -100,6 +101,8 @@ GeneralUpdate.Core 采用**三层调度 + 两层引擎**的设计:
100101
|------|---------|---------------|------|
101102
| 主程序(如 `MyApp.exe`| `Client` | `ClientStrategy` | 服务端版本校验、一次性下载所有包、原地升级自身(Upgrade 包)、写 IPC 文件、拉起 Upgrade 进程、退出 |
102103
| 升级程序(如 `Updater.exe`| `Upgrade` | `UpdateStrategy` | 读 IPC 文件获取版本信息、运行管道升级主程序文件、写回 manifest、拉起主程序、退出 |
104+
| 主程序(OSS 模式) | `OssClient` | `OssStrategy` | 下载 `versions.json`、SemVer 对比、拉起升级程序、退出(无 IPC) |
105+
| 升级程序(OSS 模式) | `OssUpgrade` | `OssStrategy` |`versions.json`、下载并解压更新包、写回 manifest、拉起主程序、退出(无 IPC) |
103106

104107
---
105108

@@ -1224,11 +1227,106 @@ Upgrade 进程
12241227

12251228
---
12261229

1227-
## 11. Silent Mode:延迟升级机制
1230+
## 11. OSS 模式:对象存储更新执行流程
1231+
1232+
`OssStrategy` 是 OSS(Object Storage Service,对象存储服务)模式的核心策略,适用于**没有后端服务**的部署场景:版本配置与更新包直接托管在对象存储(阿里云 OSS / AWS S3 / MinIO 等)上,客户端通过静态 `versions.json` 文件完成版本检查与更新。
1233+
1234+
与标准模式不同,OSS 模式**不写 IPC 文件、不请求 Verification / Report API**。Client 与 Upgrade 之间通过安装目录下的 `versions.json` 文件传递更新上下文,因此 `OssClient``OssUpgrade` 必须使用一致的 `MainAppName` / `UpdateAppName` 配置。
1235+
1236+
### 11.1 完整流程
1237+
1238+
```mermaid
1239+
flowchart TB
1240+
subgraph OSS_CLIENT["OssClient 主程序"]
1241+
direction TB
1242+
START(["启动"]) --> OC1["下载 versions.json\nUpdateUrl → {MainAppName}_versions.json"]
1243+
OC1 --> OC2["反序列化版本列表\n按 PubTime 倒序取最新版本"]
1244+
OC2 --> OC3{"SemVer 对比\n最新版本大于 ClientVersion?"}
1245+
OC3 -- "否" --> OC_EXIT["返回\n无需更新"]
1246+
OC3 -- "是" --> OC4["解析升级程序路径\n优先 UpdatePath → InstallPath"]
1247+
OC4 --> OC5["Process.Start(升级程序)"]
1248+
OC5 --> OC6["GracefulExit\n主程序退出"]
1249+
end
1250+
1251+
subgraph OSS_UPGRADE["OssUpgrade 升级程序"]
1252+
direction TB
1253+
US1(["启动"]) --> US2["读取 versions.json\n或自定义 DownloadSource"]
1254+
US2 --> US3["筛选 Version 大于 ClientVersion\n按 PubTime 升序 → DownloadAsset"]
1255+
US3 --> US4["计算 LastVersion\nSemVer 最大值"]
1256+
US4 --> US5["OnBeforeUpdateAsync 钩子"]
1257+
US5 --> US6{"返回 false?"}
1258+
US6 -- "是" --> US_EXIT["取消更新"]
1259+
US6 -- "否" --> US7["下载所有更新包\nDefaultDownloadOrchestrator"]
1260+
US7 --> US8["解压 zip → 安装目录\n删除压缩包"]
1261+
US8 --> US9["写回 manifest\nClientVersion = LastVersion"]
1262+
US9 --> US10["OnDownloadCompleted / OnAfterUpdate 钩子"]
1263+
US10 --> US11["OnBeforeStartApp 钩子"]
1264+
US11 --> US12["StartAppAsync\n拉起主程序"]
1265+
US12 --> US13["GracefulExit\n升级程序退出"]
1266+
end
1267+
1268+
OC5 -. "共享 versions.json(无 IPC)" .-> US1
1269+
```
1270+
1271+
### 11.2 与标准模式的关键差异
1272+
1273+
| 维度 | 标准 Client / Upgrade | OSS 模式 |
1274+
|------|----------------------|----------|
1275+
| 服务端 API | 需要 Verification / Report API | 不需要,纯静态文件 |
1276+
| 进程间通信 | 加密 IPC 文件 | 安装目录下的 `versions.json` 文件 |
1277+
| 包类型 | Chain(差分)+ Full(全量) | 仅 Full(zip 全量包) |
1278+
| 更新管道 | Hash → Compress → Patch | Hash 校验 + 解压(无差分 Patch) |
1279+
| 备份 / 回滚 | 有(`.backups/`||
1280+
| 黑名单机制 | 有(CheckFail) ||
1281+
| 版本对比 | 服务端返回 Assets 列表 | 本地解析 versions.json + SemVer 对比 |
1282+
| 防止更新循环 | `AllPackagesSucceeded` 闸门 | 更新成功后回写 manifest 的 `ClientVersion` |
1283+
1284+
### 11.3 OssClient:版本检查与拉起升级
1285+
1286+
【说明】`OssClient` 只负责"检查 + 拉起",**不下载更新包**。版本配置下载失败或文件不存在时直接返回,不抛异常、不阻塞主程序启动。
1287+
1288+
| 步骤 | 行为 | 关键实现 |
1289+
|------|------|----------|
1290+
| 1 | 下载版本配置 | `UpdateUrl` → 保存为 `{MainAppName}_versions.json`(InstallPath 下) |
1291+
| 2 | 解析并取最新 | `JsonContext.OssVersionRecordJsonContext` 反序列化,按 `PubTime` 倒序 |
1292+
| 3 | 版本对比 | SemVer 2.0:`latest.Version > ClientVersion` 才继续 |
1293+
| 4 | 解析升级程序路径 | 优先 `UpdatePath`,回退 `InstallPath``UpdateAppName` 默认 `Update.exe` |
1294+
| 5 | 拉起升级程序 | `Process.Start(appPath)`**不传任何参数**;升级程序靠自身代码的 `AppType.OssUpgrade` 和 manifest 身份执行升级 |
1295+
| 6 | 退出主程序 | `GracefulExit.CurrentProcessAsync()` |
1296+
1297+
### 11.4 OssUpgrade:下载、解压与应用
1298+
1299+
【说明】`OssUpgrade` 完成实际的下载与安装,全程不依赖服务端。
1300+
1301+
| 步骤 | 行为 | 关键实现 |
1302+
|------|------|----------|
1303+
| 1 | 读取版本配置 | `{MainAppName}_versions.json`(Client 已下载)或自定义 `DownloadSource` |
1304+
| 2 | 筛选更新包 | 过滤 `Version > ClientVersion`,按 `PubTime` 升序转为 `DownloadAsset``SHA256 = Hash`|
1305+
| 3 | 计算目标版本 | 所有可解析版本号的 SemVer 最大值 → `LastVersion` |
1306+
| 4 | 前置钩子 | `OnBeforeUpdateAsync`,返回 false 可取消更新 |
1307+
| 5 | 下载更新包 | 默认 `DefaultDownloadOrchestrator`(超时默认 60s),或自定义 `DownloadOrchestrator` |
1308+
| 6 | 解压安装 | `Format.Zip` 解压到 InstallPath,完成后删除压缩包 |
1309+
| 7 | 回写版本 | `ManifestInfo.TryUpdateVersion` 更新 manifest 的 `ClientVersion`,防止无限更新循环 |
1310+
| 8 | 收尾钩子 | `OnDownloadCompleted``OnAfterUpdate``OnBeforeStartApp` |
1311+
| 9 | 拉起主程序 | `StartAppAsync()` |
1312+
| 10 | 退出 | `GracefulExit.CurrentProcessAsync()`;异常时触发 `OnUpdateErrorAsync` + 上报 UpdateFailed |
1313+
1314+
### 11.5 注意事项
1315+
1316+
- OSS 模式**没有备份 / 回滚机制**,更新包解压后直接覆盖安装目录,建议发布前充分测试
1317+
- OSS 模式**不区分主程序与升级程序的更新包**`versions.json` 中所有高于当前版本的包都会被依次下载并应用
1318+
- 打包更新包时请勿包含组件内部依赖程序集(如 `System.Text.Json.dll``Microsoft.Bcl.AsyncInterfaces.dll` 等)
1319+
- 版本号必须使用 SemVer 2.0 格式(如 `1.0.0.0`),否则版本对比会静默失败
1320+
- Bucket 建议设为私有并使用预签名 URL;`OssDownloadSource` 原生支持预签名 URL 场景
1321+
- 与标准模式一致,OSS 模式同样支持 `Hooks<T>()` 生命周期钩子、`UpdateReporter<T>()` 状态上报、`DownloadSource<T>()` / `DownloadOrchestrator<T>()` 自定义下载来源与编排
1322+
1323+
---
1324+
1325+
## 12. Silent Mode:延迟升级机制
12281326

12291327
Silent Mode 是标准更新流程的一种变体,唯一的区别是**启动升级进程的时机从"立即"变成了"进程退出时"**
12301328

1231-
### 11.1 标准模式 vs 静默模式
1329+
### 12.1 标准模式 vs 静默模式
12321330

12331331
```
12341332
标准模式:
@@ -1250,7 +1348,7 @@ AppDomain.ProcessExit (进程退出时):
12501348
→ Upgrade 进程启动 → 应用更新 → 下次启动时版本已更新
12511349
```
12521350

1253-
### 11.2 完整流程图
1351+
### 12.2 完整流程图
12541352

12551353
```mermaid
12561354
flowchart TB
@@ -1292,7 +1390,7 @@ flowchart TB
12921390
end
12931391
```
12941392

1295-
### 11.3 TryLaunchUpgrade — 兜底方法
1393+
### 12.3 TryLaunchUpgrade — 兜底方法
12961394

12971395
```csharp
12981396
// SilentPollOrchestrator.cs:187-210
@@ -1310,7 +1408,7 @@ public bool TryLaunchUpgrade()
13101408

13111409
---
13121410

1313-
## 12. OS 策略的平台差异
1411+
## 13. OS 策略的平台差异
13141412

13151413
| 方面 | Windows | Linux | macOS |
13161414
|------|---------|-------|-------|
@@ -1323,7 +1421,7 @@ Bowl 是一个 Windows-only 的崩溃守护进程。当主程序意外退出时
13231421

13241422
---
13251423

1326-
## 13. 错误恢复全景
1424+
## 14. 错误恢复全景
13271425

13281426
| 错误场景 | 捕获位置 | 处理方式 | 后果 |
13291427
|----------|----------|----------|------|
@@ -1357,7 +1455,7 @@ private void TryRollback()
13571455

13581456
---
13591457

1360-
## 14. 关键代码路径索引
1458+
## 15. 关键代码路径索引
13611459

13621460
| 步骤 | 文件 | 关键行 |
13631461
|------|------|--------|

website/docs/doc/GeneralUpdate.Core.md

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,174 @@ var bootstrap = new GeneralUpdateBootstrap()
909909
await bootstrap.LaunchAsync();
910910
```
911911

912+
### 5.4 OSS 对象存储更新(零服务端部署)
913+
914+
【场景说明】OSS(Object Storage Service,对象存储服务)更新模式适用于**没有后端服务**的部署场景:将版本配置与更新包直接托管在对象存储(阿里云 OSS / AWS S3 / MinIO 等)上,客户端通过静态 `versions.json` 文件完成版本检查与更新,全程无需编写服务端 API。
915+
916+
**工作流程:**
917+
918+
```
919+
对象存储 Bucket(阿里云 OSS / AWS S3 / MinIO)
920+
├── versions.json ← 版本配置(静态文件)
921+
└── packet_20250102230201638_1.0.0.1.zip ← 更新包
922+
```
923+
924+
| 步骤 | 角色 | 说明 |
925+
| --- | --- | --- |
926+
| 1 | 运维 |`versions.json` 与更新包上传至对象存储 Bucket |
927+
| 2 | `OssClient`(主程序) | 启动时从 `UpdateUrl` 下载 `versions.json`,按 `PubTime` 倒序取最新版本 |
928+
| 3 | `OssClient`(主程序) | 最新版本与 `ClientVersion` 做 SemVer 2.0 对比,无新版本则结束检查 |
929+
| 4 | `OssClient`(主程序) | 检测到新版本 → 启动升级程序 → 主程序自行退出 |
930+
| 5 | `OssUpgrade`(升级程序) | 读取版本配置,下载所有高于当前版本的更新包并解压覆盖安装目录 |
931+
| 6 | `OssUpgrade`(升级程序) | 回写 `generalupdate.manifest.json` 版本号 → 启动主程序 → 自行退出 |
932+
933+
**两个进程如何配合:**
934+
935+
OSS 模式需要**两个独立的可执行程序**,角色由各自代码中的 `AppType` 决定,而不是通过启动参数或 IPC 文件传递:
936+
937+
| 程序 | 项目代码 | AppType | 职责 |
938+
| --- | --- | --- | --- |
939+
| 主程序(如 `MyApp.exe`| 业务应用 | `AppType.OssClient` | 检查版本、拉起升级程序、退出 |
940+
| 升级程序(如 `UpgradeApp.exe`| 独立小项目 | `AppType.OssUpgrade` | 下载更新包、解压安装、拉起主程序、退出 |
941+
942+
`OssClient` 检测到新版本后通过 `Process.Start` 直接启动升级程序,**不传任何参数**——升级程序靠自身代码中的 `AppType.OssUpgrade` 知道自己该执行升级,并依靠安装目录下的 `generalupdate.manifest.json` 获取主程序身份(见下文"安装目录布局")。
943+
944+
**versions.json 版本配置格式:**
945+
946+
```json
947+
[
948+
{
949+
"PacketName": "packet_20250102230201638_1.0.0.1",
950+
"Hash": "ad1a85a9169ca0083ab54ba390e085c56b9059efc3ca8aa1ec9ed857683cc4b1",
951+
"Version": "1.0.0.1",
952+
"Url": "https://your-bucket.example.com/packages/packet_20250102230201638_1.0.0.1.zip",
953+
"PubTime": "2025-01-02T23:48:21"
954+
}
955+
]
956+
```
957+
958+
| 字段 | 类型 | 说明 |
959+
| --- | --- | --- |
960+
| `PacketName` | `string` | 更新包名称,用于生成本地压缩文件名(`{PacketName}.zip`|
961+
| `Hash` | `string` | 更新包 SHA256 哈希,下载完成后与本地文件比对校验 |
962+
| `Version` | `string` | 版本号(SemVer 2.0 格式),用于版本对比 |
963+
| `Url` | `string` | 更新包下载地址(对象存储公开或预签名 URL) |
964+
| `PubTime` | `DateTime` | 发布时间,OSS 模式按此字段倒序选取最新版本 |
965+
966+
:::info 配置文件命名
967+
`versions.json` 下载后会以 `{MainAppName}_versions.json` 的名称保存在安装目录,升级程序从同一位置读取。主程序与升级程序必须使用一致的 `MainAppName` / `UpdateAppName` 配置。
968+
:::
969+
970+
**安装目录布局(主程序 + 升级程序 + manifest):**
971+
972+
```
973+
安装目录(InstallPath)
974+
├── MyApp.exe ← 主程序(AppType.OssClient)
975+
├── MyApp.dll / 资源文件...
976+
├── generalupdate.manifest.json ← 应用身份清单(见下方示例)
977+
└── update/
978+
└── UpgradeApp.exe ← 升级程序(AppType.OssUpgrade)
979+
```
980+
981+
对应 `generalupdate.manifest.json` 示例(身份字段也可全部写在代码里,两者共存时 manifest 优先):
982+
983+
```json
984+
{
985+
"mainAppName": "MyApp.exe",
986+
"clientVersion": "1.0.0.0",
987+
"appType": "OssClient",
988+
"updateAppName": "UpgradeApp.exe",
989+
"updatePath": "update/"
990+
}
991+
```
992+
993+
- 升级程序必须位于 `InstallPath``UpdatePath` 指定的目录,否则 `OssClient` 无法拉起它并抛出 `FileNotFoundException`
994+
- 升级程序运行时会读取 `{MainAppName}_versions.json``OssClient` 下载后保存在 `InstallPath`),并依靠 `generalupdate.manifest.json` 获得 `MainAppName` / `UpdateAppName` / `ClientVersion` 等身份
995+
- 若升级程序放在 `update/` 子目录(其程序基目录是子目录)而 manifest 在父目录,升级程序代码中需通过 `SetSource(..., installPath: ...)` 显式指向父目录,例如 `Path.GetFullPath(Path.Combine(baseDir, ".."))`
996+
997+
**OSS 模式 UpdateRequest 字段说明:**
998+
999+
| 字段 | 是否必填 | 说明 |
1000+
| --- | --- | --- |
1001+
| `UpdateUrl` | 必填 | `versions.json` 的公开访问地址,`OssClient` 启动时据此下载版本配置 |
1002+
| `MainAppName` | 推荐 | 主程序可执行文件名;决定版本配置的本地文件名(`{MainAppName}_versions.json`),也是升级完成后拉起的目标 |
1003+
| `UpdateAppName` | 推荐 | 升级程序可执行文件名;`OssClient` 检测到新版本后拉起的进程,默认 `Update.exe` |
1004+
| `ClientVersion` | 推荐 | 当前主程序版本号(SemVer 2.0 格式),用于版本对比与更新包筛选 |
1005+
| `InstallPath` | 可选 | 应用安装根目录,默认 `AppDomain.CurrentDomain.BaseDirectory``versions.json` 的保存位置与更新包的解压目标目录 |
1006+
| `UpdatePath` | 可选 | 升级程序所在目录,默认 `InstallPath``OssClient` 优先从此目录解析升级程序 |
1007+
1008+
:::info OSS 模式无需配置的字段
1009+
OSS 模式没有服务端 API,以下与认证、上报、日志相关的字段**无需配置**(配置了也不会被使用):`AppSecretKey``ReportUrl``UpdateLogUrl``Token``AuthScheme``BasicUsername``BasicPassword``Bowl`
1010+
:::
1011+
1012+
另外,OSS 模式还会用到以下 `Option` 运行时选项:
1013+
1014+
| Option | 默认值 | 说明 |
1015+
| --- | --- | --- |
1016+
| `Option.AppType` || 必填,指定当前进程角色:`OssClient`(主程序)或 `OssUpgrade`(升级程序) |
1017+
| `Option.Encoding` | `UTF8` | 更新包解压时的字符编码 |
1018+
| `Option.DownloadTimeout` | `60` | 更新包下载超时时间(秒) |
1019+
1020+
**主程序示例(`AppType.OssClient`):**
1021+
1022+
```csharp
1023+
using GeneralUpdate.Core;
1024+
using GeneralUpdate.Core.Configuration;
1025+
1026+
var request = new UpdateRequest
1027+
{
1028+
UpdateUrl = "https://your-bucket.example.com/packages/versions.json",
1029+
UpdateAppName = "OSSUpgradeSample.exe",
1030+
MainAppName = "OSSClientSample.exe",
1031+
ClientVersion = "1.0.0.0",
1032+
InstallPath = AppDomain.CurrentDomain.BaseDirectory
1033+
};
1034+
1035+
await new GeneralUpdateBootstrap()
1036+
.SetConfig(request)
1037+
.SetOption(Option.AppType, AppType.OssClient)
1038+
.AddListenerException((_, e) => Console.WriteLine(e.Exception))
1039+
.LaunchAsync();
1040+
```
1041+
1042+
**升级程序示例(`AppType.OssUpgrade`):**
1043+
1044+
```csharp
1045+
using GeneralUpdate.Core;
1046+
1047+
// 升级程序无需 SetConfig:MainAppName / UpdateAppName / ClientVersion 等身份
1048+
// 字段由安装目录下的 generalupdate.manifest.json 自动发现(AppMetadataDiscoverer)。
1049+
// 若升级程序位于 update/ 子目录(manifest 在父目录),需显式指向父目录:
1050+
//
1051+
// var baseDir = AppDomain.CurrentDomain.BaseDirectory;
1052+
// await new GeneralUpdateBootstrap()
1053+
// .SetSource("https://your-bucket.example.com/packages/versions.json", "",
1054+
// installPath: Path.GetFullPath(Path.Combine(baseDir, "..")))
1055+
// .SetOption(Option.AppType, AppType.OssUpgrade)
1056+
// .LaunchAsync();
1057+
1058+
await new GeneralUpdateBootstrap()
1059+
.SetOption(Option.AppType, AppType.OssUpgrade)
1060+
.AddListenerException((_, e) => Console.WriteLine(e.Exception))
1061+
.LaunchAsync();
1062+
```
1063+
1064+
:::tip 新手 5 步上手
1065+
1. **建主程序项目**:引入 NuGet 包 `GeneralUpdate.Core`,按上文"主程序示例"编写代码(`AppType.OssClient`),`UpdateAppName` 填你的升级程序文件名
1066+
2. **建升级程序项目**:独立小项目,按上文"升级程序示例"编写代码(`AppType.OssUpgrade`),编译产物文件名与 `UpdateAppName` 保持一致
1067+
3. **准备 manifest**:用 `GeneralUpdate.Tools` 生成 `generalupdate.manifest.json`(或参照上文示例手写),与主程序、升级程序一同放入安装目录
1068+
4. **发布更新包**:将应用文件打成 zip 上传对象存储;编写 `versions.json` 并上传(`Hash` 填该 zip 的 SHA256,`Url` 填 zip 的可访问地址)
1069+
5. **运行验证**:启动主程序,观察日志确认下载 `versions.json`、检测到新版本、拉起升级程序并完成安装
1070+
:::
1071+
1072+
【效果&注意事项】
1073+
- `UpdateUrl` 直接指向 `versions.json` 的公开地址,更新包同样托管在对象存储上,无需 Verification / Report API
1074+
- Bucket 建议设为私有并使用预签名 URL;若设为公共读,请勿存放敏感内容
1075+
- OSS 模式不区分主程序与升级程序的更新包:`versions.json` 中所有高于当前版本的包都会被依次下载并应用
1076+
- 打包更新包时请勿包含组件内部依赖程序集(如 `System.Text.Json.dll``Microsoft.Bcl.AsyncInterfaces.dll` 等),也可通过 `Files` / `Formats` / `Directories` 跳过配置排除
1077+
- 版本号使用 SemVer 2.0 格式(如 `1.0.0.0`),否则版本对比会失败
1078+
- 与标准模式一致,OSS 模式同样支持 `generalupdate.manifest.json` 身份发现、`Hooks<T>()` 生命周期钩子、`UpdateReporter<T>()` 状态上报,以及 `DownloadSource<T>()` / `DownloadOrchestrator<T>()` 自定义下载来源与编排
1079+
9121080
---
9131081

9141082
## 6. 全局配置

website/docusaurus.config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ const config = {
6262
],
6363
],
6464

65+
plugins: [
66+
[
67+
'@easyops-cn/docusaurus-search-local',
68+
{
69+
// 索引文件名加 hash,避免发布后浏览器缓存旧索引
70+
hashed: true,
71+
// 启用英文与中文分词(中文基于 nodejieba)
72+
language: ['en', 'zh'],
73+
// 仅索引 docs(默认),不索引独立页面
74+
indexPages: false,
75+
},
76+
],
77+
],
78+
6579
markdown: {
6680
mermaid: true,
6781
},

0 commit comments

Comments
 (0)