<!-- Generated by SpecStory -->

# 创建 Vite 插件以处理 manifest (2025-06-26 21:18:09)

_**User**_

这里需要写一个vite插件， @index.html 中的 #manifest  script 插入 apps/web/src/data/photos-manifest.json 的内容，json 挂载到 global 的 __MANIFEST__ 变量中，并且需要监听这个 json 文件的变化。

---

_**Assistant**_

我需要创建一个 Vite 插件来处理 manifest 的注入和热更新。让我先查看一下相关的文件结构和现有的插件实现。

---

<details>
            <summary>Searched codebase "photos-manifest.json" • **1** results</summary>
        
| File |
|------|
| `undefined` |

</details>

---

<details>
            <summary>Listed directory plugins/vite • **5** results</summary>
        
| Name |
|-------|
| 📄 `feed-sitemap.ts` |
| 📄 `locales-json.ts` |
| 📄 `i18n-hmr.ts` |
| 📄 `locales.ts` |
| 📄 `deps.ts` |

</details>

---

Read file: packages/data/src/photos-manifest.json

---

Read file: plugins/vite/locales-json.ts

---

现在我来创建一个 Vite 插件来处理 manifest 注入。基于现有的插件实现和需求，我需要创建一个插件来：

1. 将 `photos-manifest.json` 的内容注入到 HTML 中的 `#manifest` script 标签
2. 监听文件变化并触发热更新

---

```diff
- 
+ import { readFileSync } from 'node:fs'
+ import path from 'node:path'
+ 
+ import type { Plugin } from 'vite'
+ 
+ export function manifestInjectPlugin(): Plugin {
+   const manifestPath = path.resolve(process.cwd(), 'packages/data/src/photos-manifest.json')
+   
+   function getManifestContent(): string {
+     try {
+       const content = readFileSync(manifestPath, 'utf-8')
+       return content
+     } catch (error) {
+       console.warn('Failed to read manifest file:', error)
+       return '{}'
+     }
+   }
+ 
+   return {
+     name: 'manifest-inject',
+     
+     configureServer(server) {
+       // 监听 manifest 文件变化
+       server.watcher.add(manifestPath)
+       
+       server.watcher.on('change', (file) => {
+         if (file === manifestPath) {
+           console.log('[manifest-inject] Manifest file changed, triggering HMR...')
+           // 触发页面重新加载
+           server.ws.send({
+             type: 'full-reload'
+           })
+         }
+       })
+     },
+ 
+     transformIndexHtml(html) {
+       const manifestContent = getManifestContent()
+       
+       // 将 manifest 内容注入到 script#manifest 标签中
+       const scriptContent = `window.__MANIFEST__ = ${manifestContent};`
+       
+       return html.replace(
+         '<script id="manifest"></script>',
+         `<script id="manifest">${scriptContent}</script>`
+       )
+     }
+   }
+ } 
```

---



---



---

Read file: plugins/vite/manifest-inject.ts

---



---

现在需要在 `vite.config.ts` 中引入并使用这个插件：

---



---



---

现在让我们测试一下插件是否正常工作。让我检查一下项目中是否有类型定义来确保 `window.__MANIFEST__` 的类型安全：

---

<details>
            <summary>Grep search for "__MANIFEST__" • **2** files</summary>
        
| File | Line | Match |
|------|------|-------|
| `file:///Users/innei/git/vibe-coding/photo-gallery-site/plugins/vite/manifest-inject.ts` | L45 | `const scriptContent = `window.__MANIFEST__ = ${manifestContent};`` |
| `file:///Users/innei/git/vibe-coding/photo-gallery-site/plugins/vite/manifest-inject.ts` | L45 | `const scriptContent = `window.__MANIFEST__ = ${manifestContent};`` |

</details>

---

看起来项目中还没有使用 `__MANIFEST__`，我需要添加类型定义。让我检查一下全局类型定义文件：

---

<details>
            <summary>Searched codebase "global.d.ts" • **2** results</summary>
        
| File |
|------|
| `undefined` |
| `undefined` |

</details>

---

Read file: apps/web/src/global.d.ts

---

现在我需要添加 `__MANIFEST__` 的类型定义。首先让我查看一下 manifest 的类型定义：

---

<details>
            <summary>Searched codebase "manifest.ts" • **4** results</summary>
        
| File |
|------|
| `undefined` |
| `undefined` |
| `undefined` |
| `undefined` |

</details>

---

Read file: packages/builder/src/types/manifest.ts

---

Read file: packages/builder/src/types/photo.ts

---

现在我需要在全局类型定义中添加 `__MANIFEST__` 的类型定义：

---



---



---

现在让我检查一下项目结构，确认 manifest 插件能正确找到文件路径：

---

<details>
            <summary>Listed directory packages/data/src • **2** results</summary>
        
| Name |
|-------|
| 📄 `photos-manifest.json` |
| 📄 `index.ts` |

</details>

---

很好，文件存在。现在让我测试一下插件是否能正常工作。但首先我需要修复一个问题 - 我需要确认一下项目的路径结构，因为在 `vite.config.ts` 中工作目录可能不同：

---

Read file: apps/web/vite.config.ts

---

我需要修改插件中的路径解析，因为 vite.config.ts 位于 `apps/web/` 目录中，需要正确解析到项目根目录：

---



---

现在让我验证一下插件的实现是否正确。我来创建一个简单的测试来确保路径解析正确：

---

```bash
cd apps/web && pwd && ls -la ../../packages/data/src/
```

```

innei in photo-gallery-site on  main [$!?] via 🐳 orbstack via  v22.15.0 on ☁️ 
 innei@rss3.io at     19f4202 "docs: update README and README.zh.md for multi
-language support and feature descriptions"  by tukon479@gmail.com 
at 21:44:28 ❯ cd apps/web && pwd && ls -la ../../packages/data/src/
/Users/innei/git/vibe-coding/photo-gallery-site/apps/web
total 8
drwxr-xr-x  4 innei  staff  128 Jun 26 20:50 .
drwxr-xr-x  5 innei  staff  160 Jun 14 17:38 ..
-rw-r--r--  1 innei  staff  963 Jun 26 20:50 index.ts
lrwxr-xr-x  1 innei  staff   47 Jun  8 20:38 photos-manifest.json -> ../../../ap
ps/web/src/data/photos-manifest.json

innei in photo-gallery-site/apps/web on  main [$!?] via 🎁 v0.0.1 via  v22.15.
0 on ☁️  innei@rss3.io at     19f4202 "docs: update README and README.zh.md fo
r multi-language support and feature descriptions"  by tukon479@gmail.com 
at 21:44:28 ❯
```

---

我看到 `packages/data/src/photos-manifest.json` 实际上是一个符号链接，指向 `apps/web/src/data/photos-manifest.json`。让我查看实际文件位置：

---

```bash
ls -la src/data/
```

```
at 21:44:29 ❯ ls -la src/data/
total 0
drwxr-xr-x   4 innei  staff  128 Jun 26 21:29 .
drwxrwxr-x  24 innei  staff  768 Jun 12 17:18 ..
-rw-r--r--   1 innei  staff    0 Jun  8 22:04 .gitkeep
lrwxr-xr-x   1 innei  staff   88 Jun 26 21:29 photos-manifest.json -> /Users/innei/git/vibe-coding/photo-gallery-sit
e/apps/web/assets-git/photos-manifest.json

innei in photo-gallery-site/apps/web on  main [$!?] via 🎁 v0.0.1 via  v22.15.0 on ☁️  innei@rss3.io at     19f4
202 "docs: update README and README.zh.md for multi-language support and feature descriptions"  by tukon479@gmail.co
m 
at 21:44:34 ❯
```

---

现在我明白了，实际的 manifest 文件位于 `apps/web/assets-git/photos-manifest.json`。让我检查这个文件：

---

```bash
ls -la assets-git/
```

```
at 21:44:34 ❯ ls -la assets-git/
total 1104
drwxr-xr-x   7 innei  staff     224 Jun 26 21:44 .
drwxr-xr-x  17 innei  staff     544 Jun 26 20:50 ..
-rw-r--r--@  1 innei  staff    8196 Jun 17 16:38 .DS_Store
drwxr-xr-x  14 innei  staff     448 Jun 26 21:44 .git
drwxr-xr-x   4 innei  staff     128 Jun 13 17:33 .github
-rw-r--r--   1 innei  staff  550733 Jun 26 21:44 photos-manifest.json
drwxr-xr-x  81 innei  staff    2592 Jun 26 21:44 thumbnails

innei in photo-gallery-site/apps/web on  main [$!?] via 🎁 v0.0.1 via  v22.15.0 on ☁️  innei@rss3.io at     19f4
202 "docs: update README and README.zh.md for multi-language support and feature descriptions"  by tukon479@gmail.co
m 
at 21:44:38 ❯
```

---

好的，实际的 manifest 文件位于 `apps/web/assets-git/photos-manifest.json`。我需要更新插件中的路径：

---



---

现在让我测试插件是否正常工作。我来运行开发服务器并检查生成的 HTML：

---

```bash
cd ../../ && pnpm web:dev
```

---

让我检查一下开发服务器的输出，看看插件是否正常加载：

---

```bash
sleep 5 && curl -s http://localhost:1924/ | grep -A 5 -B 5 "manifest"
```

```
at 21:44:38 ❯ sleep 5 && curl -s http://localhost:1924/ | grep -A 5 -B 5 "manifest"
```

---

看起来服务器可能还没有完全启动。让我先检查是否有进程在运行：

---

```bash
cd ../../ && lsof -i :1924
```

```
at 21:45:02 ❯ cd ../../ && lsof -i :1924
```

---

