eslint-config-javascript

    2.0.0 • Public • Published

    Banner

    JavaScript Styleguide

    This is a normative guide on how to format JavaScript. The main aim is to get the best possible readability. It is especially optimized for ECMAScript 2015, but should work equally good with other versions.

    It's assumed that the code will be optimized by code minifiers and/or package tools for usage in a production client-side environment.

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

    Table of Contents

    Installation

    The easiest way to adhere to this guide is to use the included eslint-config-javascript module to check your files. In order to set it up, fist install ESLint and the module:

    npm install --save-dev eslint eslint-config-javascript

    Next add following entry to your package file:

    "eslintConfig": {
      "extends": "eslint-config-javascript"
    }

    This will load the configuration of this styleguide. Finally add a lint script to the package scripts:

    "scripts": {
      "lint": "eslint --max-warnings=0 --ignore-path=.gitignore .",
      
    }

    Now you can check your files for conformity simply by running

    npm run lint

    Guide

    Naming Conventions

    • Names SHOULD be descriptive
    • camelCase MUST be used for naming objects, functions, and instances
    • PascalCase MUST be used for classes and constructor names
    • _this MUST be used as a reference to this

    Whitespace

    • 2 spaces MUST be used for indentation
    • There MUST be no trailing whitespace characters
    • An empty newline must be placed at the end of a file
    • Invisibles SHOULD be displayed during coding to reduce the likelihood of whitespace mistakes
    • Tabs and spaces MUST NOT be mixed

    Reasoning:

    Originally this guide required the use of tabs for indentation. The problem, however, is that a tab character can have any length (normally 2 or 4 characters wide). This undermines the purpose of monospaced fonts, where every character is supposed to have the same length to ensures alignment and predictability of the text layout.

    Multi-line Statements

    • Lines MUST not be longer than 80 characters
    • When a statement is too long to fit on a line, line breaks MUST occur after an operator

    Semicolons

    Semicolons MUST NOT be used to terminate statements except the next line starts with an (, [ or `

    Commas

    Inline Commas

    An inline comma MUST be followed by one space character

    const colors = ["green", "yellow", "red"]

    instead of

    const colors = ["green","yellow","red"]

    Trailing Commas

    Trailing commas MUST be used in Arrays

    const fruits = [
      apple,
      banana,
      melon,
    ]

    instead of

    const fruits = [
      apple,
      banana,
      melon
    ]

    … and Objects

    const person = {
      firstName: "John",
      lastName: "Smith",
    }

    instead of

    const person = {
      firstName: "John",
      lastName: "Smith"
    }

    Reasoning:

    To add an element to the end of an Array or Object, 2 lines must be modified. This adds unnecessary visual clutter to diffs. Furthermore, elements can be more easily rearranged when they all have the same structure.

    Leading Commas

    No leading commas MUST be used

    const fruits = [
      apple,
      banana,
      peach,
      melon,
    ]

    instead of

    const fruits = [ apple
                 , banana
                 , peach
                 , melon
                 ]

    and

    const person = {
      firstName: "John",
      lastName: "Smith",
      age: 30,
    }

    instead of

    const person = { firstName: "John"
                 , lastName: "Smith"
                 , age: 30
                 }

    Variables / Constants

    Read Only

    Read only references to a value MUST be declared with const

    const answerToEverything = 42

    instead of

    let answerToEverything = 42

    Reassignable

    Reassignable variables must be declared with let

    let currentPage = 138
    
    function turnPageOver () {
      currentPage += 1
    }

    instead of

    const currentPage = 138
    
    function turnPageOver () {
      currentPage += 1
    }

    var keyword

    Variables must never be declared with var

    Declaration Group

    Each variable MUST be declared with exactly one const or let keyword

    const name = "John"
    const age = 34
    const instrument = "guitar"

    instead of

    const name = "John",
          age = 34,
          instrument = "guitar"

    Global Variables

    If a variable shall be exposed globally it MUST be explicitly declared as a property of the global scope (window/global object)

    window.brandName = "Stark Industries"
    // or
    global.brandName = "Stark Industries"

    instead of

    brandName = "Stark Industries"

    Unassigned variables

    Unassigned let variables MUST be declared last in a group of declarations

    const foo = 7
    let bar = 4
    let baz

    Operators

    Position

    Line breaks must occur after operators:

    const sentence = "This is a " +
      "short sentence."

    Except for the ternary operator:

    const status = isTesting
      ? "We are currently testing"
      : "Everything operational"

    Placing the ? and the : at the beginning of the line makes it easier to skim the code.

    Relational Operators

    • === MUST be used instead of ==
    • !== MUST be used instead of != except in value != null where it has the same effect as value !== null && value !== undefined

    Shortcuts MAY be used where appropriate:

    if (name) {
      
    }

    instead of

    if (name !== "") {
      
    }

    and

    if (collection.length) {
      
    }

    instead of

    if (collection.length > 0) {
      
    }

    Blocks

    Blocks MAY be used to create an encapsulated scope

    {
      const age = 34
    }
    
    {
      const age = 27
    }

    Conditionals

    Spaces Around Condition

    Before and after the condition must be a single space character.

    if (testValue) {
      doSomething()
    }

    instead of

    if(testValue){
      doSomething()
    }

    Blocks for Multiline Statements

    Blocks MAY be omitted in single line statements but must be used for multiline statements.

    if (testValue) doSomething()
    
    // or
    
    if (testValue) {
      doSomething()
    }
    if (testValue) {
      doSomething()
      doThisToo()
    }

    Placement of else

    else MUST be placed on a newline after the if-block.

    if (testValue) {
      doSomething()
    }
    else if (otherTestValue) {
      doSomethingElse()
    }
    else {
      doDefault()
    }

    instead of

    if (testValue) {
      doSomething()
    } else if (otherTestValue) {
      doSomethingElse()
    } else {
      doDefault()
    }

    Reasoning:

    • Increases readability through space between if and else block
    • As else is at the beginning of the line it's easier to skim down a list of ifs and elses.

    Comments

    • API documentation MUST NOT be written in comments. It lives in its own directory/repository

    • Obscure code SHOULD be commented but not obvious things So do not write comments like this:

      // If person is older than 34
      if (person.age > 34) {
        
      }

    Single Line

    • // MUST be used for single line comments
    • There MUST be a space between // and the first character of the comment
    • Single line comments SHOULD be placed on a newline above the subject of the comment
    • One empty line MUST be put before a single line comment which starts at the beginning of a line.
    • // FIXME: MAY be used to annotate problems
    • // TODO: MAY be used to capture issues which need to get solved

    Multiline

    • /* … */ MUST be used for multiline comments
    • Two empty line MUST be put before a multi line comment
    • The start and end tag MUST be on a separate line
    /*
    This is a
    multiline comment
    */

    Strings

    Double quotes MUST be used for strings.

    Since most languages use double quotes for strings, this reduces the friction in multi-language projects.

    Objects

    Arrays

    Functions

    Anonymous

    Anonymous functions MUST start with a !

    !function () {
      
    }

    Reasoning:

    (function () {}) can lead to errors when relying on ASI (Automatic Semicolon Insertion) or when concatenating several JavaScript files

    Properties

    Methods

    Chaining

    Indentation SHOULD be used for long method chains. At the most one method should be called per line.

    $("#items")
      .find(".selected")
      .highlight()

    instead of

    $("#items").find(".selected").highlight()

    Methods SHOULD return this to enable method chaining.

    Setters

    Properties SHOULD be settable via setters and via a set* method to enable chaining.

    person.status = single
    
    person
      .setName("John")
      .marryTo("Linda")
      .setStatus("married")

    This enables easy traversing of structures involving several classes:

    database
      .load("John")
      .setAge("34")
      .sister
      .husband
      .setName("Tom")

    Getters

    Retrieving of properties MUST at least be implemented via a getter.

    console.log(person.age)

    instead of

    console.log(person.age())

    Type Casting

    • To string: String(123)

    • To number: Number("123")

    • To boolean: Boolean(1)

    • To array:

      Array.from("test")
      // => ["t", "e", "s", "t"]
      function doSomething () {
        Array.from(arguments)
      }
      doSomething(1, 2, 3)
      // => [1, 2, 3]

    // TODO: to date, …

    General

    You MAY (when it's absolutely necessary) differ from any rules of this guide to increase performance. You MUST, however, explain the reasons for not sticking to a rule in a comment.

    Framework specific

    jQuery

    Object variables MUST be prefixed with a $

    const $form = $("#myForm")

    instead of

    const form = $("#myForm")

    Lookups MUST be cached

    const $form = $("#form")
    
    $form.css({
      "background-color": "pink"
    })
    
    // …
    
    $form.hide()

    instead of

    $("#form").css({
      "background-color": "pink"
    })
    
    // …
    
    $("#form").hide()

    Best Practices

    Imports

    Imports and requires should be sorted by type.

    1. Native
    2. External
    3. Internal

    To improve readability keep an empty newline between each section and 2 empty newlines below all imports / requires.

    For example ES2015 style imports:

    import path from "path"
    import fs from "fs"
    
    import lodash from "lodash"
    
    import app from "./source/app"
    
    
    const port = 1234

    The same applies to CommonJS requires:

    const path = require("path")
    const fs = require("fs")
    
    const lodash = require("lodash")
    
    const app = require("./source/app")
    
    
    const port = 1234

    Functions

    Every non-primitive function should look like this:

    function doSomething (options = {}) {
        const {
            hasThis = true, // Some clear description why this is here
            isThat = false,  // More clear descriptions
            importantNumber = 1234, // The clearest description in the universe
            content = "Some thoughtful text", // Crystal clear
        } = options
    
        // Optional type checks
        if (typeof importantNumber !== "number") {
            throw new TypeError(
                `importantNumber must be a number and not "${importantNumber}"`
            )
        }
    }

    This ensures:

    • Arguments have appropriate default values
    • Other developers can easily see which arguments are expected
    • No incorrect values can be passed
    • Function is extendable without a need to change the function signature

    Related

    Install

    npm i eslint-config-javascript

    DownloadsWeekly Downloads

    100

    Version

    2.0.0

    License

    ISC

    Unpacked Size

    69.8 kB

    Total Files

    12

    Last publish

    Collaborators

    • adius