# 萌芽导航（sproutnav）

单一 **Cloudflare Worker**：[`worker/src/index.ts`](worker/src/index.ts) 处理 `/api/*`，静态资源由 Wrangler **[assets]** 提供（Vite 构建输出 [`frontend/dist`](frontend/dist)）。

## 目录结构

- **`worker/`**：导航 API（KV：`sites` / `categories`）、与静态资源回退（SPA）
- **`frontend/`**：React + Vite PWA；[`frontend/src/config/site.ts`](frontend/src/config/site.ts) 可配置 `VITE_API_BASE`、站点文案、随机背景、`VITE_FAVICON_API_BASE`（默认 `https://favicon.smyhub.com/api/favicon?url=`）
- **[`wrangler.toml`](wrangler.toml)**：`main`、`[[kv_namespaces]]`、`[vars]`（如 `ADMIN_PASSWORD`）、`[assets]` → `./frontend/dist`

## 本地开发

```bash
# 仅前端（无同源 API 时需自行 mock 或填 VITE_API_BASE）
cd frontend && npm install && npm run dev

# Worker + 资源（需先 build 前端，或由 wrangler 触发）
npm install
npm run build:frontend
npm run dev
```

## 构建产物

`npm run build`（根目录或 `frontend/`）会连续构建两份前端：

| 脚本 / 模式 | 输出目录 | `VITE_API_BASE` | 用途 |
|-------------|----------|-----------------|------|
| 默认 `vite build` | `frontend/dist` | 空（同源 `/api`） | Worker `[assets]` 线上部署 |
| `--mode desktop` | `frontend/dist-desktop` | `https://nav.smyhub.com` | 桌面壳（Electron/Tauri 等）加载 |

单独构建：`npm run build:web` / `npm run build:desktop`（在 `frontend/` 下）。

桌面版使用 `HashRouter`、`base: './'`，且不注册 Service Worker。

## 部署

```bash
npm install
cd frontend && npm install && cd ..
npm run deploy
```

`deploy` 仅打包并上传 **`frontend/dist`**（线上版）；桌面版 `dist-desktop` 自行交给桌面工程。

生产环境请在 Dashboard 或密文中覆盖 **`ADMIN_PASSWORD`**，勿提交真实口令。

## KV 数据

沿用 [`wrangler.toml`](wrangler.toml) 中 namespace `id` 即可续用原有 KV 数据。

## 常见问题

- **站点卡片图标**：由前端根据每条站点的 `url` 请求 favicon 服务，不经 Worker；可通过 `VITE_FAVICON_API_BASE` 覆盖默认基址。
- **跨域 / 缓存**：若 API 已同源但仍见旧请求，尝试硬刷新或注销 Service Worker 后清除站点数据。
