- 开发工具
- 数据可视化
【免费下载链接】star-history
The de facto GitHub star history graph.
本指南以 star-history 仓库为核心,系统讲解这款 "de facto GitHub star history graph" 工具的整体架构:从前端图表交互、实时图表与全局排名徽章的嵌入方式,到本地开发环境搭建、Chrome 扩展构建,再到用于生成可嵌入 README 的 SVG 图表的 API Server 及其参数体系。读完本文,你将掌握如何在本仓库基础上运行首页、构建扩展、部署实验性 API 服务,并理解其底层数据抓取与缓存原理。
项目定位与核心特性
Star History 是一个专门为 GitHub 开源项目绘制 Star 增长趋势图的应用。仓库根目录的 README.md 给出了明确的定位描述——"the de facto GitHub star history graph",即业界事实标准的 GitHub Star 历史图工具。它同时提供在线网站、免费 Chrome 扩展,以及可嵌入任意页面(尤其是 GitHub README)的实时 SVG 图表。
从 README.md 的 Features 一节可以提炼出以下核心能力:
- 独特的手绘风格图表:采用
sketch xkcd手绘涂鸦质感的图表样式。仓库中 frontend/styles/xkcd.ttf 正是支撑这一视觉风格的自定义字体,backend 侧的 backend/assets/xkcd.ttf 则用于服务端 SVG 渲染。 - 一键生成高质量图表图片:前端通过
html-to-image类能力将图表导出为图片(依赖见 frontend/package.json)。 - 多种图表视图模式:支持基于日期(date)与基于时间线(timeline)两种坐标视图。该模式的类型定义位于 shared/types/chart.tsx 的
ChartMode,后端常量 backend/const.ts 也明确列出了CHART_TYPES = ["Date", "Timeline"]。 - 将实时图表嵌入 GitHub README 或其他网站:这是该项目最标志性的功能,后文会结合源码详细展开。
- 多种实用辅助功能:仓库可见性开关、仓库输入快捷方式、快速分享到 Twitter、支持一次输入多个仓库对比等。
首页交互部分由 frontend/pages/index.tsx 组织,通过RepoInputer组件接收用户输入的仓库,StarChartViewer组件负责图表的渲染、数据获取与交互(见 frontend/components/StarChartViewer.tsx)。
实时图表与全局排名徽章:把 Star 趋势图嵌入你的 README
README 的顶部就嵌着两个"活的"示例:一个是实时 Star History 图表,另一个是带全局排名的徽章(badge)。它们都指向 star-history.com 在线服务,本仓库不直接提供托管服务,但完整给出了生成这类 SVG 的后端实现,即下文会讲到的 API Server。
想要在自己的仓库 README 中嵌入同样的实时图表,可以参考仓库内的教程文档 frontend/public/blog/how-to-use-github-star-history.md。该文档详细介绍了如何获取嵌入代码并粘贴进 README 的完整流程,README 中的 live 图表正是这一能力的直接展示。
与嵌入能力配套的还有前端侧的功能支撑组件:GenerateEmbedCodeDialog用于生成嵌入代码,EmbedMarkdownSection用于展示 Markdown 片段,它们都位于 frontend/components/ 目录下,说明"一键生成嵌入代码"在前端是有完整交互实现的,而非单纯的 README 宣传。
本地开发环境搭建
README 的 Development 章节给出了明确的开发指引,并特别说明该项目不接受外部贡献("We do not accept external contribution"),克隆后主要用于本地运行与学习。
技术栈与前置要求
项目基于现代前端技术栈构建:
- Next.js:首页与博客系统基于 frontend/pages/ 目录下的页面组织,从 frontend/package.json 可以看到核心依赖
next@^14.1.0、react@^18.2.0。 - TailwindCSS:样式体系,配置见 frontend/tailwind.config.js 与 frontend/styles/tailwind.css。
- d3 系列:图表绘制底层使用
d3-axis、d3-scale、d3-selection、d3-shape,图表渲染核心实现在 shared/packages/xy-chart.tsx。
前置要求仅有两项:
- Node.js:开发环境需要现代 Node.js 运行时(项目声明
packageManager: pnpm@9.15.4,建议配套较新版本)。 - pnpm:包管理器,整个仓库的依赖锁定文件均为
pnpm-lock.yaml。
运行首页
README 给出的命令非常简洁:
cd frontend && pnpm i && pnpm dev网站将在 http://localhost:3000 提供服务。从 frontend/package.json 的 scripts 可以看到,dev实际执行的是pnpm run generate:blog && next dev:即先用tsx运行 frontend/scripts/generateBlogJson.mts 生成博客 JSON 数据,再启动 Next.js 开发服务器。这意味着首次启动会经历一个博客静态数据的预生成过程,之后才是常规的 Next.js 热更新开发。
完整构建流程
cd frontend && pnpm i && pnpm buildbuild脚本同样会先generate:blog,随后执行next build && next-sitemap。其中next-sitemap用于产出站点地图,配置见 frontend/next-sitemap.config.js。构建完成后可用pnpm start(即pnpm dlx serve out)以静态服务方式对外提供产物。
构建 Chrome 扩展
Star History 同时提供一个免费的 Chrome 扩展,支持基础的图表查看能力。README 给出的构建命令为:
cd frontend && pnpm build:ext构建产物输出到./dist目录,之后在 Chrome 的扩展管理页面(chrome://extensions)开启开发者模式,选择"加载已解压的扩展程序",指向该dist文件夹即可完成安装。
从源码看,扩展的构建链路由 frontend/plugins/scripts/copyExtensionFiles.ts 负责,它会将src/extension/background.js与src/extension/manifest.json拷贝到dist目录——扩展的清单文件(manifest)与后台脚本由此生成。同目录下的 frontend/plugins/scripts/emptyDist.ts 则负责在每次构建前清空dist,确保产物干净。
API Server:生成可嵌入 README 的 SVG 图表
README 将 API Server 明确标注为experimental feature(实验性功能),核心用途是为 GitHub README 生成可嵌入的图表 SVG 图片文件。启动方式:
cd backend && pnpm i && pnpm devAPI Server 将运行在 http://localhost:8080。从 backend/package.json 看,dev脚本为tsx main.ts,实际入口是 backend/main.ts;服务基于Hono(hono@^4.7.4)框架构建,使用@hono/node-server提供 HTTP 服务,并配合jsdom(DOM 模拟)、satori(字体/OG 卡片渲染)、svgo(SVG 优化)、lru-cache(缓存)与winston(日志)。
SVG 图表接口的完整参数体系
结合 backend/main.ts 的路由实现与 backend/const.ts 的常量定义,/svg接口支持以下核心查询参数(README 顶部 live 图表正是这种 URL 的直接应用):
| 参数 | 说明 | 取值与默认行为 |
|---|---|---|
repos | 仓库列表,逗号分隔 | 必填;例如repos=star-history/star-history;每个仓库会被去空格、转小写,并做 301 重定向规范化;单次请求上限为MAX_REPOS_PER_REQUEST = 20 |
type | 图表视图类型 | date或timeline,映射到ChartMode的"Date"/"Timeline";也兼容老式布尔参数date、timeline的存在性判断 |
logscale | 对数刻度 | 只要该参数存在且值不为false即启用对数坐标 |
legend | 图例位置 | top-left(默认)或bottom-right |
theme | 主题 | dark或light(默认) |
transparent | 透明背景 | true时输出透明背景 SVG |
size | 图表尺寸 | 必须属于CHART_SIZES = ["mobile", "laptop", "desktop"]之一,非法值回退为laptop;宽度由 backend/utils.ts 的getChartWidthWithSize计算 |
style | 卡片样式 | 置为landscape1时返回 1200x630 的雷达图 OG 卡片(见 backend/og-card.ts),此时取第一个仓库并返回其排名与属性数据 |
一个典型的请求示例(源码注释中原样给出):
/svg?repos=star-history/star-history&type=timeline&logscale&legend=bottom-right值得注意的设计细节:路由在进入真正渲染前,会先把repos参数规范化(统一小写),并做 301 跳转到规范化后的 URL。源码注释说明这是为了CDN 缓存效率——让 Cloudflare 对同一图表只缓存一份条目,避免因大小写差异产生缓存碎片。
从数据抓取到 SVG 输出的完整链路
/svg的处理流程在 backend/main.ts 中清晰可读,大致分为五步:
- 参数归一化与缓存查询:将
repos、type、size、theme、transparent、legendPosition、useLogScale拼成缓存 key,命中svgCache则直接返回缓存 SVG。 - 仓库数据命中判断:遍历
repos,已缓存的仓库直接使用cache中的starRecords与logoUrl;未命中的仓库进入数据抓取。 - GitHub API 抓取:通过
getRepoData(定义于 shared/common/chart.tsx)抓取 Star 记录,MAX_REQUEST_AMOUNT = 16控制单仓库的请求页数上限。仓库 Logo 会转为 Base64 内联进 SVG。 - JSDOM 模拟 DOM 并渲染:创建
JSDOM实例,构造 SVG 根节点,调用共享的XYChart渲染函数(shared/packages/xy-chart.tsx)绘制图表,数据经convertDataToChartData转换。 - SVG 修正与优化:
fixJsdomSvgCasing修正 JSDOM 输出的大小写问题,随后用svgo的multipass: true做多轮优化,最终连同Cache-Control: public, s-maxage=86400, max-age=86400响应头返回。
多级缓存与健康检查
API Server 的缓存体系在 backend/cache.ts 中实现,基于lru-cache分为三类:
- starData 缓存:仓库的 Star 记录与 Logo(注释估算单仓库约 896 字节内存);
- svgChart 缓存:渲染并优化后的完整 SVG;
- ogCard 缓存:
landscape1卡片。
每个缓存都统计命中/未命中次数,/healthz端点会返回status、commit(取环境变量GIT_COMMIT)以及三类缓存的条目数、内存占用、命中率等统计信息,便于监控与调优。
前端数据获取:GitHub API 分页采样原理
Star History 之所以能高效绘制任意仓库的完整 Star 历史,关键在于 shared/common/api.tsx 中getRepoStarRecords的分页采样算法,前端首页与后端 SVG 服务都复用了这套逻辑:
- 先请求第一页
stargazers(per_page=100,配合Accept: application/vnd.github.v3.star+json头以拿到带starred_at时间戳的数据),从响应的Link头解析总页数pageCount。 - 若总页数小于
maxRequestAmount(前端默认 15,见 shared/common/chart.tsx 的DEFAULT_MAX_REQUEST_AMOUNT,后端为 16),则全量并行拉取每一页。 - 若仓库 Star 数极多、页数超过上限,则等比采样:在
1..pageCount范围内均匀选取maxRequestAmount个页码,并行请求,再根据页码与每页 100 条换算各采样点的实际 Star 位置。 - 最后通过
getRepoStargazersCount获取当前实时 Star 总数,作为时间序列的终点。
这种"抽样 + 实时计数"的组合,使图表在请求量受限的前提下仍能准确还原增长曲线的整体形态。数据获取过程中若遇到 404(仓库不存在)、403(GitHub API 限流)、401(Token 无效)、501(无 Star 历史)等错误,前端 frontend/components/StarChartViewer.tsx 会分别弹出 Token 设置对话框或自动移除无效仓库。此外,前端还支持用户配置个人 GitHub Token 来规避匿名限流,Token 存储相关逻辑可参考 frontend/helpers/storage.tsx 与 frontend/components/TokenSettingDialog.tsx。
仓库结构速览
理解整个项目可以抓住这样一条主线:前端(frontend)负责交互,共享包(shared)负责跨端复用,后端(backend)负责 SVG 生成,gh 目录负责离线 Star 数据。其中:
- frontend/:Next.js 站点、博客、Chrome 扩展构建脚本;
- backend/:Hono API Server,产出可嵌入的 SVG 图表与 OG 卡片;
- shared/:前后端共享的图表类型、API 封装与 xy-chart 渲染核心;
- gh/:GitHub Star 数据的离线抓取与生成工具链(如 gh/star-fetch.ts、gh/star-count.ts);
- assets/:项目宣传图与 Logo 素材。
小结
Star History 是一个将"GitHub Star 历史图"这一单一需求做到极致的开源项目:前端提供流畅的多仓库对比、时间线/日期双视图与手绘风格图表;API Server 则把同一套渲染能力搬到了服务端,以参数化 URL 输出轻量、可缓存的 SVG,让任意 README 都能嵌入实时更新的 Star 趋势图。通过阅读本仓库源码,你可以完整学到 Next.js 站点组织、GitHub API 分页采样、JSDOM 服务端 SVG 渲染、LRU 多级缓存以及 Chrome 扩展构建等一系列可复用的工程实践。
- 开发工具
- 数据可视化
【免费下载链接】star-history
The de facto GitHub star history graph.
相关推荐
为 GitHub README 接入实时 Star History 图表:iframe 与 SVG 两种嵌入方案的完整实战
为 GitHub README 接入实时 Star History 图表:iframe 与 SVG 两种嵌入方案的完整实战 Star History 的实时星标
开发工具数据可视化Codex-X Star History Worker:基于 Cloudflare Worker 的仓库 Star 历史 SVG 图表服务实战指南
Codex X Star History Worker:基于 Cloudflare Worker 的仓库 Star 历史 SVG 图表服务实战指南 本文以仓库中
桌面应用开发者工具AI 应用Rufus 快速指南:5 分钟做好 USB 启动盘,老机器绕过 TPM 也能装 Win11
Rufus 快速指南:5 分钟做好 USB 启动盘,老机器绕过 TPM 也能装 Win11 给新电脑装系统、或想让老机器用上 Win11,第一件要备好的是一张能
桌面应用开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考