Skip to content

贡献指南

欢迎阅读贡献指南!本文档介绍如何为 Hugo 网站项目做贡献,包括编码规范、开发流程和最佳实践。

入门指南

前置条件

在贡献之前,请确保你已完成:

首次贡献者

  1. Fork 仓库到你的 GitHub 账号
  2. 克隆你的 fork 到本地:
git clone https://github.com/your-username/website.git
cd website
  1. 添加上游远程仓库
git remote add upstream https://github.com/rootsongjc/website.git
  1. 安装依赖
npm install
  1. 验证环境
make check-deps
npm run test:fast

开发流程

1. 基于 Issue 的开发

开始工作前:

  1. 在 GitHub 上查看已有 Issue
  2. 创建或评论 Issue,讨论你的修改建议
  3. 等待维护者反馈后再开始重要工作

Issue 类型:

  • 🐛 Bug 报告:现有功能的问题
  • 功能需求:新功能或增强
  • 📚 文档:文档改进
  • 🎨 设计:UI/UX 改进
  • 🔧 维护:代码清理、重构、依赖更新

2. 分支策略

分支命名规范:

# 功能分支
feature/add-new-shortcode
feature/improve-search-performance

# Bug 修复分支
fix/broken-image-links
fix/mobile-navigation-issue

# 文档分支
docs/update-contributing-guide
docs/add-api-reference

# 维护分支
chore/update-dependencies
chore/improve-build-performance

创建分支:

# 更新主分支
git checkout main
git pull upstream main

# 创建功能分支
git checkout -b feature/your-feature-name

# 推送分支到你的 fork
git push -u origin feature/your-feature-name

3. 开发过程

日常开发:

# 启动开发服务器
make server

# 修改代码
# ... 编辑文件 ...

# 测试你的修改
npm run test:fast

# 提交修改(见下方提交规范)
git add .
git commit -m "feat: 新增代码块短代码"

# 推送修改
git push origin feature/your-feature-name

提交前检查:

# 更新上游代码
git fetch upstream
git rebase upstream/main

# 运行完整测试
npm test

# 构建生产版本
npm run build

# 检查问题
make check-deps

编码规范

1. HTML/模板规范

Hugo 模板:

<!-- 使用语义化 HTML -->
<article class="blog-post">
  <header class="post-header">
    <h1 class="post-title">{{ .Title }}</h1>
    <time datetime="{{ .Date.Format "2006-01-02" }}" class="post-date">
      {{ .Date.Format "January 2, 2006" }}
    </time>
  </header>

  <div class="post-content">
    {{ .Content }}
  </div>
</article>

<!-- 使用 2 空格缩进 -->
{{ if .Params.featured }}
  <div class="featured-badge">
    <span>Featured</span>
  </div>
{{ end }}

<!-- 注释复杂逻辑 -->
{{/* 生成多格式响应式图片 */}}
{{ $image := resources.Get .Params.image }}
{{ $webp := $image.Resize "800x webp" }}
{{ $fallback := $image.Resize "800x" }}

无障碍要求:

<!-- 必须包含 alt 文本 -->
<img src="{{ $image.RelPermalink }}" alt="{{ .Title }}" loading="lazy">

<!-- 正确的标题层级 -->
<h1>主标题</h1>
<h2>章节标题</h2>
<h3>小节标题</h3>

<!-- 需要时添加 ARIA 标签 -->
<button aria-label="切换导航菜单" class="nav-toggle">
  <span class="hamburger"></span>
</button>

<!-- 使用语义化标记 -->
<nav aria-label="主导航">
  <ul>
    <li><a href="/">首页</a></li>
    <li><a href="/blog/">博客</a></li>
  </ul>
</nav>

2. CSS/SCSS 规范

文件组织:

// assets/scss/style.scss
@import 'variables';
@import 'mixins';
@import 'base';
@import 'components/index';
@import 'layouts/index';
@import 'templates/index';
@import 'custom';

命名规范(BEM):

// 块
.card {
  display: flex;
  flex-direction: column;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

// 元素
.card__header {
  padding: 1rem;
  border-bottom: 1px solid #eee;
}

.card__title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
}

.card__content {
  padding: 1rem;
  flex: 1;
}

// 修饰符
.card--featured {
  border: 2px solid #007bff;
  box-shadow: 0 4px 16px rgba(0, 123, 255, 0.2);
}

.card--large {
  .card__title {
    font-size: 1.5rem;
  }
}

响应式设计:

// 移动优先
.component {
  padding: 1rem;

  // 平板
  @media (min-width: 768px) {
    padding: 1.5rem;
  }

  // 桌面
  @media (min-width: 1024px) {
    padding: 2rem;
  }

  // 大屏桌面
  @media (min-width: 1200px) {
    padding: 2.5rem;
  }
}

// 使用 CSS 变量实现主题
:root {
  --primary-color: #007bff;
  --secondary-color: #6c757d;
  --success-color: #28a745;
  --warning-color: #ffc107;
  --danger-color: #dc3545;
}

[data-theme="dark"] {
  --primary-color: #0d6efd;
  --secondary-color: #6c757d;
}

3. JavaScript 规范

ES6+ 特性:

// 使用 const/let 替代 var
const API_URL = 'https://api.example.com';
let currentPage = 1;

// 使用箭头函数
const fetchData = async (url) => {
  try {
    const response = await fetch(url);
    return await response.json();
  } catch (error) {
    console.error('获取数据失败:', error);
    throw error;
  }
};

// 使用解构赋值
const { title, content, author } = post;
const [first, ...rest] = items;

// 使用模板字符串
const message = `你好 ${name},你有 ${count} 条新消息`;

// 使用模块
export class SearchManager {
  constructor(options = {}) {
    this.options = { threshold: 0.3, ...options };
    this.index = null;
  }

  async initialize() {
    const data = await this.loadSearchData();
    this.index = new Fuse(data, this.options);
  }

  search(query) {
    return this.index ? this.index.search(query) : [];
  }
}

错误处理:

// 正确的错误处理
const loadContent = async (url) => {
  try {
    const response = await fetch(url);

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    return await response.json();
  } catch (error) {
    // 调试日志
    console.error('内容加载失败:', error);

    // 用户友好提示
    showNotification('内容加载失败,请重试。', 'error');

    // 返回兜底数据
    return { error: true, message: error.message };
  }
};

// 优雅降级
const initializeFeature = () => {
  if (!('IntersectionObserver' in window)) {
    console.warn('不支持 IntersectionObserver,使用滚动事件降级');
    return initializeFallback();
  }

  return initializeModernFeature();
};

4. 内容规范

Markdown 格式:

# 主标题 (H1) - 每页仅一个

简要介绍段落。

## 主要章节 (H2)

内容需有适当段落间距。

### 小节 (H3)

更详细内容。

#### 子小节 (H4) - 谨慎使用

非常具体的细节。

## 代码示例

使用正确的语法高亮:

# Shell 命令
npm install
hugo server
// JavaScript 代码
const example = () => {
  console.log('Hello, world!');
};

Mermaid 图表

使用 Mermaid 语法创建图表:

graph TD
    A[开始] --> B{决策}
    B -->|是| C[执行]
    B -->|否| D[结束]

图表会自动处理并转换为 SVG 格式。

注意:未来可能会在 CI 中自动检查 Mermaid 图表编译情况。

列表

  • 使用短横线表示无序列表
  • 保持条目结构一致
  • 嵌套项需正确缩进
  • 子项 1
  • 子项 2

  • 有序列表用数字

  • 保证逻辑顺序
  • 保持格式一致

链接与引用

  • 使用描述性链接文本
  • 避免“点击这里”或“查看更多”
  • 图片需包含 alt 文本:![描述](image.webp)
**Front Matter 规范:**
```yaml
---
title: "描述性标题(50-60 字)"
description: "SEO 友好描述(150-160 字)"
date: 2025-01-16T10:00:00+08:00
categories:
- "主分类"
tags:
- "相关标签"
- "其他标签"
image: "featured-image.webp"
draft: false
weight: 10  # 排序用(可选)
toc: true   # 显示目录(可选)
---

测试规范

1. 自动化测试

测试类别:

# 完整测试
npm test

# 快速测试(开发用)
npm run test:fast

# 指定测试类型
npm run test:content      # 内容校验
npm run test:links        # 链接检查
npm run test:performance  # 性能测试
npm run test:accessibility # 无障碍测试

编写测试:

// test/content.test.js
import { describe, it, expect } from 'node:test';
import { validateFrontMatter, checkImageDimensions } from '../scripts/test-utils.js';

describe('内容校验', () => {
  it('Front Matter 应有效', async () => {
    const files = await glob('content/**/*.md');

    for (const file of files) {
      const result = await validateFrontMatter(file);
      expect(result.valid).toBe(true);
    }
  });

  it('图片需有尺寸信息', async () => {
    const result = await checkImageDimensions();
    expect(result.missingDimensions).toBe(0);
  });
});

2. 手动测试

提交前检查清单:

  • 功能:特性正常工作
  • 响应式:适配移动、平板、桌面
  • 兼容性:Chrome、Firefox、Safari 测试
  • 无障碍:键盘导航、屏幕阅读器友好
  • 性能:无明显性能回退
  • SEO:正确的 meta 标签和结构化数据
  • 内容:拼写、语法、格式正确

测试命令:

# 测试不同屏幕尺寸
hugo server --bind 0.0.0.0

# 测试生产构建
npm run build
python -m http.server 8000 -d public

# 无障碍测试
npm run test:a11y

# 性能测试
npm run test:performance

Pull Request 流程

1. PR 准备

创建 PR 前:

# 保证分支最新
git fetch upstream
git rebase upstream/main

# 运行完整测试
npm test

# 构建生产版本
npm run build

# 检查问题
git status
git diff --check

2. PR 模板

标题格式:

type(scope): 简要描述

示例:
feat(shortcodes): 新增代码块短代码
fix(search): 修复移动端搜索遮罩问题
docs(contributing): 更新贡献规范
chore(deps): 更新 Hugo 到 v0.147.8

PR 描述模板:

## 描述
简要说明修改内容和动机。

## 变更类型
- [ ] Bug 修复(非破坏性)
- [ ] 新功能(非破坏性)
- [ ] 破坏性变更
- [ ] 文档更新
- [ ] 性能优化
- [ ] 代码重构

## 测试
- [ ] 本地测试通过
- [ ] 新功能已添加测试
- [ ] 多浏览器测试
- [ ] 移动设备测试
- [ ] 无障碍测试

## 截图(如适用)
UI 变更前后截图。

## 检查清单
- [ ] 代码符合项目规范
- [ ] 自查完成
- [ ] 必要处有注释
- [ ] 文档已更新
- [ ] 无破坏性变更(或已说明)

3. 评审流程

评审关注点:

  1. 代码质量
  2. 遵循编码规范
  3. 正确错误处理
  4. 性能优化
  5. 安全最佳实践

  6. 功能

  7. 功能符合描述
  8. 边界情况处理
  9. 无回归问题

  10. 测试

  11. 测试覆盖充分
  12. 测试有意义
  13. 手动测试完成

  14. 文档

  15. 代码有注释
  16. 文档已更新
  17. 有示例

处理评审反馈:

# 按要求修改
# ... 编辑文件 ...

# 提交修改
git add .
git commit -m "address review feedback: improve error handling"

# 推送更新
git push origin feature/your-feature-name

发布流程

1. 版本管理

语义化版本号:

  • 主版本 (1.0.0):破坏性变更
  • 次版本 (0.1.0):新功能,兼容旧版
  • 补丁 (0.0.1):Bug 修复,兼容旧版

2. 发布流程

维护者操作:

# 创建发布分支
git checkout -b release/v1.2.0

# 更新版本号
# 更新 CHANGELOG.md
# 更新文档

# 测试发布
npm run build
npm test

# 创建发布 PR
# 审核通过后合并到主分支

# 打标签
git tag -a v1.2.0 -m "Release v1.2.0"
git push upstream v1.2.0

# 部署生产环境
# 更新 GitHub 发布说明

社区规范

1. 行为准则

我们的标准:

  • 尊重包容
  • 欢迎新成员并帮助他们成长
  • 注重建设性反馈
  • 尊重不同观点和经验
  • 对社区成员保持同理心

不可接受行为:

  • 骚扰或歧视性语言
  • 人身攻击或恶意挑衅
  • 发布私人信息
  • 垃圾信息或无关讨论

2. 沟通方式

首选渠道:

  • GitHub Issues:Bug 报告、功能需求
  • GitHub Discussions:一般问题、想法交流
  • Pull Requests:代码评审、技术讨论
  • Email:私密或敏感事项

沟通规范:

  • 表达清晰简明
  • 提供上下文和示例
  • 代码需正确格式化
  • 创建新 Issue 前先搜索
  • 需要时 @ 相关维护者

获取帮助

1. 文档资源

2. 支持渠道

贡献者:

  • Bug 或新功能请创建 GitHub Issue
  • 问题交流用 GitHub Discussions
  • 优先查阅现有文档
  • 提供最小可复现示例

维护者:

  • 及时评审 PR
  • 建设性反馈
  • 帮助新成员入门
  • 保持文档更新

贡献者认可

1. 贡献者名单

所有贡献者会在:

  • GitHub 贡献者列表
  • 文档贡献者名单
  • 发布说明致谢
  • 年度贡献者亮点

2. 成为维护者

晋升路径:

  1. 持续高质量贡献
  2. 帮助其他贡献者
  3. 展现项目理解
  4. 认同项目目标
  5. 由现有维护者邀请

维护者职责:

  • 评审 Pull Request
  • Issue 分类处理
  • 保持代码质量
  • 指导项目方向
  • 带新贡献者成长

下一步

阅读本指南后:

  • 搭建开发环境
  • 找一个适合的首个 Issue
  • 加入社区讨论
  • 开始贡献!

相关主题


感谢你为项目做出的贡献!你的努力让网站变得更好。