What’s next for ESLint on Firefox Source Code?


Around 2015 a couple of projects had started using ESLint in mozilla-central. In the last quarter of 2015, there was a big push to enable ESLint for browser/ and toolkit/ – the two main directories containing the javascript source behind Firefox.

Since then, we have come a long way. We have commands and hooks for developers to use, checks during the review phase, and automatic tests that run against our review tools and our continuous integration branches. Not only that, but we’ve also expanded our coverage to more directories, and expanded the amount of rules that are enabled.

As we’ve done this work, we’ve caught lots of bugs in the code or in our tests (there’s much more than just those links). Some of those have been small, some have been user facing issues. There are also now the countless potential bugs that we don’t get to see where ESLint catches issues for us before they even hit the core source trees. All this helps to save developer time and leaves more for fixing bugs and implementing new features.

Where to next?

There are several things high on the list that we should have as the next, future goals:

  1. Finish enabling ESLint on all our JavaScript code in mozilla-central

We are already covering the vast majority of production code in mozilla-central, however there are still a lot of unit tests that aren’t covered. Increasing linting coverage here will help to ensure these are functioning as we expect.

There’s always a few things it won’t make sense for, e.g. third-party imports, or the occasional piece of preprocessed code, but I think we should strive towards 100% coverage where we sensibly can.

  1. Harmonize our rules

Whilst we have a core set of rules, various directories are overriding and extending the rules. We should aim for having the majority of rules being the same everywhere, with additional rules being only occasional (e.g. experimental).

This will make it far easier for developers working across modules to be able to work in a consistent style, and help spread the useful rules across the tree.

Example rules that fall into this category: mozilla/var-only-at-top-level, block-scoped-var, no-shadow, no-throw-literal, no-unused-expressions, yoda

  1. Improve developer tools

For me, I find most use for ESLint when it is integrated into my editor. However, there’s various other occasions where we’re not doing quite enough to make it easy for developers, e.g. automatically installing hooks, or setting up editor support automatically.

These help developers to catch issues earlier whilst the developer is still focussed on the patch, reducing context switching. We should be getting these working as seamlessly as possible.

  1. Improve automatic fixing

Currently the automatic fixing doesn’t work fully if you run it across the whole tree (you can run it in segments), we should fix it to help make applying new rules globally a lot easier.

We need your help!

  • Find a problem with ESLint that is stopping you using it efficiently? Please file a bug. Alternately, come talk to me about issues that are slowing you down or getting in the way.
  • Reasonably regularly I file mentored bugs for enabling new directories or rules, which are great to get you started. However, if you’re interested in working with me on getting larger chunks going, please let me know (in the comments or ping Standard8 on IRC).
  • Anything I’ve missed or discussions points? Please add a comment.

Thank you

I’d like to say a big thank you to all those that have helped bring ESLint to where it is today. Special thanks go to Dave Townsend for his encouragement and many reviews.

There’s many more people that have been involved from the various teams that work on Firefox, as well as first-time contributors – too many to name, so thank you all!

Running ESLint on commit for mozilla-central (Git & Mercurial)

A while ago, Dave Townsend wrote a commit hook for Mercurial for ESLint. I’ve just extended the code to create a commit hook for Git users.

To install the Git hook, go into the top-level of your mozilla-central Git repository, and enter (assuming you don’t already have a pre-commit hook):

ln -s ../../tools/git/git-lint-commit-hook.sh .git/hooks/pre-commit

That’s all you need to do. If you do have an existing pre-commit hook, then you’ll need to incorporate running git-lint-commit-hook.sh as well.

This will run ESLint on the affected files when committing and print warnings if they fail. The commit will still happen, but you should fix the issues up before pushing them for review.

Coming soon:

Using eslint alongside the Firefox Hello code base to help productivity

On Firefox Hello, we recently added the eslint linter to be run against the Hello code base. We started of with a minimal set of rules, just enough to get us something running. Now we’re working on enabling more rules.

Since we enabled it, I feel like I’m able to iterate faster on patches. For example, if just as I finish typing I see something like:

eslint syntax error in sublime I know almost immediately that I’ve forgotten a closing bracket and I don’t have to run anything to find out – less run-edit-run cycles.

Now I think about it, I’m realising it has also helped reduced the amount of review nits on my patches – due to trivial formatting mistakes being caught automatically, e.g. trailing white-space or missing semi-colons.

Talking about reviews, as we’re running eslint on the Hello code, we just have to apply the patch, and run our tests, and we automatically get eslint output:

eslint output - no trailing spacesHopefully our patch authors will be running eslint before uploading the patch anyway, but this is an additional test, and a few less things that we need to look at during review which helps speed up that cycle as well.

I’ve also put together a global config file for eslint (see below), that I use for outside of the Hello code, on the rest of the Firefox code base (and other projects). This is enough, that, when using it in my editor it gives me a reasonable amount of information about bad syntax, without complaining about everything.

I would definitely recommend giving it a try. My patches feel faster overall, and my test runs are for testing, not stupid-mistake catching!

Want more specific details about the setup and advantages? Read on…

My Setup

For my setup, I’ve recently switched to using Sublime. I used to use Aquamacs (an emacs variant), but when eslint came along, the UI for real-time linting within emacs didn’t really seem great.

I use sublime with the SublimeLinter and SublimeLinter-contrib-eslint packages. I’m told other editors have eslint integration as well, but I’ve not looked at any of them.

You need to have eslint installed globally, or at least in your path, other than that, just follow the installation instructions given on the SublimeLinter page.

One configuration I change I did have to make to the global configuration:

  • Open up a normal javascript (*.js) file.
  • Select “Preferences” -> “Settings – More” -> “Syntax Specific – User”
  • In the file that appears, set the configuration up as follows (or whatever suits you):

This makes sure sublime treats the .jsm and .jsx files as javascript files, which amongst other things turns on eslint for those files.

Global Configuration

I’ve uploaded my global configuration to a gist, if it changes I’ll update it there. It isn’t intended to catch everything – there’s too many inconsistencies across the code base for that to be sensible at the moment. However, it does at least allow general syntax issues to be highlighted for most files – which is obviously useful in itself.

I haven’t yet tried running it across the whole code base via eslint on the command line – there seems to be some sort of configuration issue that is messing it up and I’ve not tracked it down yet.

Firefox Hello’s Configuration

The configuration files for Hello can be found in the mozilla-central source. There’s a few of these because we have both content and chrome code, and some of the content code is shared with a website that can be viewed by most browsers, and hence isn’t currently able to use all the es6 features, whereas the chrome code can. This is another thing that eslint is good for enforcing.

Our eslint configuration is evolving at the moment, as we enable more rules, which we’re tracking in this bug.

Any Questions?

Feel free to ask any questions about eslint or the setup in the comments, or come and visit us in #loop on irc.mozilla.org (IRC info here).