eslint: Personal config (~/.eslintrc) doesn't load global-installed configs/parsers/plugins

Tell us about your environment

  • ESLint Version: 6.0.1
  • Node Version: 12.4.0
  • npm Version: 6.9.0

What parser (default, Babel-ESLint, etc.) are you using? default

Please show your full configuration:

Configuration
{
  "env": {
    "browser": true,
    "commonjs": true,
    "es6": true,
    "node": true
  },
  "extends": [
    "standard"
  ],
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "sourceType": "module"
  },
  "plugins": [
    "html",
    "css-in-js",
    "json"
  ],
  "rules": {
    "no-const-assign": "warn",
    "no-this-before-super": "warn",
    "no-undef": "warn",
    "no-unreachable": "warn",
    "no-unused-vars": "warn",
    "constructor-super": "warn",
    "valid-typeof": "warn"
  }
}

What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.

I updated eslint from version 5.16.0 to 6.0.1 and, since I did it, eslint failes to start and I always receive this error: ‘Failed to load config “standard” to extend from eslint 6’.

What did you expect to happen?

I expected that all worked fine.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 6
  • Comments: 37 (13 by maintainers)

Commits related to this issue

Most upvoted comments

I had enough of this and created the following package: https://github.com/wintercounter/eslint-global-patch

It is a very unsafe and ugly workaround, it’ll patch your ESLint installation. For my use case it works fine for all our projects.

my 2cents: I can’t upgrade eslint past v5, as ALE in Vim will report ‘Failed to load config “standard”’ - just as CLI does. I’ve read all issues here related to forcing users to stop using a global config, and I don’t agree for reasons already cited above in this ticket. I see no option open to me atm than to slowly die on v5? That does not seem reasonable

Rolling back to 5.16 because of this issue.

For our use cases we want to have a single config automatically applied to all projects instead of individual projects being able to have different package versions and configs. Please restore the ability to have shared configs installed globally.

My solution:

// ~/.eslintrc.js

'use strict';
const Module = require('module');

const hacks = [
  'eslint-config-airbnb-base',
  'babel-eslint',
];

const ModuleFindPath = Module._findPath;
Module._findPath = (request, paths, isMain) => {
  const r = ModuleFindPath(request, paths, isMain);
  if (!r && hacks.includes(request)) {
    return require.resolve(`${process.env.HOME}/.npm-global/lib/node_modules/${request}`);
  }
  return r;
};

module.exports = {
  extends: 'airbnb-base',
  parser: 'babel-eslint',
  ... etc
};

this is so incredibly stupid. please add back global resolution in some capacity.

Can we get some love here please? We cannot move forward to 6.x. We cannot have local deps, not allowed by our systems and never will be. Is it really necessary to force one use case?

No, it doesn’t make migration difficult. It makes it impossible for many of us. I know I can pass loader options. But again, it would require manual config from every user for every project then, which is unacceptable.

Imo ESLint should be able to resolve these things relative to the eslint module directory as well and that would solve this also.

Anyway, I’m starting to feel like I’ll need to patch manually ESLint on file-system level to make this work. I really want to avoid this…

There would be so many solutions to resolve this issue:

  • Allow globals again.
  • Resolve configs/plugins relative to the loaded eslint module itself.
  • Add support for --resolve-configs-relative-to flag + add solution to pass CLI options in .eslintrc so 3rd party tools can automatically apply without extra config.
  • Allow configs to a be a file path (plugins can be, why not configs?)
  • Add option to define our own node_modules dir(s) to resolve from. (from rc file, not as a CLI flag).

I’m sure this thread will keep growing with reports from other users when they start to update their codebase.

What it needs is that is working as any other module in the NodeJS ecosystem. ESLint cannot resolve modules relative to itself currently!

Hi,

I have a similar use-case, that worked well until 6.x

We have a mono-repo, no lerna or fancy tools.
One base .eslintrc config at the repo root.

 {
   "root": true,
   "extends": "@company/config"
 }

All peerDependencies of that config are specified and installed per packages.
This way the packages can follow different upgrade times.
Also most packages don’t require a special config, so they don’t even have an .eslintrc. If one package need some special tweaks, only adding an .eslintrc with the tweaks does the job.

I think that was a simple and effective pattern. Will this definitely be impossible now?

I’m a VSCode user, too. If you installed eslint in project local, VSCode uses it. I’d like to recommend to use local installation with package.json because it allows us to share ESLint and plugins of the same versions with the development team, contributors, and CI system.

If you want to use global installation, use --resolve-plugins-relative-to option to specify the location of global-installed packages. I guess it’s npm prefix -g.

In VSCode case, configure eslint.options.resolvePluginsRelativeTo option in your settings.json of VSCode.

I believe that 5.x issues “design bug” affected less installations that 6.x design broke now. Standalone ESLint (outside node project) is now quite unusable. I have to change my editor --resolve-plugins-relative-to based on that if local project use node.js.

IMHO best solutions should be:

  1. add a way to include --resolve-configs-relative-to option in .eslintrc
  2. detect global .eslintrc usage and as a fallback to local plugins search user global npm installation

--resolve-plugins-relative-to also won’t work in case ESLint is being run by some 3rd party, eg: Webpack, VSCode, WebStorm, etc. If that config would be exposed in .eslintrc, that would also work nicely. An additional --resolve-configs-relative-to would make it even better.

UPDATE: I was trying to hack things around again, but no success as the plugins array cannot accept file paths (while extends can). This is another really weird behaviour/decision.

https://github.com/eslint/eslint/blob/afd8012c2797f2f5bf3c360cb241ea2ba6e1a489/lib/cli-engine/config-array-factory.js#L730

I’m getting the same problem. will roll back eslint

So there’s no other way than install the package where the config file is? Mmmm… so bad… I think I rollback to eslint 5. Any way thanks for your support 😃

Hi @mysticatea, thanks for you help. It seems you gotta reason because, as I read, “With ESLint v6, plugins should always be installed locally, even if ESLint was installed globally”. So there’s no way to load global plugins? It’s important to me… Anyway I use eslint along with Visual Studio Code.

If you’d like to have a single config for all projects, I would recommend:

  1. Putting that config in a separate package
  2. Installing the shareable configs and plugins that you need as dependencies of that package
  3. Using --config /path/to/that/package/.eslintrc.js --resolve-plugins-relative-to=/path/to/that/package when running ESLint on the command line

As a last-resort workaround, you could alternatively try setting the NODE_PATH environment variable to the output of npm root -g. (This isn’t the most robust way to load dependencies, but it works effectively the same as having globally-installed packages always be loadable.)

I don’t think it’s a good idea to install and run ESLint globally and I’m a little bit hesitant about adding more options, because it encourages using this behavior.

Upgrading ESLint (even a semver-minor upgrade) can lead to more linting errors, and if someone had multiple projects on their machine they would potentially have to fix up errors in every project each time they upgrade.

If this same person collaborates with others (or runs automated testing), not defining the version in package.json can lead to mismatching results between runs.

That being said, I recognize that we already support this feature and I do think this change makes sense, given that we currently are supporting global installations.

I understand your position. I agree that the current personal config’s behavior is not convenient.

@eslint/eslint-team ESLint uses ~/.eslintrc if there are no config files in the current project (it’s called personal config). I think that it’s convenient if ESLint finds also global-installed shareable configs and plugins when ESLint adopted the personal config. Thoughts?

(for a reference, lib/cli-engine/cascading-config-array-factory.js#L372-L384 is the code to load the personal config. I’m imaging to add a flag to that place to find also global-installed packages.)