Appearance
开发指南
欢迎加入 QXS-BNS 组件库的开发!本指南将带你从零开始,完成从环境搭建到发布的完整开发流程。
🚀 新人入门流程
第一步:环境准备
系统要求
工具 | 版本要求 | 说明 |
---|---|---|
Node.js | >= 16.0.0 | 推荐使用 LTS 版本 |
pnpm | >= 7.0.0 | 包管理器,必须使用 pnpm |
Git | >= 2.20.0 | 版本控制工具 |
VS Code | 最新版 | 推荐的代码编辑器 |
安装工具
bash
# 安装 Node.js (推荐使用 nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install --lts
nvm use --lts
# 安装 pnpm
npm install -g pnpm
# 验证安装
node --version
pnpm --version
git --version
第二步:获取代码
bash
# 1. Fork 项目到你的 GitHub 账号
# 2. 克隆你的 Fork
git clone https://github.com/YOUR_USERNAME/qxs-bns.git
cd qxs-bns
# 3. 添加上游仓库
git remote add upstream https://github.com/trry-hub/qxs-bns.git
# 4. 安装依赖
pnpm install
第三步:启动开发环境
bash
# 启动文档站点 (推荐新人先看文档)
pnpm docs:dev
# 启动 playground (用于测试组件)
pnpm play:dev
# 构建所有包 (验证环境是否正常)
pnpm build
访问 http://localhost:5173
查看文档站点。
📁 项目结构详解
qxs-bns/
├── packages/ # 📦 核心包目录 (Monorepo 架构)
│ ├── components/ # 🧩 Vue 组件库
│ │ ├── src/ # 组件源码
│ │ ├── __tests__/ # 组件测试
│ │ └── package.json # 包配置
│ ├── utils/ # 🛠️ 工具函数库
│ ├── hooks/ # 🪝 Vue 3 Hooks
│ ├── directives/ # 📋 自定义指令
│ ├── icons/ # 🎨 SVG 图标库
│ └── theme-chalk/ # 🎨 主题样式
├── docs/ # 📚 文档站点
│ ├── guide/ # 指南文档
│ ├── api/ # API 文档
│ └── demo/ # 演示页面
├── playground/ # 🎮 开发测试环境
├── internal/ # 🔧 内部工具
│ ├── build/ # 构建脚本
│ ├── config/ # 配置文件
│ └── plugins/ # 构建插件
├── scripts/ # 📜 自动化脚本
├── utils/ # 🛠️ 开发工具
└── typings/ # 📝 TypeScript 类型定义
🔄 完整开发流程
第一步:同步代码
bash
# 切换到主分支
git checkout main
# 同步上游代码
git fetch upstream
git merge upstream/main
# 推送到你的 Fork
git push origin main
第二步:创建功能分支
bash
# 创建功能分支 (推荐命名规范)
git checkout -b feat/add-new-component # 新功能
git checkout -b fix/component-bug # Bug 修复
git checkout -b docs/update-guide # 文档更新
git checkout -b refactor/optimize-utils # 代码重构
第三步:开发新功能
🧩 开发组件 (推荐使用自动化工具)
bash
# 使用自动化脚本创建组件 (推荐)
pnpm component:create your-component
# 这个命令会自动创建:
# - 组件文件结构
# - 组件模板代码
# - 测试文件
# - 文档模板
# - 自动引入到导出文件
手动创建组件 (如果需要自定义):
bash
# 1. 创建组件目录
mkdir packages/components/src/your-component
cd packages/components/src/your-component
# 2. 创建文件结构
mkdir src __tests__ style
touch index.ts src/your-component.vue src/types.ts __tests__/your-component.test.ts style/index.scss
组件文件结构:
your-component/
├── index.ts # 📤 导出文件
├── src/
│ ├── your-component.vue # 🧩 组件实现
│ └── types.ts # 📝 类型定义
├── __tests__/
│ └── your-component.test.ts # 🧪 单元测试
└── style/
└── index.scss # 🎨 组件样式
组件开发模板:
vue
<!-- packages/components/src/your-component/src/your-component.vue -->
<template>
<div :class="ns.b()" :style="style">
<slot />
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useNamespace } from '@qxs-bns/hooks'
import type { YourComponentProps } from './types'
defineOptions({
name: 'QxsYourComponent' // 组件名必须以 Qxs 开头
})
const props = withDefaults(defineProps<YourComponentProps>(), {
size: 'medium'
})
const emit = defineEmits<{
click: [event: MouseEvent]
}>()
const ns = useNamespace('your-component')
const style = computed(() => ({
// 计算样式
}))
const handleClick = (event: MouseEvent) => {
emit('click', event)
}
</script>
类型定义:
typescript
// packages/components/src/your-component/src/types.ts
export interface YourComponentProps {
size?: 'small' | 'medium' | 'large'
disabled?: boolean
}
export type YourComponentInstance = InstanceType<typeof YourComponent>
导出文件:
typescript
// packages/components/src/your-component/index.ts
import { withInstall } from '@qxs-bns/utils'
import YourComponent from './src/your-component.vue'
export const QxsYourComponent = withInstall(YourComponent)
export default QxsYourComponent
export * from './src/types'
🛠️ 开发工具函数
bash
# 创建工具函数
pnpm comp:create utils/your-util
# 手动创建
mkdir packages/utils/src
touch packages/utils/src/your-util.ts
工具函数模板:
typescript
// packages/utils/src/your-util.ts
/**
* 你的工具函数描述
* @param param1 参数1描述
* @param param2 参数2描述
* @returns 返回值描述
*/
export function yourUtil(param1: string, param2?: number): string {
// 实现逻辑
return `${param1}-${param2 || 0}`
}
/**
* 工具类示例
*/
export class YourUtilClass {
private value: string
constructor(initialValue: string) {
this.value = initialValue
}
public getValue(): string {
return this.value
}
public setValue(newValue: string): void {
this.value = newValue
}
}
第四步:配置依赖 (重要!)
如果组件有特殊依赖,必须配置依赖映射:
bash
# 添加依赖 Element Plus 的桌面端组件
pnpm deps:add QxsYourComponent your-component element-plus
# 添加不依赖 Element Plus 的移动端组件
pnpm deps:add QxsMobileComponent mobile-component lodash-es @vueuse/core
# 查看所有依赖配置
pnpm deps:list
# 查看依赖特定库的组件
pnpm deps:check element-plus
第五步:编写测试 (必须)
typescript
// packages/components/src/your-component/__tests__/your-component.test.ts
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import YourComponent from '../src/your-component.vue'
describe('YourComponent', () => {
it('should render correctly', () => {
const wrapper = mount(YourComponent, {
props: {
size: 'medium'
}
})
expect(wrapper.classes()).toContain('qxs-your-component')
expect(wrapper.classes()).toContain('qxs-your-component--medium')
})
it('should emit click event', async () => {
const wrapper = mount(YourComponent)
await wrapper.trigger('click')
expect(wrapper.emitted('click')).toBeTruthy()
})
it('should handle props correctly', () => {
const wrapper = mount(YourComponent, {
props: {
disabled: true
}
})
expect(wrapper.props('disabled')).toBe(true)
})
})
运行测试:
bash
# 运行所有测试
pnpm test
# 运行特定组件测试
pnpm test your-component
# 查看测试覆盖率
pnpm test:coverage
第六步:编写文档 (自动生成)
bash
# 自动生成文档模板
pnpm docs:new your-component
文档模板会自动创建在 docs/guide/components/your-component.md
:
markdown
# YourComponent 组件
组件的简短描述
## 基础用法
\`\`\`vue
<template>
<QxsYourComponent size="medium" @click="handleClick">
内容
</QxsYourComponent>
</template>
<script setup>
import { QxsYourComponent } from '@qxs-bns/components'
const handleClick = () => {
console.log('clicked')
}
</script>
\`\`\`
## API
### Props
| 属性 | 说明 | 类型 | 默认值 |
|------|------|------|--------|
| size | 尺寸 | `'small' \| 'medium' \| 'large'` | `'medium'` |
| disabled | 是否禁用 | `boolean` | `false` |
### Events
| 事件名 | 说明 | 参数 |
|--------|------|------|
| click | 点击事件 | `(event: MouseEvent) => void` |
### Slots
| 插槽名 | 说明 |
|--------|------|
| default | 默认内容 |
第七步:本地验证
bash
# 1. 代码检查
pnpm lint
# 2. 类型检查
pnpm lint:tsc
# 3. 运行测试
pnpm test
# 4. 构建验证
pnpm build
# 5. 在 playground 中测试
pnpm play:dev
第八步:提交代码
bash
# 1. 添加文件
git add .
# 2. 提交 (使用规范的提交信息)
pnpm git-commit
# 或手动提交
git commit -m "feat(components): 添加 YourComponent 组件
- 实现基础功能
- 添加单元测试
- 完善文档
Closes #123"
# 3. 推送到你的 Fork
git push origin feat/add-new-component
第九步:创建 Pull Request
- 访问你的 GitHub Fork 页面
- 点击 "Compare & pull request"
- 填写 PR 描述:
- 功能说明
- 测试情况
- 相关 Issue
- 等待代码审查
📋 代码规范
TypeScript 规范
typescript
// ✅ 好的示例
interface ComponentProps {
size?: 'small' | 'medium' | 'large'
disabled?: boolean
onClick?: (event: MouseEvent) => void
}
// ❌ 避免的写法
interface ComponentProps {
size?: string // 应该使用联合类型
disabled?: any // 应该使用具体类型
}
Vue 组件规范
vue
<!-- ✅ 推荐的组件结构 -->
<template>
<div :class="ns.b()" v-bind="$attrs">
<slot />
</div>
</template>
<script setup lang="ts">
import { useNamespace } from '@qxs-bns/hooks'
defineOptions({
name: 'QxsYourComponent', // 必须以 Qxs 开头
inheritAttrs: false // 手动控制属性继承
})
const ns = useNamespace('your-component')
</script>
样式规范
scss
// ✅ 使用 BEM 命名法
.qxs-your-component {
// 基础样式
&__element {
// 元素样式
}
&--modifier {
// 修饰符样式
}
&.is-disabled {
// 状态样式
}
}
测试规范
typescript
// ✅ 完整的测试用例
describe('YourComponent', () => {
// 基础渲染测试
it('should render correctly', () => {
// 测试代码
})
// 属性测试
it('should handle props correctly', () => {
// 测试代码
})
// 事件测试
it('should emit events correctly', () => {
// 测试代码
})
// 边界情况测试
it('should handle edge cases', () => {
// 测试代码
})
})
🚀 发布流程
版本发布 (维护者)
bash
# 1. 确保在 main 分支
git checkout main
git pull upstream main
# 2. 运行发布脚本
pnpm release
# 这个脚本会:
# - 自动更新版本号
# - 生成 CHANGELOG
# - 创建 Git 标签
# - 构建所有包
# - 发布到 npm
手动发布特定包
bash
# 发布组件库
pnpm publish:components
# 发布工具库
pnpm publish:utils
# 发布 Hooks
pnpm publish:hooks
# 发布指令
pnpm publish:directives
# 发布图标库
pnpm publish:icons
文档部署
bash
# 构建文档
pnpm build:docs
# 文档会自动部署到 GitHub Pages
# 访问: https://qxs-bns.pages.dev/
🛠️ 常用命令
开发命令
bash
# 启动开发环境
pnpm docs:dev # 启动文档站点
pnpm play:dev # 启动 playground
# 构建相关
pnpm build # 构建所有包
pnpm build:components # 构建组件库
pnpm build:docs # 构建文档
# 测试相关
pnpm test # 运行所有测试
pnpm test:coverage # 测试覆盖率
pnpm lint # 代码检查
pnpm lint:tsc # TypeScript 类型检查
自动化命令
bash
# 组件开发
pnpm component:create [name] # 创建组件 (推荐)
pnpm comp:create [name] # 创建组件文件
pnpm comp:new [name] # 创建测试组件
pnpm docs:new [name] # 创建文档
# 依赖管理
pnpm deps:add [component] [file] [deps...] # 添加依赖配置
pnpm deps:remove [component] # 删除依赖配置
pnpm deps:list # 查看所有依赖
pnpm deps:check [dependency] # 查看特定依赖
# 版本管理
pnpm tag-manager # 标签管理工具
pnpm git-commit # 规范化提交
pnpm release # 发布新版本
📝 提交规范
快速开始
我们使用 Conventional Commits 规范来标准化提交信息。
bash
# 使用自动化工具 (推荐)
pnpm git-commit
# 手动提交
git commit -m "feat(components): 添加 YourComponent 组件
- 实现基础功能
- 支持多种尺寸
- 添加单元测试
- 完善文档
Closes #123"
详细指南
👉 Git 提交规范详细指南 - 包含完整的提交信息生成方法
该指南包含:
- 📋 完整的提交类型和作用域说明
- 🤖 AI 提交信息生成模板
- 📖 详细的示例和最佳实践
- 🚨 常见问题解决方案
- 🛠️ 自动化工具推荐
基本格式
<type>(<scope>): <subject>
<body>
<footer>
常用提交类型
类型 | 说明 | 示例 |
---|---|---|
feat | 新功能 | feat(components): 添加 Button 组件 |
fix | Bug 修复 | fix(utils): 修复日期格式化问题 |
docs | 文档更新 | docs(guide): 更新安装指南 |
style | 代码格式 | style: 修复 ESLint 警告 |
refactor | 代码重构 | refactor(hooks): 优化 usePagination |
test | 测试相关 | test(components): 添加 Button 测试 |
chore | 其他修改 | chore: 更新依赖版本 |
🔍 代码审查
Pull Request 检查清单
提交 PR 前请确保:
- [ ] 代码通过所有测试
- [ ] 代码通过 ESLint 检查
- [ ] 添加了必要的单元测试
- [ ] 更新了相关文档
- [ ] 遵循了代码规范
- [ ] 提交信息符合规范
审查要点
- 功能实现:是否正确实现了需求
- 代码质量:是否遵循最佳实践
- 测试覆盖:是否有足够的测试
- 文档完整:是否更新了文档
- 性能影响:是否影响性能
- 兼容性:是否保持向后兼容
🔧 故障排除
常见问题
1. 安装依赖失败
bash
# 清理缓存
pnpm store prune
rm -rf node_modules pnpm-lock.yaml
# 重新安装
pnpm install
2. 构建失败
bash
# 检查 TypeScript 错误
pnpm lint:tsc
# 检查 ESLint 错误
pnpm lint
# 清理构建缓存
rm -rf dist
pnpm build
3. 测试失败
bash
# 运行特定测试
pnpm test your-component
# 查看详细错误信息
pnpm test --reporter=verbose
# 更新测试快照
pnpm test --update-snapshots
4. 文档站点启动失败
bash
# 清理文档缓存
cd docs
rm -rf node_modules .vitepress/cache
pnpm install
pnpm dev
5. 组件依赖问题
bash
# 检查依赖配置
pnpm deps:list
# 重新配置依赖
pnpm deps:remove YourComponent
pnpm deps:add YourComponent your-component element-plus
调试技巧
1. 使用 Playground 调试
bash
# 启动 playground
pnpm play:dev
# 在 playground/src/App.vue 中测试组件
2. 使用 Vue DevTools
安装 Vue DevTools 浏览器扩展,可以:
- 查看组件树
- 检查组件状态
- 监听事件
- 性能分析
3. 使用 Console 调试
typescript
// 在组件中添加调试信息
console.log('Component props:', props)
console.log('Component state:', reactive_state)
性能优化
1. 构建优化
bash
# 分析构建产物
pnpm build --analyze
# 检查包大小
pnpm build && ls -la dist/
2. 开发优化
typescript
// 使用 shallowRef 优化大对象
import { shallowRef } from 'vue'
const largeObject = shallowRef(initialValue)
// 使用 markRaw 标记不需要响应式的对象
import { markRaw } from 'vue'
const staticObject = markRaw(someObject)
📚 学习资源
官方文档
推荐阅读
🤝 贡献指南
贡献类型
我们欢迎以下类型的贡献:
- 🐛 Bug 修复 - 修复现有功能的问题
- ✨ 新功能 - 添加新的组件或工具函数
- 📚 文档改进 - 改进文档内容和示例
- 🎨 样式优化 - 改进 UI 和用户体验
- ⚡ 性能优化 - 提升性能和效率
- 🧪 测试增强 - 增加测试覆盖率
贡献流程
- Fork 项目 - 在 GitHub 上 Fork 项目
- 创建分支 - 基于 main 分支创建功能分支
- 开发功能 - 按照开发规范实现功能
- 编写测试 - 确保测试覆盖率
- 更新文档 - 更新相关文档
- 提交代码 - 使用规范的提交信息
- 创建 PR - 提交 Pull Request
- 代码审查 - 等待维护者审查
- 合并代码 - 审查通过后合并
成为维护者
如果你:
- 持续贡献高质量代码
- 积极参与社区讨论
- 帮助其他开发者解决问题
我们欢迎你成为项目维护者!
🆘 获取帮助
问题反馈
- Bug 报告: GitHub Issues
- 功能请求: GitHub Issues
- 问题讨论: GitHub Discussions
联系方式
- 项目维护者: @trry-hub
- 在线文档: https://qxs-bns.pages.dev/
- 更新日志: 查看各包的 CHANGELOG.md 文件
社区支持
- 加入我们的开发者群组
- 关注项目更新动态
- 参与技术讨论和分享
🎯 快速上手检查清单
新人开发者可以按照以下清单快速上手:
环境准备
- [ ] 安装 Node.js (>= 16.0.0)
- [ ] 安装 pnpm (>= 7.0.0)
- [ ] 安装 Git (>= 2.20.0)
- [ ] 安装 VS Code 和推荐插件
项目设置
- [ ] Fork 项目到个人账号
- [ ] 克隆项目到本地
- [ ] 安装项目依赖
- [ ] 启动开发环境
开发流程
- [ ] 创建功能分支
- [ ] 使用自动化工具创建组件
- [ ] 编写组件代码和测试
- [ ] 运行测试和代码检查
- [ ] 提交代码并创建 PR
学习资源
- [ ] 阅读项目文档
- [ ] 查看现有组件示例
- [ ] 了解代码规范
- [ ] 熟悉开发工具
🎉 恭喜! 你已经掌握了 QXS-BNS 组件库的完整开发流程。现在可以开始你的第一个贡献了!
如果在开发过程中遇到任何问题,请随时通过上述渠道寻求帮助。我们的社区非常友好,乐于帮助新的贡献者!