ESLint

ESLint is a popular linter for JavaScript. The ESLint integration also uses Prettier to enforce code formatting.

Run Locally

The mozlint integration of ESLint can be run using mach:

$ mach lint --linter eslint <file paths>

Alternatively, omit the --linter eslint and run all configured linters, which will include ESLint.

ESLint also supports the --fix option to autofix most errors raised from most of the rules.

See the Usage guide for more options.

Custom Configurations

Our ESLint configuration has a number of custom configurations that define globals and rules for various code based on the pattern file path and names.

Using the correct patterns helps ESLint to know about the correct details, so that you don’t get warnings about undefined or unused variables.

  • .mjs - A module file.

  • .sys.mjs - A system module, this is typically a singleton in the process it is loaded into.

  • .worker.(m)js - A file that is a web worker.

    • Workers that use ctypes should use /* eslint-env mozilla/chrome-worker */

  • Test files, see the section on adding tests

Understanding Rules and Errors

Enabling new rules and adding plugins

Please see this page for enabling new rules.

Common Issues and How To Solve Them

My editor says that mozilla/whatever is unknown

  • Run ./mach eslint --setup, and restart your editor.

My editor doesn’t understand a new global I’ve just added (e.g. to a content file or head.js file)

  • This is a limitation which is a mixture of our ESLint setup and how we share globals across files.

  • Restarting your editor should pick up the new globals.

  • You can always double check via ./mach lint --linter eslint <file path> on the command line.

I am getting a linter error “Unknown Services member property”

Make sure to add any new Services to tools/lint/eslint/eslint-plugin-mozilla/lib/services.json. For example by copying from <objdir>/xpcom/components/services.json after a build.

I’m adding tests, how do I set up the right configuration?

Please note we prefer the tests to be in named directories as this makes it easier to identify the types of tests developers are working with. Additionally, it is not possible to scope ESLint rules to individual files based on .ini files without a build step that would break editors, or an expensive loading cycle.

  • If the directory path of the tests is one of the known ones, then ESLint will do the right thing for that test type. This is the preferred option.

    • For example placing xpcshell-tests in browser/components/foo/test/unit/ will set up ESLint correctly.

  • If you really can’t match the directory name, e.g. like the browser/base/content/tests/*, then you’ll need to add a new entry in .eslintrc-test-paths.js.

Please do not add new cases of multiple types of tests within a single directory, this is difficult for ESLint to handle. Currently this may cause:

  • Rules to be incorrectly applied to the wrong types of test file.

  • Extra definitions for globals in tests which means that the no undefined variables rule does not get triggered in some cases.

This code should neither be linted nor formatted

This code shouldn’t be formatted

The vast majority of code should be formatted, however we allow some limited cases where it makes sense, for example:

  • A table in an array where laying it out in a table fashion makes it more readable.

  • Other structures or function calls where layout is more readable in a particular format.

To disable prettier for code like this, // prettier-ignore may be used on the line previous to where you want it disabled. See the prettier ignore docs for more information.

I have valid code that is failing the no-undef rule or can’t be parsed

  • Please do not add this to .eslintignore. Generally this can be fixed, if the following tips don’t help, please seek help.

  • If you are adding a new test directory, see the section above

  • If you are writing a script loaded into special environment (e.g. frame script) you may need to tell ESLint to use the environment definitions for each case:

    • /* eslint-env mozilla/frame-script */

  • I use Services.scriptloader.loadSubScript:

    • /* import-globals-from relative/path/to/file.js

Configuration

The global configuration file lives in topsrcdir/.eslintrc. This global configuration can be overridden by including an .eslintrc in the appropriate subdirectory. For an overview of the supported configuration, see ESLint’s documentation.

Please keep differences in rules across the tree to a minimum. We want to be consistent to make it easier for developers.

Sources

Builders

Mark Banner (standard8) owns the builders. Questions can also be asked on #lint:mozilla.org on Matrix.

ESLint (ES)

This is a tier-1 task. For test failures the patch causing the issue should be backed out or the issue fixed.

Some failures can be fixed with ./mach eslint --fix path/to/file.

For test harness issues, file bugs in Developer Infrastructure :: Lint and Formatting.

ESLint-build (ES-B)

This is a tier-2 task that is run once a day at midnight UTC via a cron job.

It currently runs the ESLint rules plus two additional rules:

These are two rules that both require build artifacts.

To run them manually, you can run:

MOZ_OBJDIR=objdir-ff-opt ./mach eslint --rule "mozilla/valid-ci-uses: error" --rule "mozilla/valid-services-property: error" *

For test failures, the regression causing bug may be able to be found by:

  • Determining if the file where the error is reported has been changed recently.

  • Seeing if an associated .idl file has been changed.

If no regressing bug can easily be found, file a bug in the relevant product/component for the file where the failure is and cc :standard8.

For test harness issues, file bugs in Developer Infrastructure :: Lint and Formatting.