This is a living document with coding conventions and rules to improve the writing and design of the Bower codebase.
All code in any code-base should look like a single person typed it, no matter how many people contributed. – Principles of Writing Consistent, Idiomatic JavaScript
Bower's code style stays true to convention, while still allowing for flexibility. When contributing, you should write your code following Bower's style.
We make use of JSHint and JSCS. JSHint takes care of coding correctness, while JSCS focuses on coding style.
Use braces with all multi-line blocks.
// bad
if (foo)
return false;
// good
if (foo) return true;
// bad
function foo() { return false; }
// good
function foo() {
return true;
}
If there is a list of things separated by commas, and it wraps across multiple lines, put the comma at the end of the current line. Also start the first element on a new line, after the first array bracket. End on the same indentation level as you started.
// bad
var magicWords = [
'abracadabra'
, 'gesundheit'
, 'ventrilo'
];
// good
var magicWords = [
'abracadabra',
'gesundheit',
'ventrilo'
];
Yes.
// bad
(function() {
var name = 'Skywalker'
return name
})()
// good
(function() {
var name = 'Skywalker';
return name;
})();
Use single quotes for all strings except to avoid escaping.
// bad
var notOk = "Just double quotes"
// good
var ok = 'String contains "double" quotes'
var alsoOk = "String contains 'single' quotes or apostrophe"
Set your editor to the following settings to avoid common code inconsistencies and dirty diffs:
- Use soft-tabs set to four spaces.
- Trim trailing white space on save.
- Set encoding to UTF-8.
- Add new line at end of files.
You can also install the EditorConfig in your text editor, it will grab the settings from the .editorconfig
in the root of this repo automatically.
Never name a parameter arguments. This will take precedence over the arguments object that is given to every function scope.
// bad
function nope(name, options, arguments) {
// ...stuff...
}
// good
function yup(name, options, args) {
// ...stuff...
}
Use camelCase
when naming objects, functions, and instances.
// bad
var THISISMYOBJECT = {};
var this_is_my_function = function() {};
// good
var thisIsMyObject = {};
var thisIsMyFunction = function() {};
Use PascalCase
when naming constructors, classes, and filenames.
// bad
function person(options) {
this.name = options.name;
}
var bad = new person({
name: 'john doe'
});
// good
function Person(options) {
this.name = options.name;
}
var good = new Person({
name: 'john doe'
});
Use a leading underscore _
when naming private properties.
// bad
this.__firstName__ = 'John';
this.firstName_ = 'John';
// good
this._firstName = 'John';
Name your functions. This is helpful for stack traces.
// bad
var log = function(msg) {
console.log("yo");
};
// good
var log = function log(msg) {
console.log("yo");
};
Use CAPS_SNAKE_CASE
for symbolic constants.
// bad
apikey = "73b91e6e0f1ae12b73d8";
// good
API_KEY = "73b91e6e0f1ae12b73d8";
Use /** ... */
for multi-line comments. Include a description, specify types and values for all parameters and return values.
// bad
// make() returns a new element
// based on the passed in tag name
//
// @param {String} tag
// @return {Element} element
function make(tag) {
// ...stuff...
return element;
}
// good
/**
* make() returns a new element
* based on the passed in tag name
*
* @param {String} tag
* @return {Element} element
*/
function make(tag) {
// ...stuff...
return element;
}
Use //
for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment.
// bad
var active = true; // is current tab
// good
// is current tab
var active = true;
// bad
function getType() {
console.log('fetching type...');
// set the default type to 'no type'
var type = this._type || 'no type';
return type;
}
// good
function getType() {
console.log('fetching type...');
// set the default type to 'no type'
var type = this._type || 'no type';
return type;
}
Prefixing your comments with FIXME
or TODO
helps other developers quickly understand if you're pointing out a problem that needs to be revisited, or if you're suggesting a solution to the problem that needs to be implemented. These are different than regular comments because they are actionable. The actions are FIXME -- need to figure this out
or TODO -- need to implement
.
Use // FIXME:
to annotate problems.
function Calculator() {
// FIXME: shouldn't use a global here
total = 0;
return this;
}
Use // TODO:
to annotate solutions to problems.
function Calculator() {
// TODO: total should be configurable by an options param
this.total = 0;
return this;
}