コメントの書き方
目的
このリポジトリのコメントは、数ヶ月後、数年後に、あなたが今持っている文脈を一切持たないコントリビューターによって読まれます。このスキルは、その読者が誰であり、各種コメントの目的と、禁止されているパターンを定義します。
適用範囲
このスキルは、TypeScript/JavaScriptソースにおける コントリビューター向け のコメントを規定します。エンドユーザー向けのドキュメントには 適用されません:
packages/astro/src/types/public/config.tsおよびpackages/astro/src/core/errors/errors-data.ts内の@docsタグが付いたJSDocブロックは、外部のdocgenツールによってスクレイピングされ、Astroドキュメントサイトに公開されます。これらについてはpackages/astro/src/core/errors/README.mdに従い、ドキュメントチームのレビューを受けてください。types/public/**が変更されると、CIがリファレンスを再生成します。types/public/**のその他のJSDocは、エディタのインテリセンスを通じてユーザーに表示されます。これはソースを読むコントリビューターではなく、サイトを構築するAstro ユーザー のために書いてください。
以下はすべて、HEADでコントリビューターが読むソースについての内容です。
読者
TypeScriptに習熟しているが、あなたの現在の文脈にアクセスできない Astroコントリビューターのために書いてください:この会話、プルリクエスト、Issue、差分のいずれにもアクセスできません。彼らが見るのはHEADのリポジトリだけです。
これから直接的に2つの帰結が導かれます:
- 変更履歴を決して語らないこと。 「現在は」「以前は」「もはや~しない」「新しいアプローチ」といった言葉は、一つのアプローチしか存在しないHEADでは無意味です。コードがどのように機能するかを述べ、どのようにしてそうなったかを述べてはいけません。(
@deprecated通知は例外です — このコードベースの規約 を参照 — これは読者が必要とする契約の将来を説明するためです。) - レビューアに決して語りかけないこと。 自分の変更が正しいことを主張するコメント(「これはXを適切に処理する」)は、PRの説明に属し、ソースには属しません。コメントは、恒久的に、コードをそのまま正当化するものでなければなりません。
3種類のコメント、3つの異なる役割
| 種類 | 構文 | 役割 | 含む内容 |
|---|---|---|---|
| ファイル / モジュール概要 | ファイル先頭の /** */ | 説明 | モジュールが存在する理由、定義する概念や用語、各部分の関係、設計の根拠 |
| 項目ドキュメント | 宣言の直上の /** */ | リファレンス | 契約:動作、パラメータ、戻り値、スローされるエラー、不変条件。中立的で事実に基づく |
| インラインコメント | 本文内の // | 根拠 | コードが表現できないことのみ:制約、回避策(Issueへのリンク付き)、自明でない結合 |
役割を混同してはいけません。実装の詳細は /** */ 契約に含めず、本文内に // コメントとして記述してください。契約はインラインコメントに散在させるのではなく、宣言に記述してください。
動作のドキュメント化
項目ドキュメントを書く場合、実装の翻訳としてではなく、人間の読者のために契約を書いてください。これはすべての関数にJSDocが必要という意味ではありません。名前、型、構造が単純な動作をそれ自体で伝えるべきです。
- 関数が何を返すか、または何を達成するかを平易な言葉で説明することから始めてください。
- 短めから中程度の長さの文で、一文に一つの主なアイデアを持つようにしてください。
- 呼び出し側が不要な内部のAstro専門用語を避けてください。専門用語が必要な場合は、同じ段落で説明してください。
- 驚くような、呼び出し側から見える注意点を説明してください:フォールバック動作、制限、曖昧な結果、オーバーロードの順序、副作用、そして
undefined、null、空の結果、またはその他の不確定な値を返す条件。 - 呼び出し側がそれらを区別または回復することが期待される場合にスローされるエラーを文書化してください。
- 呼び出し側が動作を理解したりAPIを安全に使用したりするために必要でない限り、実装の詳細を説明しないでください。
シグネチャだけでは明確に示せない関係に動作が依存する場合、例を追加してください。一般的なAstroおよびTypeScriptのケースは以下を含みます:
- どのオーバーロードが選択されるか
- 引数がオプションパラメータや残余パラメータにどのようにマッピングされるか
- 別の場所で実装または再エクスポートされているシンボルを公開するパブリックなAstroエントリポイント
- 曖昧なルート、不完全な設定、または欠落したコンテンツに対するフォールバック動作
- その型からは意味が自明でない結果
コードブロックの前に散文で例を導入してください。何を示しているのか、どのような結果が期待されるのかを述べてください。スニペットは最小限で自己完結型にし、Astroユーザーまたは契約を所有する内部呼び出し側の視点から書いてください。
モジュールドキュメントは、永続的な概念、アーキテクチャ上の境界、または設計上の理由を説明するべきです。ファイルを要約するために個々のエクスポートを列挙しないでください。そのような目録は、シンボルが追加または名前変更されるにつれて古くなります。モジュールに説明すべき永続的な概念がない場合は、簡潔な1行の説明を使用するか、概要を省略してください。
削除テスト
コメントを書く前に、自問してください:これは、読者がコード自体から回復できない情報を述べていますか?
- 情報が既に名前、型、または構造によって伝えられている場合、コメントを書かないでください。名前がそれを伝えきれない場合は、名前を改善してください。
- 正当にコメントを必要とする情報:不変条件、根拠、他の場所のコードとの結合、リンク付きの回避策、依存関係の驚くべき動作、モジュールが定義する専門用語。
後で編集する場合も、同じテストが逆に適用されます:テストに合格しなくなったコメントは、腐らせるのではなく削除するべきです。
回避策にはIssueへリンクする
このコードベースでは、一貫して回避策をソースに紐付けます。回避策、HACK、リグレッションガード、または依存関係の驚くべき動作を説明するコメントは、その動機となるGitHub IssueまたはPRにリンクしなければなりません。リンクは、将来の読者が回避策がまだ必要かどうかを判断できるようにするものです。
// Handle recommended nanostores. Only @nanostores/preact is required from our testing!
// Full explanation and related bug report: https://github.com/withastro/astro/pull/3667
'@nanostores/preact',
リンクのない回避策は、間違いと区別がつきません。
禁止パターン
次の行のナレーション。 これらを見つけ次第削除してください:
// Increment the generation counter
generation += 1;
変更履歴のナレーション。 現在形の根拠として書き直してください:
// BAD: We now resolve lightningcss from the user's root instead of ours.
// GOOD: lightningcss is an optional peer dep, so it resolves from the user's project root.
レビューア向けの正当化。 その議論はPRに移動してください:
// BAD: This correctly handles the multi-encoded path from the bug report.
// GOOD: A path still encoded after MAX_DECODE_ITERATIONS is rejected, so
// middleware and routing can never disagree on the decoded path.
JSDocの言い換え。 宣言名を言い換えた /** */ ブロックは何も述べていません:
// BAD:
/** Compiles the styles. */
function compileStyles(...)
// GOOD:
/** Rewrites relative `url()` references in `css` against `base`, leaving
* absolute and data URLs untouched. */
function compileStyles(...)
曖昧な hedging。 「いくつかのケース」「様々な理由」「エッジケースを処理する」「など」— それらを具体的に挙げるか、文を削除してください。
絵文字。 ソース、コメントを含め禁止されています(リポジトリ全体の方針)。
アドホックなセクションバナー (// ----- helpers -----, // ==== TYPES ====)。 このコードベースには // #region 折りたたみ規則はありません。バナーを追加しないでください。ファイルが長すぎてバナーを使いたくなった場合、それはファイルを装飾するためではなく、分割する必要があるシグナルです。
このコードベースの規約
JSDocタグ。 @param name - description、@returns、@throws は契約を述べます。シグネチャだけでは曖昧な場合のみ、型を中括弧で囲んでください(@returns {Promise<string>})。自明でない使用法については、フェンス付きの ```js ブロックと共に @example を使用してください。
相互参照。 裸の名前ではなく {@link Symbol} / {@linkcode Symbol} を使用してください。これにより、名前変更時に参照が更新され、エディタがターゲットにジャンプできます。
@internal。 パブリックな表面の一部ではないAPIを示します。これは規則に過ぎません — typedocやapi-extractorがここでそれを取り除くことはありません — そのため、意図を文書化しますが、アクセス修飾子を置き換えるものではありません。
@deprecated。 移行方法、次に廃止予定を述べてください:
/** @deprecated Use the instance method `cookies.consume()` instead. This will be removed in Astro 7 */
代わりに何を使うべきかを述べ、単にシンボルが非推奨であると述べるだけではいけません。この未来時制の注意は、読者が求める契約情報であり、禁止されている変更履歴のナレーションではありません。
TODO。 先延ばしされた作業には // TODO: を使用し、それを追跡するIssueがある場合はリンクしてください。破壊的変更のウィンドウに依存する作業には、確立されたイディオム // TODO: remove in Astro <N> を使用してください。このコードベースに FIXME はありません — 導入しないでください。
既存コードの編集
- 既存のコメントを保持してください。変更によって動作が変わる場合は、特定の散文を拡張または修正し、決して汎用的なテキストで置き換えないでください。苦労して得た文脈を削除することは、コメントを少し古くしたままにするよりも悪いことです。
- 変更によってコメントが誤ったものになった場合は、同じ差分で修正してください。古くなったコメントは、何もないより悪いです。
- 周囲の密度に合わせてください。ドキュメントが充実したモジュールでは、新しい項目にも同様のレベルが求められます。コメントが少ないモジュールに、むやみにコメントを追加しないでください。
完了前の自己チェック
コメントに触れるタスクを完了した後、コード変更から切り離して、差分内のコメントのみ を再読してください:
- それぞれが削除テストに合格していますか?
- 会話、変更自体、またはレビューアを参照しているものはありますか?
- すべての回避策がIssueまたはPRにリンクしていますか?
- 差分にアクセスできない読者がそれぞれを理解できるでしょうか?
合格しないものは修正または削除してください。削除がデフォルトです。欠落したコメントは、誤解を招くコメントよりはましです。
参考文献
- Diátaxis — 上記の説明 / リファレンス / 根拠の分割の背後にあるフレームワーク。
packages/astro/src/core/errors/README.md—@docsタグが付いたエラーエントリ(エンドユーザードキュメント)について。- TSDoc — TypeScript ドキュメントコメントのタグリファレンス。