Code Linting refers to using the magic powers of static analysis to find potentially erroneous, inconsistent, or otherwise undesirable (whatever that means to you) bits of code in a program. Linting is useful because it can:
From idiomatic.js, a popular style guide:
All code in any code-base should look like a single person typed it, no matter how many people contributed.
Imagine how close to this goal a project can get if every developer just uses a linter configured in the same way.
The magic powers of static analysis are harnessed by magic tools which do linting for you. This magic has become more powerful over time. A brief history:
First, there was JSLint, which:
Recall: "undesirable (whatever that means to you)".
Neither did some other people. One guy called JSLint:
a tool that makes sure you write your code like Douglas Crockford
after he forked JSLint, added magic, and called it JSHint.
JSHint covers most use cases, but it can't possibly cover them all out of the box. So another guy came along and added even more magic. Enter, ESLint.
Recall: "undesirable (whatever that means to you)".
If we just want to configure and use ESLint, we can just:
npm install -g eslint
But to write our own rules, we'll need to:
git clone git://github.com/eslint/eslint.git
cd eslint
npm install
npm test
npm install -g yo
npm install -g generator-eslint
First, you need to write a .eslintrc
. We could read the docs and write our own, but I've already done that, so let's take a look at it.
Then we can run ESLint on an example file:
eslint examples/horrible.js
Look at all of those bad practices that it caught!
Let's try to fix them.
First, let's look at some rules that ESLint provides. Namely, no-space-before-semi
and func-style
.
Nothing crazy yet; let's make a rule. Normally we'd go:
yo eslint:rule
but for this talk's environment, we'll just copy rules/template.js
and start from there.
The context
has report
and some source-level stuff:
var source = context.getSource(); // full source
var nodeSource = context.getSource(node); // just this piece
// three characters after this piece
var justFollowingThree = context.getSource(node, 0, 3);
// three characters before this piece
var justPreviousThree = context.getSource(node, 3);
and each function receives a node
argument when invoked, whose properties vary from type to type. Example: Identifier
nodes will give us node.name
.
Yep. I already made some config files to help out, so we'll just need to point ESLint at all the right places:
eslint --reset --eslintrc=false --rulesdir rules
-c configs/curly-eslint.json examples/one.js
That will run just our one new rule against one.js
. Then we can run it against two.js
and three.js
and even horrible.js
, if we're so inclined.
Sure. Let's take a more generous interpretation of
"undesirable (whatever that means to you)"
this time. We'll call our rule four.js
.
Of course. Let's make sure none of these pesky variable names are too long for our taste. Run:
eslint --reset --eslintrc=false --rulesdir rules
-c configs/four-eslint.json examples/one.js
and then on two.js
and three.js
and horrible.js
if we want.
You bet:
eslint --reset --eslintrc=false --rulesdir rules
-c configs/both-eslint.json examples/one.js
and then on two.js
and three.js
, of course.
Well, as you saw, sometimes simple things aren't quite so simple. There can be multiple ways to enforce a particular rule, and enforcing some is harder than enforcing others. Let's look at these rule files:
yoda
camelcase
block-scoped-var
The ones we looked at before were all easy cases, but some ESLint rules have quite a bit of their own magic.
In this talk, I've used the word Magic, roughly, as a replacement for static code analysis.
ESLint has some of its own magic contained in its rules, generally more complex than the ones we just wrote.
It's built on the magic powers of Esprima, a parser which turns JS into Abstract Syntax Trees according to the subject of Michael's talk, the SpiderMonkey Parser API.
Esprima was made by Shape's own Ariya Hidayat.
Surprisingly, Ariya has not written any JavaScript books.
He did make PhantomJS, though.
Cleaver, a nice JS tool which turns a simple Markdown file of your talk into a single HTML file of your slides.
They're already available on my GitHub: http://github.com/LewisJEllis/eslint101
Other relevant links: