ESLint is a popular linting utility for JavaScript. In this post I’ll show you how I use it in a Ruby on Rails app.
A quick intro to ESLint
ESLint lets you specify how you want to style your JavaScript and it will then check your code and report any issues. For example, if you use the quotes rule to specify that you want to use single quotes everywhere, ESLint will check whether that’s true and report back anywhere you accidentally used double quotes.
Whether you’re a part of a team or working on a project by yourself, ESLint is a great way to ensure clean, consistent code and identify bugs before they ever make their way into production.
The ESLint Gem
Jon Kessler and Justin Force created a handy ESLint gem for Rails. You simplify create a configuration file in config/eslint.json
, execute rake eslint:run
, and it will check your application.js
file for any issues.
If you’re looking for a solid eslint config file, check out the one we at Automattic use for Calypso.
Customing the workflow
I wound up customizing how I use the the gem for two reasons:
- The gem checks
application.js
which concatenates all of your JavaScript assets based on the manifest file. If your assets include third party scripts like jQuery, ESLint will wind up linting those as well which you probably don’t care about. - Similarly, because all of your JavaScript files are concatenated in
application.js
, the line numbers that ESLint spits out in its report don’t correspond to the line numbers in the individual files, making it difficult to pinpoint the offending lines of code.
To account for this, I first moved all of the third party JavaScript files out of app/assets/javascripts
and into app/assets/javascripts/lib
. With them moved out of the javascripts
directory, I then wrote a new Rake task that takes advantage of the gem’s ability to lint a single file:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace :lint do | |
task run: :environment do | |
js_dir = "#{Rails.root}/app/assets/javascripts" | |
Dir.chdir(js_dir) | |
# No directories and no application.js | |
files = Dir.glob('*').delete_if{ |f| File.directory?(f) || f == 'application.js' } | |
files.each do |file| | |
puts file | |
# There is a likely way to do this with Rake::Task's `invoke` and `reenable` methods | |
# but I couldn't figure out how to get it to check more than the first file. | |
puts `rake eslint:run[#{js_dir}/#{file}]` | |
end | |
end | |
end |
With this in place, you can run rake lint:run
and it will iterate over each of your JavaScript files within the javascripts
directory and execute ESLint on each one:
$ rake lint:run account.js 48:5 low indent Expected indentation of 3 tab chrs but found 4 49:5 low indent Expected indentation of 3 tab chrs but found 4 50:5 low indent Expected indentation of 3 tab chrs but found 4 interface.js 612:3 slow quote-props Unnecessarily quoted property `class` found 613:28 low quote-props Unnecessarily quoted property `class` found 915:1 low valid-jsdoc Missing JSDoc parameter type for 'reason'
If you also use ESLint in your Rails project, I’d love to hear more about your setup.