跳转至

贡献指南

欢迎阅读贡献指南!本文档介绍如何为 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 规范:

---
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
  • 加入社区讨论
  • 开始贡献!

相关主题


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