question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

First-class support for project-specific linting rules

See original GitHub issue

This issue is a continuation of #2715. See that issue for more context.

tl;dr: The current proposal is to topLevelOptions property to a config file only available in the project-level config (not shareable/extended configs). Allow rulesDir to be specified there.

Version

This problem is not solved as of 4.0.0.

The problem

Many projects have their own unique conventions, ESLint and Node included. From comments in the previous issue, Facebook and Taskworld also have project-specific ESLint rules. The --rulesdir command-line argument and rulePaths APIs can be used to tell ESLint to look for rules in additional directories. Both Node and ESLint puts this configuration in their Makefiles.

Here comes the problem: Many people use ESLint integration for their text editors (e.g. Sublime Text, Atom). These plugins don’t read Makefiles; they assumed the project can be linted by running eslint in the project directory without passing extra command line arguments or API options.

Even if these editor plugins can be configured to add CLI arguments, they will be applied at global level instead of project-specific level. And these configurations are local to each text editor.

This brings the need for standardized way to include project-specific linting rules that will get picked up by all tools that integrate with ESLint.

Existing workarounds

Create an ESLint plugin

This is the approach previously suggested by ESLint maintainers—by creating ESLint plugins and including it in the project. ESLint requires plugins to be in node_modules folder. There are several drawbacks to this:

  • Publishing the plugins to npm: It is cumbersome to update the rules in tandem with the codebase. I would have to go to the plugin, test the rule, and publish a new version to npm. The main project needs to point the plugin to the new version. Finally, each developer needs to run npm install again to make sure their plugin is at the latest version.
  • Putting the plugin in the project and use npm link. This makes it cumbersome for developers to prepare the project for development. They would have to run npm install inside the plugin folder in addition to the main project folder, and run npm link afterwards. If the plugin’s dependencies are updated, they need to run npm install inside the plugin folder again.
  • Specifying relative folders in package.json. This makes it very cumbersome to update plugins, as both npm@3 and yarn@0.24 will say “Already up-to-date” when running yarn after changing the rules. I need to run rm -rf node_modules/eslint-plugin-proprietary before running yarn again.

Clearly, using ESLint plugin is more suitable for ESLint rules that are maintained separately. But it is unwieldy for rules that are project-specific.

Here’s how a suitable solution must look like:

  • The rules are part of the project. The linting rules are version-controlled along with project’s code and is updated in lockstep.
  • They work out-of-the-box with the CLI and all text editor integrations.
  • They are ready to use after a single npm install command on the project directory.
  • They can updated by git pull without requiring any extra step.

Hacking ESLint internals to load extra rules from .eslintrc.js

Accroding to @zertosh, Facebook uses this approach:

// .eslintrc.js
const Rules = require('eslint/lib/rules');
Rules.load(path.join(__dirname, 'resources/eslint-rules'));

Hacking Node’s module resolution system

We at @taskworld put this in .eslintrc to hack Node’s module resolution system so that require('eslint-plugin-proprietary') becomes require('./lib/eslint/plugin'):

// .eslintrc.js
const Module = require('module')

// Hack Node module system to recognize our plugin.
Module._resolveFilename = (original => function (request, requester) {
  if (request === 'eslint-plugin-proprietary') {
    return require.resolve('./lib/eslint/plugin')
  } else {
    return original.apply(this, arguments)
  }
})(Module._resolveFilename)

Proposed solution

A solution proposed by @not-an-aardvark is to have topLevelOptions property in a configuration file. This topLevelOptions is only usable inside a project (cannot be used in shareable/extended configs).

It is a place where we could include the rulesDir option, and other options which would not make much sense or would have unintended side-effects when placed in shareable configs.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:12 (12 by maintainers)

github_iconTop GitHub Comments

2reactions
dtinthcommented, Jun 30, 2017

@not-an-aardvark I ended up creating eslint-plugin-local, heavily inspired by eslint-plugin-local-rules. The module is one line of code:

module.exports = require('../../.eslintplugin')

Since this plugin is intended to be installed at project-level (not in shareable config; in that case, better to create a plugin), we can be sure it will reside at $PROJECT/node_modules/eslint-plugin-local. This means the plugin will work regardless of the cwd.

The name .eslintplugin is chosen so that the file appears alongside .eslintrc. Then we can implement our project-specific plugin at:

  • .eslintplugin.js
  • .eslintplugin/index.js
2reactions
ilyavolodincommented, Jun 21, 2017

Would this solve your issue: https://github.com/cletusw/eslint-plugin-local-rules This is a plugin that allows you to configure local rules through eslintrc file.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Rules - ESLint - Pluggable JavaScript Linter
A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease.
Read more >
Building an overly specific lint rule with ESLint, AST and React
Well, hopefully, this will help you take that extra step forward to a world of overly specific, probably unnecessary linting rules.
Read more >
Implementing your first Android lint rule - ProAndroidDev
Lint is a static analyser, which has the goal of finding bugs on our source code without the need of compiling or running...
Read more >
14 Linting Rules To Help You Write Asynchronous Code in ...
A compiled list of linting rules to specifically help you with writing asynchronous code in JavaScript and Node.js.
Read more >
How To Customize ESLint Rules with an Ejected Create React ...
Projects created using Create React App have linting with ESLint already ... and even provide a link for more info on that specific...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found