Blockly 样式指南

遵循 Google TypeScript 样式指南

迁移到 TypeScript 和 ES6

Blockly 最初是用 ES5.1 编写的,符合 Google JavaScript 样式指南的旧版本和当前版本。新编写的代码应符合当前的样式指南,并在适用的情况下使用 ES6 语言功能(如 letconstclass 和解构赋值)。现有代码可能会被更新,或者不合规。Blockly 团队会根据代码一致性和库用户的体验做出最佳决策,例如,我们可能会选择不重命名不再符合样式指南的公共函数。

正确做法

  • 使用 lint 检查和格式设置工具。
    • 我们使用 eslint 并设置一个 .eslintrc.js 文件,其中设置了首选样式的规则。
    • 我们使用 prettier 进行自动格式设置。
    • 运行 npm run lint 以运行 linter,并运行 npm run format 以运行格式化程序。
  • 使用空格缩进,而非制表符。
  • 使用英文分号
  • 对于变量和函数,请使用 camelCase
  • 对于类,请使用 TitleCase
  • 对常量使用 ALL_CAPS
  • 对所有控件结构使用大括号
    • 例外情况:可以省略单行 if 语句的大括号。
  • 使用单引号(写入 JSON 时除外)。
  • for 循环中重新声明变量。也就是说,应始终写入 for (const i = 0; ...) 而不是 for (i = 0; ...)
    • 否则,在对函数进行更高级别的重构后,该变量将变为孤立状态,并成为出乎意料的全局变量的风险。
  • 评论应以大写字母开头,并以句点结尾。
  • 创建有关 TODO 的 GitHub 问题,并使用 TODO(#issueNumber) 关联它们。
  • 使用 TSDoc 为所有内容添加注解。

错误做法

  • 使用制表符缩进。
  • 在变量或函数名称末尾使用下划线。
    • 某些早期代码使用下划线来表示私有属性或内部属性或函数。虽然这些代码可能会继续存在,但不应按照此惯例添加新代码。
  • 使用 snake_case
  • 使用英文双引号(写入 JSON 时除外)。
  • 使用格式错误的 TSDoc。
    • 我们的 TSDoc 会自动作为文档的一部分发布。
  • 写入 TODO (username)
    • 请改为创建有关 TODO 的 GitHub 问题,并使用 TODO(#issueNumber) 关联它们。
  • 使用 string.startsWith。请改用 Blockly.utils.string.startsWith

TS 文档

Blockly 团队使用 TSDoc 为代码添加注释并生成文档。我们希望类的所有公共属性以及所有导出的函数具有 TSDoc。

TSDoc 注释必须以 /** 开头并以 */ 结尾,才能被正确解析。

类型

TSDoc 中省略了类型,因为该信息直接包含在 TypeScript 代码中。如果要修改剩下的几个 JavaScript 文件中之一,请根据 Closure 编译器文档添加类型注解。

公开范围

应只应在 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;
}