一个基于 Electron + Vue 3 + TypeScript 的桌面音乐播放器,支持 Bilibili 歌曲搜索与播放。
- 前端: Vue 3 + TypeScript + Composition API
- 桌面: Electron + electron-vite
- 状态管理: Pinia + pinia-plugin-persistedstate
- UI: Naive UI + Tailwind CSS 4 + SCSS
- 构建: Vite + electron-vite
- 代码规范: ESLint 9 + @antfu/eslint-config
- 测试: Vitest
- Bilibili 歌曲搜索与播放
- 播放列表管理(最近播放、收藏、浏览器插件导入)
- 歌词显示与同步
- 深色/浅色主题切换
- 响应式布局
- 浏览器扩展导入歌曲
- 客户端搜索功能
# 开发
pnpm dev # 启动开发环境
# 构建
pnpm build # 类型检查 + electron-vite 构建
pnpm build:nocheck # 仅构建
pnpm build:win # Windows
pnpm build:mac # macOS
pnpm build:linux # Linux
# 类型检查
pnpm typecheck # 主进程 + 渲染进程
pnpm typecheck:node # 仅 Electron 主进程
pnpm typecheck:web # 仅 Vue 渲染进程
# 代码规范
pnpm lint # ESLint 检查
pnpm lint:fix # 自动修复kolaBiliHelper/
├── electron/ # Electron 主进程
│ ├── main/ # 主进程逻辑 (Node.js): index, tray, ipcMain, utils
│ ├── preload/ # 预加载脚本
│ └── server/ # 内嵌 HTTP 服务器
├── src/ # 渲染进程 (Vue 3)
│ ├── api/ # API 模块 (bilibili, search, wbi)
│ ├── assets/ # 静态资源 (CSS, SVG)
│ ├── components/ # Vue 组件
│ │ ├── card/ # SongCard
│ │ ├── common/ # TextContainer
│ │ ├── control/ # PlayerControl, Volume, Progress
│ │ ├── global/ # AppProvider, Loading, Like
│ │ ├── layout/ # Header, Sidebar
│ │ ├── list/ # SongList, SearchList
│ │ ├── menus/ # 上下文菜单
│ │ └── modals/ # LoginModal, PlaylistModal, CloseAppModal
│ ├── hooks/ # Composables
│ ├── plugins/ # 插件 (store setup)
│ ├── router/ # Vue Router
│ ├── stores/ # Pinia 状态 (play, search, system, user)
│ ├── types/ # TypeScript 定义 (app.d.ts)
│ └── utils/ # 工具函数 (request, adapter, player, helper, time)
├── constants/ # 常量定义
│ ├── ipcChannels.ts # IPC 通道定义
│ ├── pageId.ts # 页面标识符
│ ├── playStatus.ts # 播放状态常量
│ ├── renderer.ts # 渲染进程常量
│ ├── urls.ts # URL 常量
│ └── browserExtension.ts # 浏览器扩展常量
└── index.html
@/*→src/*@constants/*→constants/*
| 类型 | 规范 | 示例 |
|---|---|---|
| 变量、函数、ref、props、hooks | camelCase |
currentSong, usePlayStore |
| 组件、组件文件 | PascalCase |
SongCard.vue, PlayerControl |
| 常量 | UPPER_SNAKE_CASE |
HISTORY_MAX, PLAY_MODE |
| 文件夹、HTML 类、插槽、模板 props | kebab-case |
player-control, class="flex gap-2" |
| 接口、类型 | I 前缀 + PascalCase |
ISong, IPlaylist |
| 枚举 | E 前缀 + PascalCase |
EPlayState |
| API 函数 | api 前缀 |
apiGetUser, apiSearchSongs |
| 全局状态实例 | store 前缀 |
storeUser, storePlay |
| 数据转换函数 | transform 前缀 |
transformDate |
- 使用
<script setup lang="ts">+ Composition API - 文件名:
PascalCase.vue - 模板中显式使用
props.xx访问属性(不解构) - 结构顺序: script → template → style
- Props 顺序: visible → model → emit → setup
- Composition API 风格:
defineStore('name', () => {...}) - 使用
storeToRefs进行响应式解构 - Store 文件:
src/stores/{name}Store.ts
- 遵循 @antfu/eslint-config 模块排序
- 禁止行内导出
- 所有具名导出在文件末尾统一导出
- 函数需编写 JSDoc/TSDoc 注释
interface ISong {
id: string
bvid: string
title: string
artist: string
pic: string
duration: number | string
url?: string
custom?: {
source?: 'browser-extension' | 'client-search'
}
}HISTORY_PAGE: 最近播放LIKED_PAGE: 收藏歌曲PLUGIN_PAGE: 浏览器扩展导入的歌曲
格式: feat(模块名): 描述、fix(模块名): 描述、refactor(模块名): 描述
示例:
feat(player): 添加播放进度同步
fix(search): 修复搜索结果排序
refactor(api): 重构 WBI 签名逻辑
- ESLint
- Prettier
- Volar
- TypeScript Vue Plugin
欢迎 Fork 和 Pull Request!
MIT