Ben Gladwell

How Linting Produces Better Code

Writing code free of blunders is nearly impossible. How can a team manage a cumbersome programming language like JavaScript? Find out how we use static analysis to meet our goals at Adept.

Writing code free of blunders is nearly impossible. How can a team manage a cumbersome programming language like JavaScript? Find out how we use static analysis to meet our goals at Adept.

At Adept, we take pride in delivering the best web experiences for our clients. That means we write quite a bit of JavaScript. And as Douglas Crockford will tell you:

“In JavaScript, there is a beautiful, elegant, highly expressive language that is buried under a steaming pile of good intentions and blunders.”

Of course, we would like to keep our code free of blunders. But how can a team manage an unwieldy programming language in addition to writing good, maintainable code?

Linting provides flexible guardrails that can keep you coding quickly and accurately. Here, I’ll explain the basics of linting, and reasons why it can help your projects.

What is Linting?

Linting tools provide static analysis of your code. These tools don’t run your code to see what happens – they inspect your code, looking for typos or anti-patterns.

A Brief History of Linting

The JavaScript community has been evolving its linting tools for 15 years!

In 2002, Douglas Crockford released JSLint, designed to address many of the “good intentions and blunders” that he had discovered in JavaScript. The code style conventions enforced by JSLint continue to influence JavaScript developers today, myself included.

In 2010, JSLint was forked in an effort to create a more configurable version. The resulting project, JSHint, is both more configurable and more focused; all of the style-related rules were stripped out. For this reason, it was often paired with JSCS, a JavaScript style analysis tool.

Where Linting is Today

The latest evolution in JavaScript linting tools is ESLint. The flexibility of ESLint has made it the de facto linting tool for pretty much every major JavaScript project today. It handles syntax and style like JSLint, and is even more configurable than JSHint.

How can Linting Help my Project?

Linting JavaScript in real time as you code provides three main benefits:

1. Bug Detection

There is a large class of bugs that are the result of typos. Linting tools have saved me hours of time by simply alerting me to mistyped variable names, either where they are declared or where they are (mis)used. Static analysis can easily detect when you attempt to reference a variable that is not in scope; this is usually the result of a typo.

2. Maintainability

Reading code written in an unfamiliar style is like reading poor handwriting. The information is all there, but it requires inordinate concentration simply to extract to it. Conversely, reading code that adheres to a familiar style allows you to focus on what is important. Whether it’s someone else’s code or your own that you are returning to, having a common style greatly reduces maintainability costs.

3. Flow

Experiencing flow while developing software is priceless. When you are in the zone and ideas flow freely, you create better, more creative code. In the various studies that examine conditions for flow, one common factor is structure; there should be clear goals and ongoing feedback built into the activity. In my experience, real time linting feedback greatly contributes to flow. In addition to feedback, adhering to one code style reduces cognitive load as many small, insignificant decisions are made in advance: indentation, curly brace placement, operator separation, etc.

How to Start the Linting Process

If you are new to linting JavaScript, getting started is easy. First, install ESLint for your project:

npm install --save-dev eslint

Your editor of choice likely has built in support for ESLint. If not, you should figure out how to get it working—or choose a new editor!

Configuring ESLint

The most important thing you need to get started with ESLint is an .eslintrc file that describes the rules you want to enforce. Below, you will find the configuration that Adept uses for non-transpiled / ES5 projects (as of the time of writing, of course). Most of the style related rules simply emulate JSLint’s original style requirements. Drop an .eslintrc file like this into your project’s root directory and your editor should start using the rules.

Note the use of `“extends”: “eslint:recommended”`. This imports a baseline set of rules that are indispensable.

{
 "env": {
   "browser": true
 },
 "extends": "eslint:recommended",
 "rules": {
   "curly": 2,
   "eqeqeq": 2,
   "no-else-return": 2,
   "no-eval": 2,
   "no-extra-bind": 2,
   "no-floating-decimal": 2,
   "no-implicit-coercion": 2,
   "no-implied-eval": 2,
   "no-labels": 2,
   "no-multi-spaces": 2,
   "no-param-reassign": 2,
   "no-throw-literal": 2,
   "no-unused-expressions": 2,
   "no-useless-concat": 2,
   "block-scoped-var": 2,
   "no-inner-declarations": [2, "both"],
   "strict": 2,

   "array-bracket-spacing": 2,
   "block-spacing": 2,
   "brace-style": [2, "1tbs", { "allowSingleLine": true }],
   "comma-spacing": 2,
   "comma-dangle": 2,
   "comma-style": 2,
   "computed-property-spacing": 2,
   "eol-last": 2,
   "indent": [2, 2],
   "no-bitwise": 2,
   "no-lonely-if": 2,
   "no-empty": 2,
   "no-plusplus": 2,
   "no-trailing-spaces": 2,
   "no-unneeded-ternary": 2,
   "space-in-parens": 2,
   "space-infix-ops": 2,
   "space-unary-ops": 2,
   "keyword-spacing": 2,
   "space-before-function-paren": [2, {
     "anonymous": "always",
     "named": "never"
   }],
   "space-before-blocks": 2,
   "no-shadow": 2
 }
}

ES2015 / ES6 rules

When working on projects with a transpiled build we are more than happy to make use of new ES2015 syntax. Our .eslintrc for those projects is largely the same as the ES5 version with the following additions:

There is an additional parserOptions block that enables ES2015 rules:

  "parserOptions": {
   "ecmaVersion": 6,
   "sourceType": "module"
 }

There are some additional rules for ES2015 syntax.

Our use of arrow-parens allows for single line arrow functions like n => { n * 2 } but requires parameter parentheses when the function body spans multiple lines.

    "arrow-parens": [2, "as-needed", { "requireForBlockBody": true }],
   "arrow-spacing": 2,
   "no-confusing-arrow": 2,
   "prefer-rest-params": 2,
   "prefer-spread": 2,
   "rest-spread-spacing": 2

Happy Linting!

How else does your team ensure code quality? Have you run into challenges with linting before, or do you have questions about getting started? I’d love to hear from youcomment below!

Like what you just read? Share it!

Ben Gladwell

About Ben Gladwell

Ben is the Director of Technology at Adept Marketing. With a background in front-end and back-end development, full stack development and network and systems administration, he capably leads the evolution of technology within an aggressively-growing digital agency. He prides himself on being a generalist and a problem solver.