TL;DR
Follow the
Google JavaScript style guide.
New code should use ES6 language features like let
, const
, class
,
destructuring assignment, etc, where applicable.
Migrating to ES6
Blockly was originally written in ES5.1 in compliance with an older, then-current version of the Google JavaScript style guide. We are migrating the codebase to ES6 and the new style guide. Older browsers, including Internet Explorer 11, will continue to be supported by transpilation to ES5.1.
Do
- Indent with spaces, not tabs.
- Use eslint.
- We have a
.eslintrc.json
set up with rules for our preferred style.
- We have a
- Use semicolons.
- Use underlines at the end of
protectedVariableNames_
,privateVariableNames_
,protectedFunctionNames_
, andprivateFunctionNames_
. - Use
camelCase
for variables and functions. - Use
TitleCase
for classes. - Use
ALL_CAPS
for constants. - Use braces for all control structures.
- Use single quotes (except when writing JSON).
- Redeclare variables in
for
loops. That is, always writefor (let 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.
- Line wrap at 80 characters to make reviewing easier.
- Indent the wrapped line with four spaces.
- If a line is broken at multiple syntactic levels, each level should have a four space indent from the previous line / syntactic level.
- Start comments with capital letters and end them with periods.
- Create GitHub issues with TODOs and link them using
TODO(#issueNumber)
. - Annotate everything with JSDoc.
Don't
- Indent with tabs.
- Use underlines at the ends of
publicVariableNames
andpublicFunctionNames
. - Use
snake_case
. - Use double quotes (except when writing JSON).
- Use malformed JSDoc.
- Our JSDoc 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.
JSDoc
The Blockly team uses JSDoc to annotate our code and generate documentation. We expect JSDoc for all properties of classes, and for all functions.
JSDoc comments must start with /**
and end with */
to be parsed correctly.
Blockly uses four visibility tags. Always use the most restricted scope possible.
public
means that the function or property can be used by anyone, including outside developers.package
means that the function or property can be used by any class inside Blockly, but outside developers may not use it.protected
means that the function or property can be used by the owning class or subclasses of the owning class.private
means that the function or property can be used by the owning class, and only the owning class.
Properties
Annotations for properties should include
- A description of the property
- The type
- A visibility tag:
public
,package
,protected
, orprivate
Preferred:
/**
* Whether the block may be deleted by the user.
* @type {boolean}
* @private
*/
this.deletable_ = true;
Allowed, only when the meaning of the property is obvious.
/** @type {boolean} */
this.isInFlyout = false;
Functions
Annotations for functions should include
- A description of the function
- One
@param
tag per parameter, including- Type
- Name
- Description
- A visibility tag:
public
,package
,protected
orprivate
- A
@return
tag if the function will return a value, including- Type
- A description of the returned value, if any
For example:
/**
* Obtain a newly created block.
* @param {!Blockly.Workspace} workspace The block's workspace.
* @param {string} prototypeName Name of the language object containing
* type-specific functions for this block.
* @return {!Blockly.Block} The created block.
* @public
* @deprecated December 2015. Will be removed Decmeber 2016. Use
* workspace.newBlock instead.
*/
Blockly.Block.obtain = function(workspace, prototypeName) {
Blockly.utils.deprecation.warn(
'Connection.prototype.checkType',
'December 2015',
'December 2016',
'workspace.newBlock');
return workspace.newBlock(prototypeName);
};