Follow the Google TypeScript style guide.
Migration to TypeScript & ES6
Blockly was originally written in ES5.1 in compliance with an older,
then-current version of the Google JavaScript style
guide. Newly-written
code should comply with the current style guide and use ES6 language features
like let
, const
, class
, destructuring assignment where applicable.
Existing code may be updated or may be left out of compliance. The Blockly team
tries to make the best decision taking into account code consistency and the
experience for users of the library - for example, we may opt not to rename
public functions that no longer comply with the style guide.
Do
- Use linting and formatting tools.
- We use eslint and have a
.eslintrc.js
file set up with rules for our preferred style. - We use prettier for automatic formatting.
- Run
npm run lint
to run the linter andnpm run format
to run the formatter.
- We use eslint and have a
- Indent with spaces, not tabs.
- Use semicolons.
- Use
camelCase
for variables and functions. - Use
TitleCase
for classes. - Use
ALL_CAPS
for constants. - Use braces
for all control structures.
- Exception: You may omit the braces for single-line
if
statements.
- Exception: You may omit the braces for single-line
- Use single quotes (except when writing JSON).
- Redeclare variables in
for
loops. That is, always writefor (const i = 0; ...)
instead offor (i = 0; ...)
.- Not doing so raises the risk that after a refactor higher up in the function the variable will be orphaned and become a surprise global.
- Start comments with capital letters and end them with periods.
- Create GitHub issues with TODOs and link them using
TODO(#issueNumber)
. - Annotate everything with TSDoc.
Don't
- Indent with tabs.
- Use underlines at the ends of variable or function names.
- Some earlier code uses underscores for private or internal properties or functions. While these may continue to exist, no new code should be added following this convention.
- Use
snake_case
. - Use double quotes (except when writing JSON).
- Use malformed TSDoc.
- Our TSDoc is automatically published as part of our documentation.
- Write
TODO (username)
.- Instead create GitHub issues with TODOs and link them using
TODO(#issueNumber)
.
- Instead create GitHub issues with TODOs and link them using
- Use
string.startsWith
. UseBlockly.utils.string.startsWith
instead.
TSDoc
The Blockly team uses TSDoc to annotate our code and generate documentation. We expect TSDoc for all public properties of classes, and for all exported functions.
TSDoc comments must start with /**
and end with */
to be parsed correctly.
Types
Types are omitted from TSDoc because that information is in the TypeScript code directly. If you are editing one of the few remaining JavaScript files, include type annotations according to the Closure Compiler documentation.
Visibility
Functions or properties that should only be accessed within the Blockly library
should be annotated with @internal
. This prevents these properties from
appearing in the public documentation. Other visibility
modifiers
should be placed in the TypeScript code directly, not in the TSDoc.
Properties
TSDoc for properties should include a description of the property. The description may be omitted for self-explanatory properties.
/**
* 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);
Functions
Annotations for functions should include
- A description of the function
- One
@param
tag per parameter, including- Name
- Description
- A
@returns
tag if the function will return a value, with a description of the returned value.
Descriptions may omitted for functions, parameters, or return values if they are self-explanatory.
For example:
/**
* 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;
}