格式指南

請參閱 Google TypeScript 樣式指南

遷移至 TypeScript 和 ES6

Blockly 最初是使用 ES5.1 編寫,符合較舊的 Google JavaScript 樣式指南 (當時為最新版本)。新編寫的程式碼應遵循目前的樣式指南,並使用 ES6 語言功能,例如 letconstclass,以及在適用情況下使用結構重組指派。現有程式碼可能會更新,也可能不符合規定。Blockly 團隊會考量程式碼一致性和程式庫使用者體驗,盡力做出最佳決策。舉例來說,我們可能會選擇不重新命名不再符合樣式指南的公開函式。

正確做法

  • 使用 linting 和格式設定工具。
    • 我們使用 eslint,並設定 eslint.config.mjs 檔案,其中包含我們偏好風格的規則。
    • 我們會使用 prettier 自動調整格式。
    • 執行 npm run lint 可執行 lint 工具,執行 npm run format 可執行格式化工具。
  • 使用空格縮排,而非 Tab 鍵。
  • 使用分號
  • camelCase 用於變數和函式。
  • TitleCase 用於類別。
  • ALL_CAPS 用於常數。
  • 使用大括號來表示所有控制結構。
    • 例外狀況:您可以省略單行 if 陳述式的大括號。
  • 使用單引號 (撰寫 JSON 時除外)。
  • for 迴圈中重新宣告變數。也就是說,請一律使用 for (const i = 0; ...),而非 for (i = 0; ...)
    • 否則在函式中進行較高層級的重構後,變數就會變成孤立的變數,並意外成為全域變數。
  • 以大寫字母開頭,結尾則須加上句號。
  • 建立含有待辦事項的 GitHub 問題,並使用 TODO(#issueNumber) 連結。
  • 使用 TSDoc 為所有項目加上註解。

錯誤做法

  • 使用 Tab 鍵縮排。
  • 在變數或函式名稱結尾處使用底線。
    • 部分舊版程式碼會使用底線來表示私人或內部屬性或函式。雖然這些程式碼可能會繼續存在,但請勿依照這項慣例新增任何新程式碼。
  • 使用 snake_case
  • 使用雙引號 (撰寫 JSON 時除外)。
  • 使用格式錯誤的 TSDoc。
    • 我們的 TSDoc 會自動發布為說明文件的一部分。
  • 寫入 TODO (username)
    • 請改為建立含有待辦事項的 GitHub 問題,並使用 TODO(#issueNumber) 連結這些問題。
  • 使用「string.startsWith」。改用 Blockly.utils.string.startsWith

TSDoc

Blockly 團隊會使用 TSDoc 為程式碼加上註解,並產生文件。我們希望所有類別的公開屬性和所有匯出的函式都有 TSDoc。

TSDoc 註解必須以 /** 開頭,並以 */ 結尾,才能正確剖析。

類型

因為 TSDoc 中的資訊會直接顯示在 TypeScript 程式碼中,因此會省略類型。如果您要編輯剩餘的少數 JavaScript 檔案,請根據 Closure Compiler 說明文件加入型別註解。

顯示設定

僅可在 Blockly 程式庫中存取的函式或屬性,應加上 @internal 註解。這樣可避免這些屬性出現在公開文件中。其他可見度修飾符應直接放入 TypeScript 程式碼中,而非 TSDoc。

屬性

屬性的 TSDoc 應包含屬性的說明。如果屬性不需說明,可以省略說明。

/**
  *   The location of the top left of this block (in workspace coordinates)
  *   relative to either its parent block, or the workspace origin if it has no
  *   parent.
  *
  *   @internal
  */
relativeCoords = new Coordinate(0, 0);

函式

函式註解應包含

  • 函式的說明
  • 每個參數一個 @param 標記,包括
    • 名稱
    • 說明
  • 如果函式會傳回值,則使用 @returns 標記,並附上傳回值的說明。

如果函式、參數或傳回值不言自明,可以省略說明。

例如:

/**
 *   Find the workspace with the specified ID.
 *
 *   @param id ID of workspace to find.
 *   @returns The sought after workspace or null if not found.
 */
export function getWorkspaceById(id: string): Workspace | null {
  return WorkspaceDB_[id] || null;
}