ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PhotoPrism 的 JS/Go 代码注释规范:从 `// Name does X.` 到硬性行数上限的工程实践

PhotoPrism 的 JS/Go 代码注释规范:从 `// Name does X.` 到硬性行数上限的工程实践 后端前端图像处理人工智能AI 应用【免费下载链接】photoprismAI-Powered Photos App ✨项目地址https://gitcode.com/gh_mirrors/ph/photoprism点击查看免费下载PhotoPrism 是一个同时维护着 Go 后端internal/、pkg/与 Vue 前端frontend/src/的大型开源照片应用跨语言协作下注释风格极易漂移。本指南以仓库中的 .claude/rules/code-comments.md 为骨架结合真实源码示例系统讲解 PhotoPrism 的文档注释书写规则何时必须写注释、一行注释的精确格式、follow-up 行的触发条件与硬性上限以及哪些内容严禁进入源码注释。读完本文你可以在 Go 函数、Vue 方法、包与导出标识符三个层面写出与仓库现有代码完全同构的注释。一、规范要解决的核心问题PhotoPrism 的代码库横跨两种语言文化Go 侧有pkg/clean、internal/api等大量纯函数与 HTTP 处理器前端侧有frontend/src/model的模型类与frontend/src/component的上百个 Vue 组件。若不加以约束注释会呈现两种极端要么缺失、要么退化为一段记录当时发生了什么的历史叙事。这份规则文档给出了明确立场注释默认只回答 what仅在必要时回答 why。它同时设定了三条可测量的标准——每个函数都要有注释、follow-up 行数目标 1-2 行、硬性上限 3 行含首行共 4 行——使得注释质量可以被评审和 lint 客观检查而不是靠个人审美。二、注释覆盖范围每个函数都必须有规则的第一句话是硬性要求A doc comment isrequiredfor every function (including unexported helpers), as well as for every non-trivial Vuemethods:/computed:/ watcher.即每个函数都必须有文档注释包括未导出的 helper 函数每个非平凡的 Vuemethods:/computed:/ watcher 也必须有。这意味着注释不是可选项而是与函数签名绑定的交付物。仓库中的实际执行情况随处可见。例如 pkg/clean/altitude.go// Altitude returns the altitude within a maximum range as an integer, or 0 if it is invalid.即使是最短小的工具函数也遵循这一要求见 pkg/clean/ascii.go// ASCII removes all non-ASCII bytes from a string. // Fast path: return the original string when it already contains only ASCII. func ASCII(s string) string {前端 JavaScript 同样执行该规则例如 frontend/src/model/logs.js// severityName returns the severity label (e.g., info) or info when unknown.以及 frontend/src/model/file.js// isAnimated returns true when the file is an image with multiple frames or a non-trivial duration.三、单行注释的精确格式// Name does X.规则对一行注释给出了字面级别的格式约定Keep commentscompactand default to one line for what in the format// Name does X..即默认用一行描述 what格式固定为// 名字 做了什么.。三个要点以标识符的名字开头Go 惯例是函数名JS 中同样以方法/属性名开头而不是以 This function 或 Returns 开头以句号结尾是一个完整的句子跳过琐碎的 getter规则原文给出的例子是isOpen: () this.open——这类一行就能看懂、且名字自解释的取值函数不写注释反而更好。对照仓库实际// GetAlbum returns album details as JSON.internal/api/albums.go与// Auth returns the sanitized authentication identifier trimmed to a maximum length of 255 characters.pkg/clean/auth.go都是标准形态。注意Auth一行虽然句子较长但仍是一行、单句、以名字开头、以句号收尾——紧凑指的是结构紧凑而非内容贫瘠。四、何时加 follow-up 行回答 why 的三个判据单行注释无法覆盖所有场景。规则给出了必须追加 1-2 行 follow-up格式// …的三个判据满足其一才写Add 1-2 follow-up lines (// …)onlyif the why is non-obvious: a hidden invariant, a workaround that would otherwise be undone by a future cleanup, a contract a reader cant infer from the code. If readers can infer the why from the function body or a nearby line, then omit it.三种典型场景隐藏不变量hidden invariant函数依赖一个代码里看不出的约束。例如 frontend/src/model/model-cache.js// has returns true if the key has a live (non-expired) entry; expired entries // are pruned before reporting absence. Probe only — does not promote LRU order.第二行 Probe only — does not promote LRU order 就是读者无法从函数体推断的契约调用has不能当作访问因为它不改变 LRU 顺序。会被未来清理破坏的 workaround例如 frontend/src/component/auth/menu.vue// openOnHover reactively reflects the users menu open-on-hover preference so a settings // change applies without a page reload (persistent menus keep no mount-time snapshot).若没有第二行说明未来的重构很可能把这块逻辑优化成挂载时快照从而破坏实时生效的行为。读者无法从代码推断的契约例如 pkg/clean/auth.go 的Handle// Handle returns the sanitized username with trimmed whitespace and in lowercase. It folds the // characters that render as a space and removes those that render as nothing, so a handle cannot // carry a character a reader will not see. A handle that would start with a dot is empty.这里共 3 行1 行 what 2 行 why恰好落在目标区间解释折叠空白字符、去掉不可见字符的动机是函数体无法自明、但读者理解行为所必需的信息。反向判据同样重要如果 why 能从函数体或邻近代码推断出来就必须省略follow-up 行。注释不是课堂讲义重复函数体内可见的逻辑只会增加噪声。五、行数硬性上限3 行 follow-up共 4 行规则用非常强硬的措辞规定了上限1-2 follow-up lines is the target to aim for when writing a new comment.3 follow-up lines (4 in total) is the hard limit, and it applies to every comment you touch — compact an existing one that exceeds it rather than preserving its length.三点执行细则写新注释时以 1-2 行 follow-up 为目标硬性上限是 3 行 follow-up即整条注释最多 4 行任何超过的注释都不允许存在上限适用于你接触到的每一条注释——即使是别人写的、即使超出了也应压缩到合规范围内而不是保留原样。这条规则把历史存量注释也纳入了维护范围防止规范只对新代码生效。作为参考pkg/clean/auth.go 的Handle是 3 行含首行frontend/src/model/model-cache.js 的get是 2 行// get returns a freshly hydrated model for the key (or null on miss/expiry), // promoting the entry to the most-recent LRU slot.这些都是合规形态一旦某条注释需要第四行 follow-up规则强制你回退一步把解释挪到函数体、拆分函数或者移入外部文档。六、多段解释的去处源码之外规则明确划定了边界Multi-paragraph explanations belong inspecs/, packageREADME.mdfiles, or GitHub issues — never in the source itself.超过 4 行、需要多段落的解释应该去三个地方specs/目录、包级README.md、或 GitHub issue。源码注释只承载稳态行为的速览深度背景一律外置。这与 PhotoPrism 仓库的结构一致frontend/AGENTS.md、各目录的README.md如 internal/api/README.md、internal/AGENTS.md承担了跨文件、跨模块的说明职责源码注释则保持短小。七、包与导出标识符完整句子 名字开头 句号结尾对于包级注释和导出标识符规则要求更高的语言完整性Doc comments for packages and exported identifiers must be complete sentences that begin with the name of the thing being described and end with a period. For short examples in comments, indent code instead of using backticks.必须是被描述对象的名字开头包注释应为// Package xxx ...导出函数注释以函数名开头必须以句号结尾形成完整句子短示例用缩进代码而非反引号注释内嵌的简短代码片段应缩进排版不要使用 Markdown 反引号。仓库中导出变量的注释即为此形态见 pkg/clean/auth.go// EmailRegexp validates RFC 5322-like email addresses used by the app. // DomainRegexp validates hostnames for authentication inputs.八、一律使用美式英语拼写Use US English spelling in all code comments (parameterized,behavior,color,serialize,normalize,optimize, …) — not the British-ised/-our/-revariants.所有代码注释必须使用美式拼写parameterized而非 parameterised、behavior而非 behaviour、color而非 colour、serialize/normalize/optimize而非 -ise 变体。这条规则对 PhotoPrism 这种多语言贡献者的开源项目尤其重要——母语为英式英语的贡献者很容易在注释中无意识地引入-ised后缀因此把它单列为一条强制规则也便于在 code review 中机械检查。仓库现有注释如sanitized、normalized、lowercase均遵循此约定。九、注释中绝对不要出现的内容规则用一段加粗引用给出了排除清单Dont include in code comments:Issue / PR numbers, previously… history, alternatives considered, what the function used to do, references to old commits, names of subsequent reviewers, or any narrative that names the change rather than the steady-state behavior. That context belongs in commit messages, specs, or handover notes.具体禁止项禁止内容原因正确去处Issue / PR 编号与稳态行为无关且会随 issue 关闭而过时commit messagepreviously… 式的历史叙述注释应描述现在而非演变过程commit message、specs曾经考虑过的备选方案属于决策记录不属于源码specs函数以前的行为what it used to do误导读者以为代码仍如此工作commit message旧 commit 的引用无法从代码层面验证其相关性commit message后续评审者的名字与行为无关的人名噪声交接笔记handover notes任何命名这次变更而非描述稳态行为的叙述注释是给读者看行为契约的不是变更日志commit message判断标准注释只允许描述steady-state behavior稳态行为——代码此刻做什么、以及读者无法推断的约束。凡是描述这次改动的叙事一律属于 commit message、specs 或交接笔记。这与前文回答 why 而非记录历史的精神完全一致即便要写 follow-up 行写的也是隐藏不变量和契约而不是变更历程。十、落地实践如何在 PhotoPrism 中写出合规注释综合全部规则一条合规注释的决策流程如下先判断是否该写函数/方法/非平凡 watcher 必写琐碎 getter如isOpen: () this.open跳过写一行 what// Name does X.以名字开头、句号结尾、美式拼写检查 why 是否自明能从函数体或邻近代码推断则止步不能推断隐藏不变量、易被清理的 workaround、隐性契约才追加 1-2 行数行数超过 3 行 follow-up共 4 行必须压缩压缩不了就把解释挪到specs/、包README.md或 issue对照排除清单确认没有 issue 编号、历史叙事、备选方案、旧行为描述、评审者名字语言检查确认使用美式拼写短示例用缩进代码而非反引号。以 pkg/clean/ascii.go 为例可以完整看到规范在真实代码中的落点函数注释// ASCII removes all non-ASCII bytes from a string.回答 what一行 follow-up// Fast path: ...解释性能动机隐藏的性能契约函数体内的// Fast path: all bytes 128 → no allocation.与// Slow path: ...则是局部辅助注释同样保持一行、直述事实。整条链路没有历史、没有编号、没有备选方案全部指向稳态行为——这正是这份规范希望每条注释都能达到的状态。十一、小结PhotoPrism 的代码注释规范用五个数字和一个排除清单即可概括每个函数必写注释、默认 1 行// Name does X.、follow-up 目标 1-2 行、硬性上限 3 行共 4 行、多段解释一律外置注释中严禁 issue 编号、历史叙事、备选方案与评审者信息。这套规则在 .claude/rules/code-comments.md 中定义并由 pkg/clean/auth.go、frontend/src/model/model-cache.js 等真实代码持续执行。对贡献者而言遵循它意味着你的注释将天然具备一眼看懂、永不误导的品质对维护者而言它把注释质量变成了可评审、可 lint、可量化的工程约束。赞分享后端前端图像处理人工智能AI 应用【免费下载链接】photoprismAI-Powered Photos App ✨项目地址https://gitcode.com/gh_mirrors/ph/photoprism点击查看免费下载相关推荐Inpaint-web 使用指南浏览器内免费完成图片去水印与超分辨率放大Inpaint web 使用指南浏览器内免费完成图片去水印与超分辨率放大 产品图上有供应商水印去不掉老照片模糊到看不清细节这是大家最常遇到的两个修图难题。图像处理AI 应用前端如何编写清晰的js-cookie代码注释完整规范指南如何编写清晰的js cookie代码注释完整规范指南 在JavaScript开发中良好的代码注释是提升代码可读性和可维护性的关键。对于轻量级浏览器Cooki前端RedditVideoMakerBot代码注释规范提高代码可读性的实践RedditVideoMakerBot代码注释规范提高代码可读性的实践 1. 注释规范的重要性 在开源项目中代码注释是提升团队协作效率和代码可维护性的关键因音视频工作流自动化上一篇BiliTools3步将B站视频变成你的个人知识库AI智能总结让学习效率提升300%下一篇从3天到10分钟OpCore-Simplify如何通过智能算法重构黑苹果配置流程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表