主题
贡献指南
欢迎为 NeteaseMiniPlayer v2 (NMP v2) 项目做出贡献!本指南将帮助你了解如何参与项目开发。
🤝 如何贡献
贡献方式
- 🐛 报告 Bug:发现问题请提交 Issue
- 💡 功能建议:提出新功能想法
- 📝 文档改进:完善项目文档
- 🔧 代码贡献:修复 Bug 或添加新功能
- 🌐 翻译工作:帮助翻译文档
参与流程
Fork 项目
bash# 在 GitHub 上 Fork 项目到你的账户克隆仓库
bashgit clone https://github.com/your-username/NeteaseMiniPlayer.git cd NeteaseMiniPlayer创建分支
bashgit checkout -b feature/your-feature-name # 或 git checkout -b fix/your-bug-fix安装依赖
bashnpm install开发和测试
bash# 启动开发服务器 npm run dev # 运行测试 npm test提交更改
bashgit add . git commit -m "feat: 添加新功能描述"推送分支
bashgit push origin feature/your-feature-name创建 Pull Request
- 在 GitHub 上创建 PR
- 详细描述你的更改
- 等待代码审查
📋 开发规范
代码风格
JavaScript 规范
javascript
// ✅ 推荐的代码风格
class MusicPlayer {
constructor(options = {}) {
this.config = {
theme: 'auto',
position: 'bottom-right',
...options
}
}
/**
* 初始化播放器
* @param {Object} config - 配置选项
* @returns {Promise<void>}
*/
async init(config) {
try {
await this.loadResources()
this.render()
} catch (error) {
console.error('播放器初始化失败:', error)
throw error
}
}
// 私有方法使用下划线前缀
_validateConfig(config) {
if (!config.songId && !config.playlistId) {
throw new Error('必须提供 songId 或 playlistId')
}
}
}
// 常量使用大写
const DEFAULT_CONFIG = {
THEME: 'auto',
POSITION: 'bottom-right'
}
// 使用 const/let,避免 var
const apiUrl = 'https://api.hypcvgm.top'
let currentSong = nullCSS 规范
css
/* ✅ 推荐的 CSS 风格 */
.netease-mini-player {
/* 使用 BEM 命名规范 */
position: relative;
background: var(--nmp-bg-color);
border-radius: 8px;
transition: all 0.3s ease;
}
.netease-mini-player__controls {
display: flex;
align-items: center;
gap: 12px;
}
.netease-mini-player__button {
padding: 8px;
border: none;
background: transparent;
cursor: pointer;
}
.netease-mini-player__button--active {
color: var(--nmp-primary-color);
}
/* 响应式设计 */
@media (max-width: 768px) {
.netease-mini-player {
width: 100%;
border-radius: 0;
}
}
/* 深色主题 */
.netease-mini-player[data-theme="dark"] {
--nmp-bg-color: #1a1a1a;
--nmp-text-color: #ffffff;
}命名规范
- 变量和函数:使用 camelCase
- 常量:使用 UPPER_SNAKE_CASE
- 类名:使用 PascalCase
- CSS 类:使用 kebab-case 或 BEM
- 文件名:使用 kebab-case
注释规范
javascript
/**
* 播放器核心类
* @class MusicPlayer
* @description 提供音乐播放功能的核心类
*/
class MusicPlayer {
/**
* 播放指定歌曲
* @param {string} songId - 歌曲 ID
* @param {Object} options - 播放选项
* @param {boolean} options.autoplay - 是否自动播放
* @returns {Promise<void>}
* @throws {Error} 当歌曲 ID 无效时抛出错误
*/
async playSong(songId, options = {}) {
// 实现代码...
}
}🧪 测试要求
测试覆盖率
- 单元测试:覆盖率 ≥ 80%
- 集成测试:覆盖主要功能流程
- E2E 测试:覆盖用户关键操作
测试示例
单元测试
javascript
// tests/unit/player.test.js
import { describe, it, expect, beforeEach } from 'vitest'
import { MusicPlayer } from '../src/player.js'
describe('MusicPlayer', () => {
let player
beforeEach(() => {
player = new MusicPlayer()
})
it('应该正确初始化默认配置', () => {
expect(player.config.theme).toBe('auto')
expect(player.config.position).toBe('bottom-right')
})
it('应该验证必需的配置参数', () => {
expect(() => {
player._validateConfig({})
}).toThrow('必须提供 songId 或 playlistId')
})
})集成测试
javascript
// tests/integration/api.test.js
import { describe, it, expect } from 'vitest'
import { ApiService } from '../src/services/api.js'
describe('ApiService Integration', () => {
it('应该能够获取歌曲信息', async () => {
const api = new ApiService()
const songInfo = await api.getSongInfo('1823012873')
expect(songInfo).toHaveProperty('name')
expect(songInfo).toHaveProperty('artist')
expect(songInfo).toHaveProperty('url')
})
})E2E 测试
javascript
// tests/e2e/player.spec.js
import { test, expect } from '@playwright/test'
test('播放器基本功能', async ({ page }) => {
await page.goto('/demo')
// 检查播放器是否渲染
const player = page.locator('.netease-mini-player')
await expect(player).toBeVisible()
// 测试播放按钮
const playButton = page.locator('.play-button')
await playButton.click()
await expect(playButton).toHaveClass(/playing/)
})运行测试
bash
# 运行所有测试
npm test
# 运行单元测试
npm run test:unit
# 运行集成测试
npm run test:integration
# 运行 E2E 测试
npm run test:e2e
# 生成覆盖率报告
npm run test:coverage📝 提交规范
Commit Message 格式
使用 Conventional Commits 规范:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]类型说明
feat: 新功能fix: Bug 修复docs: 文档更新style: 代码格式调整refactor: 代码重构test: 测试相关chore: 构建过程或辅助工具的变动
示例
bash
# 新功能
git commit -m "feat(player): 添加歌词显示功能"
# Bug 修复
git commit -m "fix(api): 修复歌曲信息获取失败的问题"
# 文档更新
git commit -m "docs: 更新 API 使用说明"
# 重构
git commit -m "refactor(ui): 优化播放器组件结构"🔍 Pull Request 检查清单
提交 PR 前请确保:
- [ ] 代码遵循项目规范
- [ ] 添加了必要的测试
- [ ] 测试全部通过
- [ ] 更新了相关文档
- [ ] Commit message 符合规范
- [ ] 没有引入 breaking changes(如有请说明)
PR 模板
markdown
## 📋 变更说明
### 变更类型
- [ ] Bug 修复
- [ ] 新功能
- [ ] 文档更新
- [ ] 性能优化
- [ ] 代码重构
### 变更描述
简要描述你的更改...
### 测试
- [ ] 添加了单元测试
- [ ] 添加了集成测试
- [ ] 手动测试通过
### 截图(如适用)
添加截图来展示你的更改...
### 相关 Issue
Closes #123🎯 开发环境设置
推荐工具
- 编辑器:VS Code
- Node.js:≥ 16.0.0
- 包管理器:npm 或 yarn
- 浏览器:Chrome(用于调试)
VS Code 扩展推荐
json
{
"recommendations": [
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"bradlc.vscode-tailwindcss",
"ms-vscode.vscode-typescript-next"
]
}项目配置
json
// .vscode/settings.json
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"files.associations": {
"*.vue": "vue"
}
}📞 获取帮助
如果你在贡献过程中遇到问题:
- 搜索现有的 Issues
- 创建新的 Issue 描述你的问题
🙏 致谢
感谢所有为 NeteaseMiniPlayer v2 做出贡献的开发者!
记住:每一个贡献都很重要,无论大小。让我们一起打造更好的音乐播放器! 🎵
