Skip to content

Latest commit

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..

README.md

Invoca Javascript Style Guide

  • The javascript style guide rules are defined in the ESlint configuration file.
  • The style guide rules that couldn't be defined in ESlint are documented below.

Table Of Contents

Source Code Layout

No space before : in a hash; by default do not line up items

// goodvarsettings={version: 8,deviceType: 'iPhone'};// BAD - leading spacevarsettings={version : 8,deviceType : 'iPhone'};// use sparingly - no leading space, but lining up the keys// can be useful for hashes that are difficult to read but don't change oftenvardefaultConfig={version: 8,deviceType: 'iPhone',log: true};

Put opening { on same line as the function declaration or boolean expression. This matches common JavaScript convention and most IDE's default to this behavior

// goodfunctioninlineness(){alert("hi");if(Ext.isIE){alert("I'm sorry you are using that browser.");}}// BAD - new line before opening parenfunctioninlineness(){alert("hi");if(Ext.isIE){alert("I'm sorry you are using that browser.");}}// goodif(inlineIf===true){// do stuff}else{// do other stuff};// BADif(inlineIf===true){// do stuff}else{// do other stuff};

Use spaces around operators, after commas, colons and semicolons, around { and before }. (But there is no need for spaces inside the empty hash {}.)

// goodonClick="function() { alert('hi'); }"myHash={}// bad - no space around assignmentonClick="function() { alert('hi'); }"// bad - no space after function argsonClick="function(){ alert('hi'); }"// bad - no spaces in method declarationonClick="function() {alert('hi');}"// bad - padding spaces next to parensonClick="function( ) { alert( 'hi' ); }"// React// When using JSX templates do not use spaces after bracket// good
render: function(){return(<p>
It is {this.props.date.toTimeString()}</p>);}// bad
render: function(){return(<p>
It is {this.props.date.toTimeString()}</p>);}

When possible (and you only need falsey), rely on null & undefined returning false by default

// good// when checking if var is not null, not undefined, and not falseif(myVar){
...
}// when checking if var is either null, undefined or falseif(!myVar){
...
}// badif(myVar!=null&&typeofmyVar==undefined){
...
}

When needing to check for undefined explicitly, use underscore

// goodif(_.isUndefined(myVar)){
...
}// BADif(typeofmyVar==="undefined"){
...
}// WORST: only two ==if(typeofmyVar==undefined){
...
}

Use proper quotes "" for valid JSON and '' for html elements

// goodjson={key: "Valid JSON"}html='<div class="example" id="some_id">'// BADjson={key: 'invalid JSON'}html="<div class=\"example\" id=\"some_id\">"Bewaryofchainingmethodsthatmayreturnnull// goodvarmatch=$(id).val().match(/\.([^.]+)$/);varextension=match&&match[1].toLowerCase();// badvarextension=$(input).val().match(/\.([^.]+)$/)[1].toLowerCase();

Assign variables on separate lines, as 2 statements or a combined statement (but only when all variables in the combined statement are starting as undefined). If in doubt, use separate lines with separate var statements

// goodvarisCustom=false;varisLoading=true;// goodvariterator;varisLoading=true;// okay because both are undefinedvarisCustom,isLoading;// badvarisCustom=false,isLoading=true;// badvarisCustom=false,isLoading=true;// bad - and confusing as to the intent (should isCustom also have been set to false?)varisCustom,isLoading=false;

Prefer || assignment over ternary

// goodvarminCount=count||0;// badvarminCount=count ? count : 0;

New Lines

Blank line between methods in a "class"

// goodvarWidget={methodA: function(){},methodB: function(){}}// badvarWidget={methodA: function(){},methodB: function(){}}

Switch statements

Blank line between case statements in switch

Indent case as deep as switch

// goodswitch(foo){case'bar':
alert("it's bar!");break;case'bar2':
alert("it's bar2!");break;default:
alert("default!");}// badswitch(foo){case'bar':
alert("it's bar!");break;case'bar2':
alert("it's bar2!");break;default:
alert("default!");}

Naming

Follow standard JS conventions

Use camelCase with leading lower case for variable names and attributes / methods

// goodvarinsightsColumns=[];// bad - ruby stylevarinsights_columns=[];// goodapp.view("NetworkEdit",{adjustButtonState: function(){ ...
// bad - don't name views with underscores, don't name methods with underscoresapp.view("network_edit",{adjust_button_state: function(){ ...

Use CamelCase with leading upper case for class names and Backdraft app & plugin names

// goodBackdraft.app("InsightsManager",function(app){app.view("NetworkIndex",{ ...

when javascript uses class names as selectors, preface the class names with js-

// goodvarmydiv=$(".js-find-me");// bad - no js- preface for javascript selector classvarmydiv=$(".find-me");

Promises

Prefer async/await over Promise.prototype.then/catch/finally because it's easier to write, read, debug, and test, and it's an effective way to write asynchronous code that appears synchronous.

// goodasync()=>{try{awaitonSubmit(value);console.log("it succeeded");}catch(error){console.log("there was an error");}}// bad()=>{onSubmit(value).then(()=>{console.log("it succeeded");}).catch((error)=>{console.log("there was an error");})}

Comments

Good code is its own best documentation.

-- Steve McConnell

When code can be refactored and put into better named methods / classes, we prefer that over a comment that just describes what a method does. But comments are okay to describe an interface or a browser hack needed, etc.

CoffeeScript

For a period we created CoffeeScript classes and have tests written in CoffeeScript, but we are not adding new CoffeeScript.

Source Code Layout

Use two spaces per indentation level. No hard tabs. Coffeescript is whitespace significant, so you must be diligent about indentation! Insert a single newline after method definitions

# goodclassFoorun: ->implementation()jump: ->implementation()
# BAD-nonewlineclassFoorun: ->implementation()jump: ->implementation()

Have spaces between operators in an expression

# goodifx>0run
# bad-nospacesifx>0run
# goodfoo="bar"
# bad-nospacesfoo="bar"