Lint Like It’s 2015
If you write ES6 with Babel but JSHint holds you back, I have good news!
I’m a static analysis person. I come from C# and I trust my tools to understand what I write and let me type absent-mindedly.
However, as my build workflow got more sophisticated, I had a falling-out with JSHint.
In early 2015, I switched from React’s JSX compiler to Babel in order to use ES6 (and some ES7) syntax freely. It’s a tad slower but …rest assured, it’s the future. I never regretted switching to Babel for a moment, and I only have the highest praise for its authors and contributors. My only pain was getting Babel code to lint.
See, JSXHint works by taking JSX sources, running them through React’s JSX transformer, and then feeding the result to JSHint. Not only was this slow due to the code being parsed twice, but I also could not use any Babel features that weren’t also supported by React’s JSX transformer. Doesn’t this defeat the purpose of adding Babel in the first place?
To be fair, JSXHint has a special mode that uses Babel’s transformer instead of React’s. Still, I found it unusable because Babel often generates additional lines for readable generated code but JSXHint doesn’t know how to preserve the line numbers, so they’re wildly off.
If you haven’t heard of it, ESLint is the linter I always wanted JSHint to be. It’s smarter than JSHint, it’s completely customizable with custom linting rules and it doesn’t purposefully annoy you. Every warning and error also comes with the exact option you need to write into the configuration file to turn it off (or at least tone it down).
So ESLint is clearly what you want as a linter in 2015. It can even do JSX! Sadly it doesn’t support full ES6 quite yet. Are we going to live in the linter hell for a few more months?
Sebastian McKenzie, creator of Babel, wrote babel-eslint. Did you know that ESLint supports pluggable parsers? I didn’t. Well, turns out that it does, and Sebastian found a way to make ESLint parse (and lint) all valid Babel code.
It’s just been released and has two or three bugs on my codebase, but I’m sure they will be fixed soon. I already switched to the new tool and suggest you do the same!
Follow these steps to integrate Babel and ESLint-powered ES6 linting into Sublime Text 3 or your build pipeline.
An Important Disclaimer
Only do this if you don’t mind a few false flags while the bugs are being fixed. On my 700-something module codebase, I have about 20 invalid flags caused by 4 babel-eslint bugs. I reported them all and fully expect them to be fixed soon! Since I don’t run hinting as a build step, this doesn’t affect my productivity, but you may want to wait out a little bit.
Installing eslint and babel-eslint
Start by creating a file called .eslintrc in the root of your project. It might look like this:
// I want to use babel-eslint for parsing!
// I write for browser
// in CommonJS
// To give you an idea how to override rule options:
"quotes": [2, "single"],
Saved it? Good.
Install eslint and babel-eslint NPM packages locally to your project. (Yes, an earlier version of this tutorial said “globally” but local installation works for me now, and it’s a way better idea.) Having different versions of global and local eslint will only confuse you so I suggest you uninstall global eslint if you have one.
npm uninstall -g eslint # uninstall the global if you have it
npm install --save-dev eslint@latest
npm install --save-dev babel-eslint@latest
Make sure you can run the local eslint:
It should output a version (mine says 0.20.0). Note that local eslint won’t work if it can’t find babel-eslint next to it in your node_modules.
Running ./node_modules/.bin/eslint src (or whatever your source directory is) now should parse your sources with Babel. It would be a good idea to alias this as npm run lint by putting this into your package.json:
"lint": "eslint src"
If you don’t use Sublime, you should be all set.
If you do, read on!
If you started reading from this section because you have already set up ESLint before, make sure it’s installed globally and available in PATH. Still better, do read the previous section, it will save you configuration woes.
Install SublimeLinter package via Package Control. This guide has you covered. SublimeLinter is a generic package, it works with many languages and doesn’t include any specific linter. You’ll need to also install SublimeLinter-contrib-eslint via Package Control. See this guide. If you already have it, make sure to update to a recent version.
I don’t like the default color schemes in babel-sublime so I suggest you install and use oceanic-next-theme which is neat and optimized for it.
To do this, choose SublimeLinter Settings — User in command menu:
Here’s how you add it to syntax_map:
Boom! Done! Restart Sublime and open a JS(X) file. Write some nonsense on purpose. Hit “Save”.
Depending on your SublimeLinter configuration, it will be linted immediately, while editing or on save.
You can configure this by using Choose Lint Mode command:
Happy linting in 2015!
If You Use React Too…
Make sure you use include some rules from eslint-plugin-react! Some of them help ESLint understand the semantics of React JSX usage, and others are just nice additional static checks specifically for React code.
- babel-eslint (report an issue)
Follow Dan Abramov on Twitter