Holodex架构深度剖析:Vue 2 + Vite + Vuex前端工程实践完整指南

Holodex架构深度剖析:Vue 2 + Vite + Vuex前端工程实践完整指南

【免费下载链接】Holodex Holodex frontend source code 【免费下载链接】Holodex 项目地址: https://gitcode.com/gh_mirrors/ho/Holodex

Holodex 是一个面向 Vtuber 视频与直播的开源前端项目,基于 Vue 2.7 + Vite + Vuex 构建,支持多语言、PWA 离线缓存与多画面同步观看。本文带你完整拆解它的目录结构、构建配置、状态管理与工程化细节,新手也能快速读懂这套 Vue 2 + Vite + Vuex 技术栈的真实用法 🎯

Holodex 平台界面总览,展示 Vtuber 视频列表与多语言界面

一、Holodex 是什么?一分钟了解项目

Holodex 是一个聚合 Hololive、Nijisanji 等 Vtuber 机构视频、直播与实时字幕(TL)的平台,核心功能包括:

  • 📺 视频聚合:按机构/UP主浏览视频、剪辑、合作与音乐内容
  • 🎥 MultiView 多画面:一屏同看多路直播,支持自定义布局与分享
  • 🌍 20+ 语言:日语、简体中文、韩语等多语言支持
  • 📱 PWA 应用:可安装到手机桌面,支持离线缓存
  • ⌨️ TL 实时字幕:直播弹幕翻译与实时字幕系统

Holodex MultiView 多画面布局,可同时观看多个直播窗口与聊天区

二、目录结构:清晰的工程化分层

整个项目遵循标准的前端工程分层,结构定义见 README.md:

docs/     # 变更记录,托管在 Pages
public/   # 静态资源
src/
├── components/   # Vue 组件(按业务域分文件夹)
├── locales/      # 各语言的 UI 翻译(YAML 格式)
├── plugins/      # Vuetify、i18n 等插件定义
├── mixins/       # 跨组件复用的 Vue mixins
├── external/     # 引入项目内维护的第三方组件
├── router/       # 路由定义
├── store/       # Vuex 状态模块(与页面一一对应)
├── utils/       # 工具函数
├── views/        # 页面级组件
└── App.vue      # 应用入口

值得学习的点:components 按业务域组织(chat/、multiview/、player/、video/ 等),而不是按"大组件/小组件"划分,团队协作时定位代码非常快。

三、Vite 构建配置:Vue 2 也能用上 Vite

很多人以为 Vite 只配 Vue 3,Holodex 用 vite.config.js 证明了 Vue 2 同样可以丝滑接入:

import { createVuePlugin } from "vite-plugin-vue2";
import ViteComponents, { VuetifyResolver } from "vite-plugin-components";
import { VitePWA } from "vite-plugin-pwa";

3.1 关键插件一览

插件作用
vite-plugin-vue2让 Vite 编译 Vue 2 SFC 单文件组件
vite-plugin-components自动按需解析 Vuetify 组件(VuetifyResolver),减少打包体积
@rollup/plugin-yaml直接 import YAML 文件,翻译文件零配置加载
vite-plugin-pwa生成 Service Worker 与 PWA manifest
rollup-plugin-visualizer构建产物体积分析,优化打包必备

3.2 开发代理与 API 转发

server: {
    port: 8080,
    proxy: {
        "/api": {
            target: API_BASE_URL,
            changeOrigin: true,
            secure: false,
            ws: true,   // 支持 WebSocket 转发
        },
    },
},

本地开发时 /api 请求自动代理到 staging 后端(默认 https://staging.holodex.net),无需处理跨域 👌

3.3 双入口构建:主站 + SEO 页

input: {
    main: path.resolve(__dirname, "index.html"),
    seo: path.resolve(__dirname, "seo.html"),
},

通过 seo.html 额外产出 SEO 落地页,这是 Vite 多入口的典型用法。

四、应用入口:main.ts 与 App.vue

入口文件 src/main.ts 展示了 Vue 2 项目的标准插件装配顺序:

  1. 注册 vue-gtag(统计)、vue-meta(SEO meta 信息)、vue-i18n(国际化)
  2. 挂载 PortalVue 与全局图标 $prototype.icons
  3. 创建根实例,注入 i18n / router / store / vuetify

一个有意思的细节:

Vue.config.devtools = window.location.hostname === "localhost";
Vue.config.performance = ["localhost", "staging.holodex.net"].includes(window.location.hostname);

仅在开发/预发环境开启 Devtools 与性能面板,生产环境零开销——这种环境感知的开关值得借鉴。

页面容器 src/App.vue 中则用了 keep-alive 做页面缓存:

<keep-alive max="4" exclude="Watch,MugenClips,EditVideo,MultiView,Channel,Playlists,About">
  <router-view :key="viewKey" />
</keep-alive>

最多缓存 4 个页面,并精准排除直播页等需要实时刷新的视图,兼顾性能与体验 ⚡

五、Vuex 状态管理:模块化 + 持久化 + 迁移

这是 Holodex 最值得学习的部分。根 store 定义在 src/store/index.js,采用三大技术组合:

5.1 模块化拆分

按业务域拆出 12 个模块,每个文件大致对应一个页面:

modules: {
    home, channel, channels, watch, settings,
    favorites, multiview, playlist, history,
    orgs, tlclient,
}

模块文件位于 src/store/,例如 multiview.module.ts、playlist.module.ts。

5.2 持久化 + 数据迁移

createPersistedState({
    key: "holodex-v2",
    paths: persistedPaths,   // 只持久化白名单字段
    getState: createMigrate(migrations, "migration.version"),
    setState: debounce((key, state, storage) => {
        storage.setItem(key, JSON.stringify(state));
    }),
}),
  • 白名单持久化:只把 orgs、settings、favorites 等 20 多个字段存入 localStorage,而不是整个 state
  • 防抖写入:debounce 降低高频 mutation 对存储的冲击
  • 版本化迁移:通过 vuex-persistedstate-migrate 管理历史数据升级,已积累 v2 → v11 共 9 个迁移脚本(如 v5-20210621-library-to-playlist.ts 将旧的"收藏夹"数据结构升级为"播放列表")

💡 迁移脚本命名带版本号与日期(v10-20230401-fools.ts),未来维护者能一眼看懂每个版本的变更背景。

5.3 跨标签页状态同步

createMutationsSharer({
    predicate: (mutation) =>
        mutation.type.match(syncedModules) || syncedMutations.has(mutation.type),
}),

利用 vuex-shared-mutations 让 playlist、settings、history 三个模块及登录、收藏等关键 mutation 在多个浏览器标签页之间自动同步——用户在 A 标签页登录,B 标签页立刻同步状态,体验细节拉满 🚀

六、Vue Router 路由:懒加载与国际化拦截

路由定义在 src/router/index.js,几个亮点:

全量懒加载:除首页外所有页面都是动态 import,按需加载:

const Watch = () => import("../views/Watch.vue");
const MultiView = () => import("../views/MultiView.vue");

嵌套路由:/channel/:id 下挂 clips、collabs、about 等子路由,频道页复用同一组件不同 tab。

全局前置守卫做三件事:

router.beforeEach((to, from, next) => {
    // 1. 记录上一页路径,供"返回"使用
    // 2. 从 URL query 读取 org/lang 参数,动态切换机构与语言
    // 3. 非英语时异步加载语言包再放行
    if (actualLang !== "en") {
        loadLanguageAsync(actualLang).then(() => next());
    } else { next(); }
});

scrollBehavior 中还配合 store 实现了"回到页面顶部 + 触发重新加载"的联动逻辑。

七、i18n 多语言:语言包按需分包

多语言配置集中在 src/plugins/vuetify.js,采用动态 import 按需加载语言包:

async ja() {
    await import("dayjs/locale/ja");
    return import("@/locales/ja-JP/ui.yml");
},

配合 Vite 的 code splitting,用户只下载自己语言的那份 YAML,英语包甚至内联进主包。翻译源文件位于 src/locales/,覆盖 20+ 语言目录(en/、ja-JP/、zh-CN/、ko-KR/ 等),每个目录含 ui.yml(界面文本)与 seo.yml(SEO 文本)。

此外还实现了俄语的完整复数规则(pluralizationRules.ru),细节非常到位。

八、API 层与实时通信

后端请求统一封装在 src/utils/backend-api.ts:

export const API_BASE_URL = `${window.location.origin}/api`;
export const axiosInstance = axios.create({
    baseURL: `${API_BASE_URL}/v2`,
    timeout: 30000,
});
  • 静态资源(/statics/*.json)用原生 fetch 以利用浏览器预取
  • 机构列表 orgs.json 走 PWA 的 CacheFirst 离线缓存策略
  • 实时数据(直播状态、TL 字幕)通过 socket.io 共享 WebSocket 连接,store 里用 activeSockets 计数器管理,当所有页面的连接都释放时才断开(见 src/store/index.js)

TLdex 实时字幕系统的整体架构如下图所示:

Holodex TLdex 实时字幕架构图,展示输入、去重、存储与输出四层结构

九、PWA:离线可用的安装应用

通过 vite-plugin-pwa + src/sw.ts 生成 Service Worker,vite.config.js 中定义精细的运行时缓存策略:

资源策略说明
Google FontsCacheFirst最多 30 条
YouTube 频道头像CacheFirst缓存 24 小时
YouTube Player APICacheFirst缓存 3 小时
/api/statics/*CacheFirst静态数据 24 小时

配合 vite-plugin-pwa 的 manifest(见 vite.config.js),应用可安装到手机/桌面,移动端还配了下拉刷新组件 PullToRefresh.vue 与安装引导 InstallPrompt.vue。

十、本地运行:5 分钟跑起来

git clone https://gitcode.com/gh_mirrors/ho/Holodex
cd Holodex
npm install
# 默认代理到 staging 环境,可复制 .env.placeholder 修改 API_BASE_URL
npm run serve

启动后访问 localhost:8080。其他常用命令(见 package.json):

  • npm run build:以 prod 模式构建
  • npm run lint:ESLint 检查并自动修复
  • npm test:Jest 单元测试(测试位于 tests/)

工程化配套还有:Husky + lint-staged(提交前自动 lint)、TypeScript 渐进式接入(.ts 与 .js 混写,核心模块逐步迁移)、jest.config.js 配置单测。

十一、社区与贡献

作为开源项目,Holodex 欢迎开发者、译者与设计者参与,角色介绍如下:

![Holodex 开源社区角色介绍,包含设计、开发、翻译等岗位](https://raw.gitcode.com/gh_mirrors/ho/Holodex/raw/660ed92664b8816aa81256acd257c48419581931/docs/holodex roles.png?utm_source=gitcode_repo_files)

更新日志可查阅 docs/CHANGELOG.md。

总结

Holodex 是一套生产级的 Vue 2 + Vite + Vuex 前端工程范本,核心收获:

  1. ✅ Vite 构建:vite-plugin-vue2 + 组件自动解析 + 多入口 + PWA,构建配置集中透明
  2. ✅ Vuex 三板斧:模块化拆分、白名单持久化、版本化数据迁移 + 跨标签页同步
  3. ✅ 按需加载无处不在:路由懒加载、语言包分包、keep-alive 缓存控制
  4. ✅ 工程化细节:lint-staged 提交流水线、构建体积可视化、环境感知开关

对于想学习 Vue 2 时代工程化最佳实践的开发者,这个项目几乎涵盖了所有值得参考的模式,值得完整读一遍源码 🎓

【免费下载链接】Holodex Holodex frontend source code 【免费下载链接】Holodex 项目地址: https://gitcode.com/gh_mirrors/ho/Holodex

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值