一个基于 Next.js + TypeScript 构建的生产级 GitHub 技术栈画像分析工具。
区别于市面上盲目累加代码量的统计工具,内置智能交集过滤算法,真实还原开发者的核心技术栈。
🌐 Live Demo · 📖 API 文档 · 🛠️ 部署指南
项目的核心优势——保守交集策略,完美剔除开源大项目带来的"数据杂音":
- 自有仓库:全量信任,精准累加所有语言字节数
- 贡献仓库:采用保守交集策略,仅在开发者自有项目已拥有的语言上累加贡献量
- 例如:你偶然改动某个大型开源项目的一行配置引入了整个 Shell/NPM 环境,不会被计入统计
- 效果:得到的是核心技术栈,而非"历史垃圾"的集合
✓ GraphQL 变量参数化协议 (杜绝注入)
✓ 严格的 GitHub 账号规范正则验证
✓ 完整的 CORS 预检支持
✓ 类型安全的 TypeScript 接口
✓ 指数退避重试机制 (1s → 2s → 4s)
✓ 智能 Retry-After 头解析
✓ 15 秒硬超时熔断
✓ 标准 OPTIONS 预检请求支持
✓ 响应式 Conic Gradient 饼图
✓ 语言颜色方案同 GitHub 官方
✓ 支持 Iframe 跨域嵌入
✓ 实时冷却计数器防止 API 滥用
| 工具 | 版本 | 说明 |
|---|---|---|
| Next.js | 16.2.6 | App Router + Route Handlers |
| React | 19.2.4 | 最新 React Hooks |
| TypeScript | 5 | 完整类型覆盖 |
| Tailwind CSS | 4 | 原子化样式 |
| GraphQL | - | GitHub API v4 |
- Node.js 18+
- npm / pnpm / yarn / bun
- GitHub 个人访问令牌 (PAT)
git clone https://github.com/Linvin-1233/GitHub-Analyzer.git
cd GitHub-Analyzer前往 GitHub 设置 → Developer settings → Personal access tokens
权限需求(最小化原则):
- ✓
public_repo— 读取公开仓库信息 - ✗ 无需写入权限
复制 Token,保存到本地。
在项目根目录创建 .env.local 文件:
# .env.local
GITHUB_TOKEN=ghp_your_actual_github_token_here
NEXT_PUBLIC_APP_URL=http://localhost:3000生产环境提示:在 Vercel / 服务器部署时,需在对应平台的环境变量配置中设置上述两个变量。
npm install
npm run dev访问 http://localhost:3000,看到熟悉的 GitHub Stats 界面即成功!
GET /api/github-stats?username=octocat HTTP/1.1
Host: your-domain.vercel.app
Content-Type: application/json| 参数 | 类型 | 必填 | 描述 | 示例 |
|---|---|---|---|---|
username |
string | ✓ | GitHub 用户名(1-39 位,英文字母、数字、连字符) | octocat |
{
"my_username": "octocat",
"scope": "GitHub-Analyzer-V1.12",
"summary": {
"total_repositories_analyzed": 12,
"total_code_bytes": 1458920
},
"languages_percentage": {
"TypeScript": "65.4%",
"JavaScript": "20.1%",
"CSS": "14.5%"
},
"languages_by_bytes": {
"TypeScript": 954134,
"JavaScript": 293243,
"CSS": 211543
},
"repositories": [
"octocat/hello-world",
"octocat/spoon-knife"
]
}响应头示例:
Cache-Control: public, max-age=600
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Content-Type: application/json
| 状态码 | 错误信息 | 原因 |
|---|---|---|
| 400 | Invalid username |
用户名为空或格式非法 |
| 404 | User not found |
GitHub 中不存在该用户 |
| 500 | Missing GITHUB_TOKEN |
服务端未配置环境变量 |
| 502/503 | GitHub API error |
GitHub 服务暂时不可用(会自动重试) |
## 📊 我的技术栈
<iframe src="https://github-analyzer-six-theta.vercel.app/?username=YOUR_USERNAME&embed=true"
width="100%" height="520" frameborder="0">
</iframe>const username = 'octocat';
const response = await fetch(`/api/github-stats?username=${username}`);
const data = await response.json();
console.log(`${username} 的核心语言:${Object.keys(data.languages_percentage)[0]}`);
console.log(`统计的仓库数:${data.summary.total_repositories_analyzed}`);<!-- 从任意网站都可以调用 -->
<script>
fetch('https://github-analyzer-six-theta.vercel.app/api/github-stats?username=octocat')
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
</script>GitHub-Analyzer/
├── app/
│ ├── api/
│ │ ├── github-stats/
│ │ │ └── route.ts # 核心 API 路由
│ │ └── embed/
│ │ └── route.ts # Iframe 嵌入支持
│ ├── components/
│ │ └── GitHubStatsViewer.tsx # 前端可视化组件
│ ├── globals.css # 全局样式 (Tailwind)
│ ├── layout.tsx # 根布局
│ └── page.tsx # 首页
├── public/
│ └── data/
│ └── colors.json # GitHub 语言颜色方案
├── package.json # 依赖配置
├── tsconfig.json # TypeScript 配置
├── tailwind.config.js # Tailwind 配置
├── next.config.js # Next.js 配置
├── .env.local # 本地环境变量 (Git 忽略)
└── README.md # 本文件
// 自有仓库:100% 累加
if (isOwned) {
repoSet.add(repo.nameWithOwner);
for (const edge of repo.languages.edges) {
const lang = edge.node.name;
languageStats[lang] = (languageStats[lang] || 0) + edge.size;
}
continue;
}
// 贡献仓库:保守交集策略
if (isContributed) {
repoSet.add(repo.nameWithOwner);
for (const edge of repo.languages.edges) {
const lang = edge.node.name;
if (!languageStats[lang]) continue; // 只计算已有的语言
languageStats[lang] += edge.size;
}
}// Conic Gradient 饼图
<div
className="w-56 h-56 rounded-full shadow-lg transition-transform hover:scale-105"
style={{ background: `conic-gradient(${gradientParts.join(', ')})` }}
/>
// 语言颜色方案同 GitHub 官方
const color = githubColors[lang]?.color || '#8b5cf6';- Fork 本仓库 到你的 GitHub 账号
- 访问 vercel.com → 选择该 Fork 仓库
- 在 Environment Variables 中添加:
GITHUB_TOKEN = ghp_xxx...
- 点击 Deploy → 1-2 分钟后自动上线!
优势:
- ✓ 自动 CI/CD(Git Push 自动部署)
- ✓ 全球 CDN 加速
- ✓ 无需管理服务器
- ✓ 免费额度充足
# 构建生产版本
npm run build
# 启动服务器
npm start
# 或使用 PM2 后台运行
npm install -g pm2
pm2 start npm --name "github-analyzer" -- start
pm2 save
pm2 startup需要在 Nginx / Apache 中配置反向代理。
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
ENV GITHUB_TOKEN=${GITHUB_TOKEN}
ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}
EXPOSE 3000
CMD ["npm", "start"]# 构建镜像
docker build -t github-analyzer .
# 运行容器
docker run -e GITHUB_TOKEN=ghp_xxx \
-e NEXT_PUBLIC_APP_URL=https://your-domain \
-p 3000:3000 \
github-analyzer- 已认证请求:5000 requests/hour
- 重试机制:自动 3 次指数退避重试
- 超时设置:单次请求 15 秒硬超时
浏览器缓存 (Cache-Control)
↓
600秒 (10分钟) 边缘缓存
↓
Vercel Edge Network (全球 CDN)
这意味着同一用户的查询在 10 分钟内只会真实请求 GitHub API 一次,其余都是秒级响应!
服务端运行时的关键日志(console.log):
[GitHub-Stats] Cache MISS. Initiating fresh analysis...
[GitHub-Stats] Retry attempt 1 for octocat...
[GitHub-Stats] Retry attempt 2 for octocat... (网络抖动中)
[GitHub-Stats] Cache HIT for octocat (毫秒级响应)
[GitHub-Stats] Request DEDUPLICATED for octocat (高并发时)
👉 GitHub Settings → Developer settings → Personal access tokens
权限只需勾选 public_repo。
可能的原因:
- 用户没有公开仓库
- GitHub API 触发频率限制(每小时 5000 请求)
- Token 权限不足
- 用户名包含特殊字符(仅支持英文字母、数字、连字符)
这是设计中的保守交集策略。如果你想包含所有贡献的语言,可以修改 app/api/github-stats/route.ts 中的这行:
// 修改前:仅计算已有语言
if (!languageStats[lang]) continue;
// 修改后:计算所有语言
// if (!languageStats[lang]) languageStats[lang] = 0;在 app/api/github-stats/route.ts 中找到:
"Cache-Control": "public, max-age=600", // 600 = 10 分钟改为 max-age=3600 (1 小时) 或其他值。
硬超时为 15 秒。在 app/api/github-stats/route.ts 中:
const timeoutId = setTimeout(() => controller.abort(), 15000); // 毫秒可以。项目是标准的 Node.js Next.js 应用,支持任何支持 Node.js 的平台:
- Heroku / Railway / Render(PaaS)
- AWS / GCP / Azure(IaaS)
- 你自己的 VPS
欢迎提交 Issue 和 PR!
- 支持更多数据维度(如按时间范围统计)
- 国际化多语言
- 单元测试覆盖
提交 PR 时,请:
- Fork 本仓库
- 从
main新建 feature 分支 - 提交清晰的 commit 消息
- 确保代码通过 TypeScript 检查
- 在 PR 中说明改动原因
本项目基于 MIT License 开源,详见 LICENSE 文件。
- 📖 GitHub GraphQL API Documentation
- 🚀 Next.js Route Handlers
- 🎨 Tailwind CSS
- 📘 TypeScript Handbook
- 🔐 GitHub Security Best Practices
感谢所有使用、Star 和贡献的开发者!
Made with ❤️ by Linvin-1233
⭐ Star 这个项目 · 🐛 报告问题 · 💬 讨论想法