Configure Visual Studio Code to Lint React and JSX Syntax

by
Tags: , , , , ,

Around here a few of us are really starting to dig working with Visual Studio Code for our JavaScript development. As part of some updates to our React and Friends course, we began looking at tooling again, with an eye toward making it easy for the beginner in React to find syntax errors in JSX code.

Linting ECMAScript Code with ESLint

Linting, i.e. syntax checking of source code, has been around forever. Linters were originally created when compilation tasks took minutes or hours, as a way to run the syntax checking up front. Eventually interpreted languages came to the fore, and linters became useful tools in build processes, able to spot errors that would normally be caught only at runtime, in the browser.

One of the more popular linters for JavaScript is ESLint. It can be installed in an npm project with:

npm install --save-dev eslint

Linting rules are defined via a configuration file, .eslintrc.js (the file can also be formatted using YAML or JSON). This can be created (and plugins configured) using:

# Windows:
node_modules\.bin\eslint --init
# OS X/Linux:
./node_modules/.bin/eslint --init

ESLint then asks several questions. An example interaction:

? How would you like to configure ESLint?
(picked: Answer questions about your style)
? Are you using ECMAScript 6 features? Yes
? Are you using ES6 modules? Yes
? Where will your code run? Browser
? Do you use CommonJS? No
? Do you use JSX? Yes
? Do you use React? Yes
? What style of indentation do you use? Spaces
? What quotes do you use for strings? Single
? What line endings do you use? Unix
? Do you require semicolons? Yes
? What format do you want your config file to be in? JavaScript
Local ESLint installation not found.
Installing eslint, eslint-plugin-react

Now you can lint your code. Given this suitably horrible fragment of JavaScript:

x = 234
var q = 9
console.log("this is realy cool");
for (var q = 1; q < 300; q++) {
  console.log(q+1);
}

We can execute the linter against it like this:

# Linux, Mac OS X syntax:
./node_modules/.bin/eslint badcode.js
# Winderz
node_modules\.bin\eslint badcode.js

…which outputs something kind of like this (your errors may vary based on how you edited the file and what you did with the .eslintrc.js config file:

C:\Users\kenri\projects\foobarbazreact\badcode.js
  1:1   warning  'x' is not defined            no-undef
  3:1   error    Unexpected console statement  no-console
  4:10  error    'q' is already defined        no-redeclare
  5:3   error    Unexpected console statement  no-console
✖ 4 problems (3 errors, 1 warning)

Installing ESLint in your NPM Build

This is the fun part. If you open up your project's package.json file, and add the following item to your scripts section, you can issue a npm run-script lint command (mine is from a project created with Create React App, a great React starter utility):

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "lint": "eslint src"   <--- add this
  }

Customizing ESLint for React and create-react-app

There are a number of eslint plugins out there, and several are really useful for a project created with the create-react-app starter. Let's install them (if you used eslint --init you might have the react plugin):

npm install --save-dev eslint-plugin-react
npm install --save-dev eslint-plugin-mocha

Now, here's a configuration file (.eslintrc.json in this case) that configures my IDE for the common settings we'd need in a typical ES6+ React application:

{
    "env": {
        "browser": true,
        "commonjs": true,
        "es6": true,
        "mocha": true,
        "node": false
    },
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "sourceType": "module"
    },
    "plugins": [
        "react"
    ],
    "rules": {
        "no-const-assign": "warn",
        "no-this-before-super": "warn",
        "no-undef": "warn",
        "no-unreachable": "warn",
        "no-unused-vars": "warn",
        "constructor-super": "warn",
        "valid-typeof": "warn"
    },
    "extends": ["eslint:recommended", "plugin:react/recommended"]
}

Enabling ESLint in Visual Studio Code

Now for the final step: installing ESLint support in Visual Studio Code. Use the Extensions icon (the concentric squares) on the left-hand side of the interface to visit the extensions page. I've installed these extensions on my machine:

  • ESLint by Dirk Baeumer, which enables running of ESLint. For this to work, you need to make sure your ESLint library and plugins are installed with npm install as above; once you do this the tool will stop complaining. Resist the urge to install the plugin globally: you should be able to keep the entire configuration local to the project.
  • Code Runner by Jun Han. Very cool little tool that lets you run any code you put in selection (within reason) using CTRL-ALT-M.
  • VIM emulation plugin. VIM emulation for VS Code is the best I've seen.

Happy bug hunting!