@cody-greene/eslint-config

> eslint@^2.2.0

Usage no npm install needed!

<script type="module">
  import codyGreeneEslintConfig from 'https://cdn.skypack.dev/@cody-greene/eslint-config';
</script>

README

eslint@^2.2.0

Usage

This package offers two eslint config files:

  • lax.yml only includes rules that help catch errors while promoting best practices
  • strict.yml extends lax.yml by adding opinionated styling rules

When installing this module manually: be sure to use npm install cody-greene/eslint-config#vXXX

To configure a project, add something like this to package.json:

{
  "eslintConfig": {
    "root": true,
    "extends": "./node_modules/eslint-config/strict.yml",
    "env": {
      "browser": true,
      "commonjs": true,
      "es6": true
    },
    "parserOptions": {
      "ecmaVersion": 6,
      "ecmaFeatures": {
        "experimentalObjectRestSpread": true
      },
      "sourceType": "module"
    }
  },
  "devDependencies": {
    "eslint-config": "cody-greene/eslint-config#v1.0.0"
  }
}

Once the project is configured, make sure the appropriate eslint plugin is installed for real-time feedback.

Auto formatting

eslint --fix <file> will automatically fix several issues from the strict.yml ruleset, including:

array-bracket-spacing
eqeqeq
indent
keyword-spacing
no-multi-spaces
no-spaced-func
object-curly-spacing
quotes
semi
space-before-function-paren
space-unary-ops

Style rules

  • no-trailing-spaces Remove any trailing whitespace (configure your editor to do this automatically)

  • eol-last End files with a single newline character (configure your editor to do this automatically)

  • indent Use soft tabs set to 2 spaces (editor config). And try to limit lines to 100 columns. A complete .editorconfig is also provided. Install the plugin for sublime, vim, etc if you'd rather have per-project indentation settings.

Why? Same line-length & indentation when looking at the editor, the terminal, or github. Viewing hard-tabs properly in the terminal means adding tabs -2 to ~/.profile as well as setting git config --global core.pager 'less --tabs=1,3 --RAW-CONTROL-CHARS'. Viewing tabs on github as less than the default 8-spaces requires a browser extension.

  • semi Never use semicolons

  • quotes Use 'single-quotes' except when avoiding escape sequences e.g. an apostrophe

  • space-before-function-paren Place 1 space before the arguments list of anonymous functions

// bad
doSomething(function(err, res) {
  console.log(err, res)
})

// good
doSometing(function (err, res) {
  console.log(err, res)
})
  • no-space-func Place no space between a function name the the arguments list

  • keyword-spacing Place 1 space before the opening parenthesis in control statements.

// bad
if(isJedi) {
  fight ()
}

// good
if (isJedi) {
  fight()
}
  • brace-style Place 1 space before the leading brace. else & if-else should not be next to a closing brace.
// bad
if (foo){
  bar()
}else
{
  baz()
}

// good
if (foo) {
  bar()
}
else {
  baz()
}

// exception: one-liners (good)
function test(){ return 'test' }
if (foo) bar()
else baz()
// bad
function bar() {

  console.log(foo)

}

// good
if (baz) {
  console.log(qux)
} else {
  console.log(foo)
}
// bad
function bar( foo ) {
  return foo + baz( qux )
}

// good
if (foo) {
  console.log(foo)
}
// bad
const foo = [ 1, 2, 3 ]
console.log(foo[ 0 ])

// good
const foo = [1, 2, 3]
console.log(foo[0])
  • operator-linebreak When a statement is too long to fit on a single line, insert line breaks before operators
// bad
if (someCondition ||
  otherCondition) {
}

// good
if (someCondition
  || otherCondition) {
}
  • func-style Use function declarations instead of function expressions
// bad
const test = function (){ return 'hello' }

// good
function test(){ return 'hello' }

// exception: arrow-functions
const test = () => 'hello'

Why? It's easier to add/remove variables without messing with commas. Also, v8 will de-optimize any blocks containing let foo, bar (but not var foo, bar)

// bad
const foo = 867
  , bar = 53
  , baz = 0.9

// good
const foo = 867
const bar = 53
const baz = 0.9
  • comments Use /** ... */ for multi-line jsdoc style comments
/**
 * Post a new job for an active worker to execute
 * @example
 *   let redis = require('redis').createClient()
 *   // You may want to partially bind this:
 *   // enqueue = enqueue.bind(null, redis)
 *   enqueue(redis, {queue:'low', type:'ping'}, console.log)
 *   enqueue(redis, {queue:'hi', type:'ping', params: {
 *     foo: true,
 *     bar: 'baz'
 *   }}, console.log)
 * @param {RedisClient} redis
 * @param {string} opt.queue e.g. critical, high, low
 * @param {string} opt.type Name of the job handler
 * @param {object?} opt.params e.g. userid: '123' (may be null)
 * @param {number?} opt.time Delay the job until: epoch-time in milliseconds (default: no delay)
 * @param {function} done(err, id) Receives a unique job id if successful
 * @returns {boolean} false if redis command was added to offline queue
 */
function enqueue(redis, opt, done) {}
  • todo Use TODO & FIXME to annotate problems
class Calculator extends Abacus {
  constructor() {
    super()

    // TODO: total should be configurable by an options param
    this.total = 0
  }
}
  • naming Avoid single letter variables. Be descriptive. Use PascalCase for classes and camelCase for everything else
// bad
for (let i = 0; i < list.length; ++i) {
  let e = list[i]
  console.log(i, e)
}

// good
for (let index = 0; index < attendeeList.length; ++index) {
  let person = attendeeList[index]
  console.log(index, person)
}
  • no-unneeded-ternary Don't use conditional expressions that can be expressed with simpler constructs
// bad
var isDefault = answer === 1 ? true : false;

// good
var isDefault = answer === 1;

// bad
var foo = foo ? foo : 1;

// good
var foo = foo || 1;

Versioning this project

v<eslint-major>.<eslint-minor>.<config-version>[-cp]

example: eslint@2.2.0

  • release eslint-config@2.2.0
  • enable/change another rule
  • release eslint-config@2.2.1
  • eslint@2.3.0 released
  • update config with any new rules
  • release eslint-config@2.3.0