E24: Improve code quality using ESLint in IntelliJ

Motivation

One of the most important steps you can take to improve the quality of your code is to use a quality assurance tool appropriate for your programming language that enforces basic coding standards.

In the case of Javascript, the emerging consensus is ESLint as it is extensible and supports the latest versions of Javascript.

For our class, ESLint is good because there is a configuration file for the AirBnb Javascript Style Guide, and because there is support for ESLint in IntelliJ IDEA.

Installation

1. Install NodeJS and NPM

To begin, you must install NodeJS following the instructions for your OS at https://nodejs.org/en/. You should install the “LTS” version. When completed, verify that the installation was successful by running the node and npm commands in a console:

[~]-> node --version
v6.11.2                   // (or later)
[~]-> npm --version
4.6.1                    // (or later)
[~]->

2. Install ESLint

Now that you have node and npm installed, you can install ESLint. You should install it globally using npm install -g eslint. On a Mac, you need to preface this command with sudo because it needs write access to the /usr/local/lib directory:

[~]-> sudo npm install -g eslint
Password:
/usr/local/bin/eslint -> /usr/local/lib/node_modules/eslint/bin/eslint.js
eslint@3.2.2 /usr/local/lib/node_modules/eslint
├── ignore@3.1.3
├── imurmurhash@0.1.4
├── estraverse@4.2.0
├── strip-bom@3.0.0
├── pluralize@1.2.1
├── path-is-inside@1.0.1
├── globals@9.9.0
├── strip-json-comments@1.0.4
├── esutils@2.0.2
├── progress@1.1.8
├── text-table@0.2.0
├── user-home@2.0.0 (os-homedir@1.0.1)
├── is-resolvable@1.0.0 (tryit@1.0.2)
├── debug@2.2.0 (ms@0.7.1)
├── doctrine@1.2.2 (esutils@1.1.6, isarray@1.0.0)
├── levn@0.3.0 (type-check@0.3.2, prelude-ls@1.1.2)
├── optionator@0.8.1 (fast-levenshtein@1.1.4, type-check@0.3.2, wordwrap@1.0.0, deep-is@0.1.3, prelude-ls@1.1.2)
├── json-stable-stringify@1.0.1 (jsonify@0.0.0)
├── chalk@1.1.3 (escape-string-regexp@1.0.5, supports-color@2.0.0, ansi-styles@2.2.1, strip-ansi@3.0.1, has-ansi@2.0.0)
├── require-uncached@1.0.2 (resolve-from@1.0.1, caller-path@0.1.0)
├── shelljs@0.6.0
├── mkdirp@0.5.1 (minimist@0.0.8)
├── concat-stream@1.5.1 (inherits@2.0.1, typedarray@0.0.6, readable-stream@2.0.6)
├── glob@7.0.5 (path-is-absolute@1.0.0, fs.realpath@1.0.0, inherits@2.0.1, once@1.3.3, inflight@1.0.5, minimatch@3.0.2)
├── espree@3.1.7 (acorn-jsx@3.0.1, acorn@3.3.0)
├── is-my-json-valid@2.13.1 (jsonpointer@2.0.0, generate-function@2.0.0, xtend@4.0.1, generate-object-property@1.2.0)
├── inquirer@0.12.0 (strip-ansi@3.0.1, ansi-regex@2.0.0, ansi-escapes@1.4.0, rx-lite@3.1.2, through@2.3.8, cli-width@2.1.0, figures@1.7.0, run-async@0.1.0, readline2@1.0.1, string-width@1.0.1, cli-cursor@1.0.2)
├── js-yaml@3.6.1 (esprima@2.7.2, argparse@1.0.7)
├── table@3.7.8 (slice-ansi@0.0.4, tv4@1.2.7, xregexp@3.1.1, strip-ansi@3.0.1, string-width@1.0.1, bluebird@3.4.1)
├── file-entry-cache@1.3.1 (object-assign@4.1.0, flat-cache@1.2.1)
├── lodash@4.14.1
└── escope@3.6.0 (esrecurse@4.1.0, es6-map@0.1.4, es6-weak-map@2.0.1)

You can ignore any “npm WARN” messages. If you get “npm ERROR”, that’s a problem that needs to be solved.

We also need eslint-plugin-import, so run npm install -g eslint-plugin-import to install it. (As before, on a Mac, this command must be preceded by sudo):

[~]-> sudo npm install -g eslint-plugin-import
npm WARN peerDependencies The peer dependency eslint@2.x - 3.x included from eslint-plugin-import will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
eslint-plugin-import@1.12.0 /usr/local/lib/node_modules/eslint-plugin-import
├── object-assign@4.1.0
├── lodash.endswith@4.2.0
├── contains-path@0.1.0
├── lodash.findindex@4.5.1
├── lodash.cond@4.5.1
├── lodash.find@4.5.1
├── builtin-modules@1.1.1
├── doctrine@1.2.2 (esutils@1.1.6, isarray@1.0.0)
├── debug@2.2.0 (ms@0.7.1)
├── eslint-import-resolver-node@0.2.2 (resolve@1.1.7)
├── pkg-dir@1.0.0 (find-up@1.1.2)
├── pkg-up@1.0.0 (find-up@1.1.2)
├── es6-set@0.1.4 (d@0.1.1, es6-symbol@3.1.0, event-emitter@0.3.4, es6-iterator@2.0.0, es5-ext@0.10.12)
└── es6-map@0.1.4 (d@0.1.1, es6-symbol@3.1.0, event-emitter@0.3.4, es6-iterator@2.0.0, es5-ext@0.10.12)

Again, you can ignore any “npm WARN” messages. If you get “npm ERROR”, that’s a problem that needs to be solved.

3. Install AirBnB Javascript Style Guide configuration rules

Now that we’ve installed ESLint along with the ability to import plugins, let’s install a plugin that configures ESLint to enforce the AirBnB style guide for “basic” ES6 code. Use npm install -g eslint-config-airbnb-base (adding sudo on a mac):

[~]-> sudo npm install -g eslint-config-airbnb-base
Password:
npm WARN peerDependencies The peer dependency eslint@^3.2.0 included from eslint-config-airbnb-base will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
npm WARN peerDependencies The peer dependency eslint-plugin-import@^1.12.0 included from eslint-config-airbnb-base will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
eslint-config-airbnb-base@5.0.1 /usr/local/lib/node_modules/eslint-config-airbnb-base

Again, you can ignore any “npm WARN” messages. If you get “npm ERROR”, that’s a problem that needs to be solved.

Note that the AirBnB Style Guide package provides other plugins to enforce code style for React, JSX, and other Javascript libraries, but we don’t need these at this point. So we only install the “base” package.

4. Set up IntelliJ to use Node

Now that our global environment supports ESLint and the AirBnB Javascript Style Guidelines, we want to integrate this into IntelliJ. To do this:

First, activate the NodeJS plugin. Go to Preferences > Plugins, then click on the “Browse Repositories” button, then type “NodeJS” into the search box. You should find the following plugin to install:

Click “install” to install it. IntelliJ will replace the “Install” button with a “Restart IntelliJ” button, which you should click to restart IntelliJ.

5. Configure default settings for Javascript and ESLint

To simplify future Javascript project definition, it is helpful to configure some default settings. You do this configuration by bringing up a dialog box found in File > Other settings … > Default Settings.

Once that dialog box appears, go to Languages and Frameworks > Javascript > Code Quality Tools > ESLint, and click the checkbox to enable ESLint. Also add --quiet to “Extra ESLint options”. The --quiet flag tells IntelliJ to show only ESLint errors and to suppress warnings. The Default preferences window should look now like this:

Second, for this class, ESLint is the only tool you need to use for automated coding standard compliance checking. However, IntelliJ enables other compliance checkers by default. This means that even if you have eliminated all of the problems detected by ESLint from your code, you might get a yellow box in the upper right corner rather than the green arrow. A yellow box in the upper right corner indicates that another IntelliJ inspector has signalled a “warning”.

For this class, your code only needs to be compliant with ESLint, so it’s helpful to disable these other inspectors. To do this, go to File > Other Settings … > Default Settings as before, and then go to Editor > Inspections. Then select the Javascript language and uncheck all inspectors except for ESLint. When you’re done, only ESLint errors will be enabled for all future Javascript projects that you create:

6. Test your installation

Create a new IntelliJ project where the project directory is the one you created for the Hello Javascript experience. IntelliJ will ask you if you want to overwrite the previous IntelliJ project files. Let IntelliJ do that. By recreating the project, your project definitions will now inherit from the defaults that you specified above.

Next, download sample.eslintrc, move it into your HelloJavascript project directory, and rename it to .eslintrc. If successful, you should see it displayed in your Project pane within IntelliJ and be able to view it:

This .eslintrc file specifies that ESLint should use the AirBnB code style, with the exception that the maximum line length is 120 and that console logging is OK.

Once you’ve done that, IntelliJ should now be running ESLint in the background on your Javascript files and displaying any errors as red lines in the right margin. For example, this is what my HelloJavascript.js file looks like with ESLint enabled and the cursor over the red line:

As you can see, the use of double quotes violates the AirBnB standards and is thus an “error”. If I change them to single quotes, the red bar disappears and a green checkmark appears to indicate that no code style problems can be found in the file:

7. Troubleshooting

Make sure that the absolute path to your source code does not include a directory with a space in its name. For example, “Users/philipjohnson/Amazon Files/ics314/test/foo.js” will lead to a problem loading ESLint, because of the directory named “Amazon Files”.

Submission instructions

You do not have to submit anything for this experience. However, your ability to install ESLint and use it to remove warnings will be evaluated in subsequence experiences, so be sure to complete this experience successfully!