'use strict';
. If the file contains a shebang, strict mode should be enabled on the second line.// Right
'use strict';
console.log('even when not required');
// Also right
#!/usr/bin/env node
'use strict';
console.log('even when not required');
// Wrong
'use strict';
console.log('even when not required')
;
// Right
console.log('even when not required');
// Wrong
console.log('even when not required')
const
.let
.var
.for
parentheses (repeat const
or let
for each variable in a separate statement)for...in
iterators should use descriptive namesfor
iterators should use single character names{}
// Right
if (condition) {
return;
}
// Wrong
if (condition) return;
if (condition)
return;
for
parentheses, unless already definedi
if possible. Nested for
loops use j
, k
, etc.for
with arrays, for...in
for objects (and always check hasOwnProperty()
)++i
, never i++
// Right
const name = 'john';
for (let i = 0; i < name.length; ++i) {
console.log(name[i]);
}
// Wrong
let position;
const name = 'john' ;
const len = name.length;
for (position = 0; position < len; position++) {
console.log(name[position]) ;
}
_
Example.prototype.method = function () {
this.public = 'external';
this._private = 'internal';
};
self
for passing this
into nested functionsExample.prototype.method = function () {
const self = this;
call(123, function (err) {
self.display(err);
});
};
// Right
const method = function () {
};
const arrow = (foo) => {
return bar;
};
// Wrong
function method() {
}
const arrow = foo => bar;
this instanceof
to check if a constructor function was called with new. (This allows for future prototypical inheritance.)Hoek.assert(this instanceof Server, 'Server must be instantiated using new');
// Right
if (test) {
if (value === 12) {
console.log('result');
}
}
// Wrong
if (test) {
if (value === 12) {
console.log('result');
}
}
'
never "
// Right
const string = 'text in single quotes';
// Wrong
const string = "text in single quotes";
all files need to end with a newline (or more accurately end of line). IDEs will often do a line separator instead. This is to ensure it is unix friendly. The "cat" command is a good example of seeing this behavior. Git does a good job of pointing these out when doing pull requests.
Two empty lines between module functions or assignments (end of function to comment about next function)
exports.get = function () {
// Some code
};
// 1
// 2
/**
* jsDoc comment
*/
internals.utility = function () {
//Some code
};
{
except for inlined or empty objects
// Right
if (condition) {
execute(value, { strict: true });
}
if (condition) {
const options = {
strict: true
};
execute(value, options);
}
const empty = {};
// Wrong
if (condition) { execute(value, { strict: true }); }
if (condition) {
const options = { strict: true };
execute(value, options);
}
const empty = {
};
}
,
, ;
, );
which must be followed by a newlineelse
, catch
, etc.}
if not last statement in scope// Right
if (condition) {
value = {
func: () => {
console.log('example');
},
message: 'hello'
};
execute(value, (err) => {
console.log(err);
});
}
else {
console.log('otherwise');
}
// Wrong
if (condition) {
value = {
func: () => {
console.log('example');
}, message: 'hello'
};
execute(value, (err) => {
console.log(err); }
);
} else {
console.log('otherwise');
}
{
// Right
exports.method = function () {
if (condition) {
if (otherCondition) {
console.log('sometimes');
}
if (result &&
result.statusCode === 200) {
console.log('special case');
}
console.log('always');
}
execute(123, (err) => {
console.log(err);
});
const empty = {};
};
// Wrong
exports.method = function () {
if (condition) {
if (otherCondition) {
console.log('sometimes');
}
if (result &&
result.statusCode === 200) {
console.log('special case');
}
console.log('always');
}
execute(123, (err) => {
console.log(err);
});
const empty = {
};
};
// Right
if (condition) {
if (otherCondition) {
console.log('done');
}
}
// Wrong
if (condition) {
if (otherCondition) {
console.log('done');
}
}
// Right
const value = calculate(1, 3);
// Wrong
const value = calculate(1, 3);
(
when declaring a function// Right
const example = function () {
return value;
};
// Wrong
const example = function() {
return value;
};
(
when invoking a function// Right
const key = example();
// Wrong
const key = example ();
(
or before )
// Right
execute('order', 34);
if (result === 'ok') {
console.log('success');
}
// Wrong
execute( 'order', 34 );
if ( result === 'ok' ) {
console.log( 'success' );
}
:
, always after object key :
// Right
const obj = {
a: 1,
b: 2,
c: 3
};
// Wrong
const obj = {
a : 1,
b :2,
c:3
};
;
, always after ;
if not end-of-line// Right
const name = 'john';
for (let i = 0; i < name.length; ++i) {
console.log(name[i]);
}
// Wrong
const name = 'john' ;
for (let i = 0;i < name.length ;++i) {
console.log(name[i]) ;
}
if
, else
, for
, return
, function
, etc.)// Right
for (let book in books) {
if (books.hasOwnProperty(book)) {
console.log(book.name);
}
}
// Wrong
for(let book in books) {
if(books.hasOwnProperty(book)) {
console.log(book.name);
}
}
{
and before }
in inlined object
{}
{ }
// Right
execute({ name: 'john', email: 'john@example.com' });
const empty = {};
const callback = () => { };
// Wrong
execute({name: 'john', email: 'john@example.com'});
const empty = { };
const callback = () => {};
[
and before ]
in inlined arrays// Right
const numbers = [1, 2, 3];
// Wrong
const numbers = [ 1, 2, 3 ];
//
// Right
// Some comment
// Wrong
//Some comment
,
, always after ,
unless end-of-line// Right
const numbers = [1, 2, 3];
execute({ name: 'john', email: 'john@example.com' });
for (let i = 0; i < name.length; ++i) {
console.log(name[i]);
}
// Wrong
const numbers = [1,2 ,3];
execute({ name: 'john',email: 'john@example.com' });
// This for loop violates the style guide, but illustrates incorrect spacing around a comma
for (let i = 0,il = name.length; i < il; ++i) {
console.log(name[i]);
}
// Right
const a = 1 + 3;
const b = 'john' +
' ' +
'doe';
// Wrong
const a=1+3;
const b='john'+
' '+
'doe';
,
(always at the end of the previous line)// Right
execute('some error message',
12345,
this);
// Wrong
execute('some error message'
,12345
,this);
// Right
const message = 'Hello ' +
'Steve, ' +
'How are you?';
if (value === 'hello' &&
result === 'ok') {
console.log('yes');
}
// Wrong
const message = 'Hello '
+ 'Steve, '
+ 'How are you?';
if (value === 'hello'
&& result === 'ok') {
console.log('yes');
}
// Right
const message = foo === bar ?
foo :
bar;
// Wrong
const message = foo === bar
? foo
: bar;
// Also Wrong
const message = (foo === bar ?
foo :
bar);
Always use //
unless it's a jsDoc declaration or license header
Always begin sentences with an upper case
No trailing .
unless comment contains multiple sentences
Formal style, consistent voice, no humor, present tense
No developer name or other personal notes
No TODOs
Line
{
unless other rules require itfunction execute() {
// Initialize state
const position = 0;
if (condition) {
// Return message
return 'hello';
}
}
function execute() {
// Print each book's name
for (let book in books) {
// Check for valid properties
if (books.hasOwnProperty(book)) {
console.log(book.name);
}
}
}
function execute(value) {
if (value !== null &&
value !== undefined) { // Explicit check as 'value' can be 0
console.log(value);
}
}
Statements should only be broken into multiple lines to improve readability
Break statements if they are longer than 150 characters long
No empty lines in the middle of a single statement
Indent multi-line statements
Conditions should be indented to the first character of the condition in the first line
if (result &&
result.status &&
result.status.statusCode === 200) {
console.log('success');
}
const message = 'hello' +
' and welcome';
exports
- defined automatically by nodeinternals
- must be declared as an object at the top of each module immediate following the require
sectioninternals
, including constantsinternals
namespace) and called at the top of the module after the internals
declaration.// Right
const Hapi = require('hapi');
const Hoek = require('hoek');
const Package = require('./package.json');
const internals = {
foo: 'bar'
};
internals.init = function () {
const server = new Hapi.Server();
...
};
internals.init();
// Also right
const Hapi = require('hapi');
const internals = {};
internals.package = require('./package.json');
internals.foo = 'bar';
internals.init = function () {
const server = new Hapi.server();
...
};
internals.init();
// Wrong
const hapi = require('hapi'); // Use uppercase name
const foo = 'bar'; // No global vars outside of internals
const internals = {
Foo: 'bar' // Don't use uppercase vars inside internals
};
const server = new Hapi.Server(); // No global vars outside of internals and exports / Set up your module inside an init() function
...
const Hoek = require('hoek'); // Declare modules at the top of the module
err
is reserved for errors received via a callback. Use error
for local function variableserr
callback
argument, it must be called on process.nextTick()
. Otherwise, the argument name must be next
to clearly declare that it may get called on same tickreturn