Use the Airbnb JavaScript Style Guide as a base for rules. This document demonstrates all overrides.
When commenting on a pull requests that something deviates from the rules set forth in this document or in the Airbnb style guide, it is helpful to provide a link.
- Todo
- Documentation and Comments
- Rules
- Indentation
- Comparing to undefined
- Blocks
- Variable Declaration
- Cache jQuery Node Lists
- Chaining
- Linting / Code Sniffing
- Require.js Guidelines
- Marionette / Backbone Guidelines
- Regions
- Add jshint/jscs docs.
- Explain requirejs.
- Explain Grunt.
- Add our Marionette conventions
Comment anything that is not immediately obvious what is happening. Any comments are more valuable than no comments, and no comments are better than out of date comments. Keep them up to date.
All comments should be written in GitHub Flavored Markdown.
Generate annotated source code with grunt-docco.
Examples of others using annotated source code:
4-space indent.
Tabs: Nope.
Use http://editorconfig.org/ to help get your editor into the proper settings.
- Never compare to
undefined
.
// bad
if (something === undefined) {
...
}
// good
if (typeof something === 'undefined') {
...
}
// better
if (_.isUndefined(something)) {
...
}
Put closing bracket and else
/else if
on the same line.
// bad
if (something === 1) {
...
}
else if (something === 2) {
...
}
else {
...
}
// good
if (something === 1) {
...
} else if (something === 2) {
...
} else {
...
}
Use proper indentation for if blocks with multiple conditions.
// bad
if (this.viewModel.get('playing') && !this._heroVideo.paused() && event.scrollDirection.toLowerCase() === 'forward') {
...
}
// good
if (
this.viewModel.get('playing') &&
!this._heroVideo.paused() &&
event.scrollDirection.toLowerCase() === 'forward'
) {
...
}
First part of scope should be declaration of all vars in the scope, one per line, in alphabetical order. Only assign variables in their declaration if there is no derivation required, including references to other variables.
// bad
var bar,
baz = bar, // Do not derive values in declarations.
foo = {};
// good
var bar;
var baz;
var foo = {}; // Assign only when possible (value doesn’t need to be derived).
param = param || {}; // If this is a function and you have default parameters.
baz = doSomethingWithThing(param);
Alphabetization should follow ASCII ordering, symbols come before uppercase, and uppercase comes before lowercase. In SublimeText, there is a shortcut to alphabetize a list of selected lines: fn F5
.
var $el;
var MY_CONST = 'my const name';
var MY_SECOND_COST = 'my second const name';
var aVariable;
Always cache jQuery ‘node lists’:
var $el = $(this);
var $myEl = $('.my-selector');
When chaining function calls, indent all calls and add a semicolon ;
on it's own line after the chained sequence. Notice the whitespace.
// bad
$('body').append('div').append('div');
// bad
var $(body) = $('body');
$('body')
.append('div')
.append('div');
// good
$('body')
.append('div')
.append('div')
;
Lint all your code with JSHint, and validate it with JavaScript Code Sniffer (jscs).
SublimeLinter3 has plugins for both jshint and jscs that will use the project and user specific configuration files.
Projects should be configured with a pre-commit hook that prevents commits with code that does not pass jshint and jscs.
Some things are not yet checked by jshint or jscs. Make sure to pay attention to these as we don't have a way to automatically check them yet:
- Chaining rules.
- No derivations in var declarations.
http://geeks.bizzabo.com/post/83917692143/7-battle-tested-backbonejs-rules-for-amazing-web-apps
In Marionette, regions are searched for by using .find()
on the parent $el
. To ensure we find the correct region when we have deeply nested components, we should be as specific as possible when defining these regions. For example:
UA5.View = Marionette.Layout.extend({
regions: {
someRegion: '> .someRegion'
}
};