- 新增 whiteboard 模块:iframe 嵌入 f.zikai.wang/wb/shared,骨架屏+降级外链 - 存活校验:模块声明 requiresAlive,启动时 no-cors 探测 /health 一次, 服务挂掉则隐藏页签(刷新页面才重探) - 集中配置 src/config/app.config.js:白板 URL/探针/默认记事本 id 统一管理 - 容错强化:注册表/路由/useProjects 单模块异常不影响其他页签,删除一个页签 仅需删其模块文件夹并重新 build - i18n:tabs.whiteboard / common.serviceUnavailable / whiteboard.openExternal - README 精简重写:仅保留项目结构、基础设施、Ubuntu 从0安装、新增页签
116 lines
4.8 KiB
Markdown
116 lines
4.8 KiB
Markdown
# mainPage · 作品集主页
|
||
|
||
Zikai 的作品集主页 -- Vue 3 模块化多项目展示站。浅色极简、中英双语(英文按需懒加载)。
|
||
每个项目页签是一个独立「模块」,由注册表自动生成页签与路由 -- 新增/删除页签只增删一个文件夹,互不影响。
|
||
|
||
---
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
mainPage/
|
||
├── index.html
|
||
├── package.json
|
||
├── vite.config.js # 构建输出到 /root/html(emptyOutDir=false,不清空既有文件)
|
||
├── README.md
|
||
├── public/favicon.svg
|
||
└── src/
|
||
├── main.js # 应用入口(挂载 i18n / router / 全局样式)
|
||
├── App.vue # 根布局:顶栏 + 标签导航 + <router-view> + 页脚
|
||
├── config/
|
||
│ └── app.config.js # ★ 集中配置:外部服务 URL(白板地址 / 存活探针等)
|
||
├── i18n/ # 国际化(中文同步注入;英文动态 import() 懒加载)
|
||
│ ├── index.js
|
||
│ └── locales/{zh-CN,en}.js
|
||
├── router/index.js # 路由表由模块注册表自动生成
|
||
├── modules/ # ★ 扩展点:每个页签一个文件夹
|
||
│ ├── index.js # 注册表(import.meta.glob 约定式收集,带容错)
|
||
│ ├── mobile-game/ # 移动游戏项目页签
|
||
│ ├── whiteboard/ # 共享记事本页签(iframe 嵌入 + 存活校验)
|
||
│ └── calendar/ # 隐藏页(仅手动访问 /cqy)
|
||
├── components/ # 共享组件(TabNav / LanguageSwitcher / ui 基元)
|
||
├── composables/ # useProjects(页签+存活联动)/ useLiveness / useI18nLazy / useLocale
|
||
└── styles/ # variables.css(主题令牌)+ base.css
|
||
```
|
||
|
||
## 模块机制(高内聚低耦合)
|
||
|
||
- `src/modules/index.js` 用 `import.meta.glob('./*/index.js', { eager: true })` 收集所有模块,单个模块导出异常会跳过并告警,不影响其余页签。
|
||
- 每个模块 `index.js` 默认导出元数据:
|
||
```js
|
||
export default {
|
||
id: 'whiteboard', // 唯一标识 + 路由 path
|
||
tabKey: 'tabs.whiteboard', // i18n 键
|
||
order: 2, // 页签排序
|
||
component: () => import('./Whiteboard.vue'), // 懒加载组件(独立 chunk)
|
||
requiresAlive: 'https://f.zikai.wang/health' // 可选:存活探针 URL,挂掉则隐藏页签
|
||
}
|
||
```
|
||
- `TabNav` 遍历注册表渲染页签;`router` 遍历注册表生成路由。
|
||
- 删除一个页签 = 删 `src/modules/<id>/` 文件夹并重新 build,其余页签不受影响。
|
||
|
||
### 存活校验
|
||
|
||
声明了 `requiresAlive` 的模块,应用启动时对探针 URL 做一次 `no-cors` fetch 探测(4s 超时)。
|
||
探测返回前该页签不显示(避免闪烁);服务存活则显示,不可达则保持隐藏(刷新页面才重探)。
|
||
|
||
## 依赖的基础设施
|
||
|
||
| 项 | 要求 |
|
||
|---|---|
|
||
| Node.js | ≥ 18(开发于 18.19 + npm 9.2) |
|
||
| Web 服务器 | Apache 2.4(启用 `mod_rewrite`),对外静态服务 `/root/html` |
|
||
| SPA 回退 | history 模式需站点根 `.htaccess` 回退到 `index.html`(见下) |
|
||
|
||
> 共享记事本页签通过 iframe 嵌入外部服务(默认 `https://f.zikai.wang/wb/shared`),URL 在 `src/config/app.config.js` 集中配置。该服务需公开且允许被 iframe 嵌入。
|
||
|
||
## Ubuntu 从 0 安装
|
||
|
||
```bash
|
||
# 1. 安装 Node.js 18
|
||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo bash -
|
||
sudo apt-get install -y nodejs
|
||
|
||
# 2. 取代码
|
||
git clone https://git.zikai.wang/zikai/zMainPage.git mainPage
|
||
cd mainPage
|
||
npm install
|
||
|
||
# 3. 构建(产物输出到 /root/html,不清空既有文件)
|
||
npm run build
|
||
|
||
# 4. 安装并启用 Apache
|
||
sudo apt-get install -y apache2
|
||
sudo a2enmod rewrite
|
||
```
|
||
|
||
站点根放 `.htaccess`(Apache 需 `AllowOverride All`)做 SPA 回退:
|
||
|
||
```apache
|
||
RewriteEngine On
|
||
RewriteCond %{REQUEST_FILENAME} -f [OR]
|
||
RewriteCond %{REQUEST_FILENAME} -d
|
||
RewriteRule ^ - [L]
|
||
RewriteRule ^ index.html [L]
|
||
```
|
||
|
||
把 `/root/html`(或 `/var/www/html`)设为 `DocumentRoot`,访问站点即可。开发预览用 `npm run dev`(http://localhost:5173)。
|
||
|
||
## 如何新增一个项目页签
|
||
|
||
1. 复制 `src/modules/whiteboard/`(或 `mobile-game/`)为 `src/modules/<新项目>/`。
|
||
2. 改 `<新项目>/index.js` 的 `id` / `tabKey` / `order` / `component`。
|
||
3. 在 `src/i18n/locales/zh-CN.js` 与 `en.js` 的 `tabs` 下加对应文案。
|
||
4. `npm run build` -- 页签与路由自动出现,无需改导航或路由代码。
|
||
|
||
---
|
||
|
||
## 开发命令
|
||
|
||
```bash
|
||
npm install # 首次安装依赖
|
||
npm run dev # 开发服务器 http://localhost:5173
|
||
npm run build # 构建到 /root/html
|
||
npm run preview # 本地预览构建产物
|
||
```
|