贡献指南
介绍
🎉 欢迎来到 Vant 大家庭!感谢你选择 Vant 作为你的开发伙伴。
Vant 就像一个充满活力的开源社区花园,每一位开发者都是这个花园的园丁。无论你是想要报告一个小虫子🐛,还是想要贡献一朵美丽的代码之花🌸,我们都热烈欢迎!
在你准备向 Vant 提交 issue 或者 PR 之前,请先花几分钟时间阅读这份贡献指南。就像园丁需要了解花园的规则一样,这些指南将帮助你更好地参与到 Vant 的建设中来。让我们一起让这个开源花园更加繁荣美丽!🌺
Issue 规范 - 问题反馈的艺术 🎨
发现问题就像发现花园里的小虫害,及时反馈能让我们的花园更加健康!
- 🔍 先做个小侦探:遇到问题时,请先在 issue 列表中搜索一下,看看这个问题是否已经有其他园丁发现并记录了,或者已经被我们的园艺师修复了。
- 📝 写一份清晰的问题报告:提 issue 时,请用简洁明了的语言描述遇到的问题。就像给医生看病一样,详细描述症状、发生环境和复现步骤,这样我们就能快速定位问题并对症下药!
参与开发 - 成为代码园丁 👨💻
本地开发 - 搭建你的专属工作台 🛠️
想要在 Vant 花园里种植代码之花吗?首先我们需要准备好园艺工具!
在开始你的园艺之旅前,请确保你的工具箱里有 Node.js >= 18 这把万能铲子。
准备好了吗?让我们一步步搭建你的专属开发工作台:
# 克隆仓库
git clone git@github.com:vant-ui/vant.git
# 启用 pnpm 包管理器
corepack enable
# 安装依赖
pnpm i
# 进入开发模式,浏览器访问 localhost
pnpm dev🌳 选择你的开发分支 - 就像选择合适的花圃一样重要:
- main 分支 🌟 - Vant 4 版本的主花园,专为 Vue 3 打造的现代化花圃
- 3.x 分支 🌿 - Vant 3 版本的经典花园,同样适用于 Vue 3 的稳定花圃
- 2.x 分支 🌱 - Vant 2 版本的传统花园,为 Vue 2 量身定制的经典花圃
目录结构 - 探索花园的布局 🗺️
Vant 就像一个精心规划的植物园,采用 monorepo 的方式进行管理。所有的花圃都整齐地排列在 packages 目录这个大花园里:
root
└─ packages
├─ vant # 组件库
├─ vant-cli # 脚手架
├─ vant-icons # 图标库
├─ vant-use # Composition API
└─ .... # 其他周边 npm 包其中,packages/vant 目录就是我们花园的心脏 💖,这里存放着组件库的核心代码:
vant
├─ docs # 文档
├─ src # 组件源代码
├─ test # 单测工具类
└─ vant.config.mjs # 文档网站配置而 packages/vant/src 目录就像是组件们的温室大棚 🏠,每个文件夹都是一个独立的小花圃,精心培育着一个组件:
src
└─ button
├─ demo # 示例代码
├─ test # 单元测试
├─ Component.tsx # 组件
├─ index.ts # 组件入口
├─ index.less # 样式
├─ README.md # 英文文档
└─ README.zh-CN.md # 中文文档代码规范 - 让代码像诗一样优雅 ✨
写代码就像写诗一样,需要遵循一定的韵律和格式。让我们一起让代码变得更加优雅:
- 🔍 ESLint 是你的好朋友:确保代码可以通过仓库的 ESLint 校验,就像诗歌需要押韵一样,代码也需要符合规范。
- 🎨 Prettier 让代码更美丽:使用 prettier 进行代码格式化,让你的代码像精心排版的诗集一样整洁美观。
- ⚡ 兼容性是关键:确保没有使用超出兼容性范围的 API(比如
async,await),让你的代码能在各种环境中优雅地运行。
提交 Pull Request - 分享你的代码之花 🌸
参考指南 - 新手园丁的入门宝典 📚
第一次在开源花园里种花吗?别担心,每个园艺大师都有第一次!这里有两本贴心的入门指南:
- 🌱 第一次参与开源 - 新手园丁的第一课
- 🎯 如何优雅地在 GitHub 上贡献代码 - 进阶园艺技巧
Pull Request 规范 - 精心包装你的礼物 🎁
提交 Pull Request 就像给朋友送礼物,需要精心包装才能让人感受到你的用心:
- 🎯 专注而精准:保持你的 PR 足够小巧精致,一个 PR 只解决一个问题或添加一个功能,就像一份礼物只表达一个心意。
- 🛡️ 质量保证很重要:新增或修改组件时,别忘了为它们编写单元测试,就像给礼物加上保护包装一样,确保代码的稳定性。
- 📝 贴心的说明卡片:在 PR 中添加详细的描述,并关联相关的 Issue,让审核者能快速理解你的贡献。
Pull Request 流程 - 你的贡献之旅 🚀
让我们一步步走过这个充满成就感的贡献之旅:
- 🍴 复制一份花园蓝图:fork 主仓库到你的账户下,如果已经 fork 过,记得同步主仓库的最新代码,保持花园蓝图是最新的。
- 🌿 开辟你的专属花圃:基于 fork 后仓库的 main 分支新建一个分支,比如
feature/button_color,这就是你的专属创作空间。 - 🎨 尽情创作:在新分支上进行开发,完成你的杰作后,提交 Pull Request 到主仓库的 main 分支。
- 👥 等待花园管理员的认可:Pull Request 会经过 Review,通过后就会被合并到主仓库,你的作品正式成为花园的一部分!
- 🎉 见证发布的喜悦:等待 Vant 发布新版本(一般每周一次),你的贡献将惠及千万开发者!
Pull Request 标题格式 - 给你的作品起个好名字 📝
一个好的标题就像一首诗的题目,能让人一眼就明白你的作品想要表达什么。Pull Request 的标题应该遵循以下格式:
type(ComponentName?):commit message示例:
- docs: fix typo in quickstart
- build: optimize build speed
- fix(Button): incorrect style
- feat(Button): add color prop
可选的类型:
- fix
- feat
- docs
- perf
- test
- types
- style
- build
- chore
- release
- refactor
- breaking change
- revert:
同步最新代码 - 保持花园蓝图最新 🔄
在提交你的杰作之前,记得先更新一下花园蓝图,确保你的创作是基于最新的设计!请按照下面的步骤同步主仓库的最新代码:
# 添加主仓库到 remote
git remote add upstream git@github.com:vant-ui/vant.git
# 拉取主仓库最新代码
git fetch upstream
# 切换至 main 分支
git checkout main
# 合并主仓库代码
git merge upstream/main最佳实践 - 成为优秀园丁的秘诀 🌟
代码贡献技巧
🎯 专注单一功能
// ✅ 好的做法:专注于单一功能
// 为 Button 组件添加 loading 状态
const Button = ({ loading, children, ...props }) => {
return (
<button disabled={loading} {...props}>
{loading ? <Loading /> : children}
</button>
);
};
// ❌ 避免:在一个 PR 中修改多个不相关的功能📝 编写清晰的提交信息
# ✅ 好的提交信息
feat(Button): add loading state support
fix(Dialog): resolve overlay z-index issue
docs: update Button component examples
# ❌ 模糊的提交信息
update button
fix bug
change style测试编写指南
🧪 为新功能编写测试
// 为新功能编写完整的测试用例
describe('Button Loading State', () => {
test('should show loading icon when loading is true', () => {
const { container } = render(<Button loading>Submit</Button>);
expect(container.querySelector('.van-loading')).toBeTruthy();
});
test('should disable button when loading', () => {
const { container } = render(<Button loading>Submit</Button>);
expect(container.querySelector('button')).toBeDisabled();
});
});常见问题解决 🔧
开发环境问题
❓ 本地开发服务启动失败
# 清理依赖并重新安装
rm -rf node_modules package-lock.json
npm install
# 或者使用 pnpm
rm -rf node_modules pnpm-lock.yaml
pnpm install❓ ESLint 检查不通过
# 自动修复可修复的问题
npm run lint:fix
# 手动检查剩余问题
npm run lint❓ 单元测试失败
# 运行特定测试文件
npm test -- Button
# 更新快照测试
npm test -- --updateSnapshotGit 操作问题
❓ 分支同步冲突
# 使用 rebase 保持提交历史整洁
git fetch upstream
git rebase upstream/main
# 解决冲突后继续
git add .
git rebase --continue❓ 提交历史混乱
# 使用 interactive rebase 整理提交
git rebase -i HEAD~3
# 合并多个提交为一个
# 在编辑器中将 pick 改为 squash贡献者成长路径 🚀
新手园丁 🌱
- 从修复文档错误开始
- 提交简单的 bug 修复
- 参与 issue 讨论
进阶园丁 🌿
- 添加新的组件功能
- 优化现有组件性能
- 编写详细的测试用例
资深园丁 🌳
- 设计新的组件架构
- 参与技术方案讨论
- 指导新贡献者
园艺大师 🏆
- 主导重大功能开发
- 制定代码规范
- 维护项目生态
社区互动指南 💬
参与讨论的艺术
🗣️ 在 Issue 中提供帮助
- 复现并确认问题
- 提供解决方案建议
- 分享相关经验
💡 提出建设性建议
- 详细描述使用场景
- 提供设计方案
- 考虑向后兼容性
🤝 协作开发
- 及时响应 Review 意见
- 主动寻求帮助
- 分享开发心得
设计灵感 🎨
组件设计原则
🎯 用户体验优先
- 直观的 API 设计
- 一致的交互体验
- 完善的错误处理
🔧 开发者友好
- 清晰的文档说明
- 丰富的使用示例
- 灵活的定制选项
📱 移动端优化
- 触摸友好的交互
- 响应式设计
- 性能优化
创新功能建议
🌈 主题系统增强
- 动态主题切换
- 自定义主题生成器
- 主题预览功能
♿ 无障碍支持
- 键盘导航优化
- 屏幕阅读器支持
- 高对比度模式
🚀 性能优化
- 按需加载优化
- 虚拟滚动支持
- 内存使用优化
延伸阅读 📚
技术文档
- Vue.js 官方文档 - 深入了解 Vue.js 框架
- TypeScript 指南 - 掌握 TypeScript 开发
- Jest 测试框架 - 学习单元测试编写
开源贡献
- 开源指南 - 开源项目参与指南
- GitHub 协作流程 - 掌握 GitHub 协作技巧
- 代码审查最佳实践 - 提升代码质量
设计资源
- Material Design - 现代化设计语言
- Human Interface Guidelines - iOS 设计规范
- Ant Design - 企业级设计语言
🎉 感谢你的贡献! 每一个 PR、每一个 Issue、每一次讨论都让 Vant 变得更好。让我们一起打造最优秀的移动端组件库!