Eslint-plugin-react: Eslint cannot find global install

Created on 1 Jul 2019  路  39Comments  路  Source: yannickcr/eslint-plugin-react

Hi there,

So this is something that seems to have happened quite recently. I have installed eslint and eslint-plugin-react globally using npm i -g

I have an .eslintrc file in my home folder like so:

{
  "env": {
    "browser": true,
    "commonjs": true,
    "es6": true,
    "node": true
  },
  "plugins": [
    "react"
  ],
  "extends": ["eslint:recommended", "plugin:react/recommended"],
  "globals": {
    "$": true
  },
  "parser": "babel-eslint",
  "parserOptions": {
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true,
      "modules": true
    }
  },
  "rules": {
    "brace-style": "error",
    "camelcase": ["error", { "properties": "never" }],
    "comma-dangle": ["error", "never"],
    "func-call-spacing": ["error", "never"],
    "eqeqeq": "warn",
    "indent": [ "error", 2, { "SwitchCase": 1 } ],
    "key-spacing": [ "error", { "beforeColon": false } ],
    "no-console": "off",
    "no-fallthrough": "warn",
    "prefer-const": "error",
    "quotes": [ "error", "single" ],
    "semi": [ "error", "never" ],
    "react/prop-types": [ 0 ]
  }
}

I get the following error when I try to lint a file from the command line:

Oops! Something went wrong! :(

ESLint: 6.0.1.

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "/path/to/project/folder".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

    npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in "PersonalConfig".

If you still can't figure out the problem, please stop by https://gitter.im/eslint/eslint to chat with the team.

I appreciate I could probably fix the issue by installing the plugin to devDependencies, but I would like to keep it global.

Any ideas?

Most helpful comment

Why was this closed ? I've just run into the very same issue.
The use case is this, the company doesn't want to add linting to the code repo, but I still want it to run whenever I'm working on the code-base to get whatver utility I can out of it.
Currently looking for a way to tell eslint to look for plugins (react) in the global install folder.

All 39 comments

Nothing eslint-related should be global - only installed locally per project. Similarly, you shouldn't have a config in your home dir - a project that doesn't have eslint included in it should not have eslint run on it.

Ok fair enough, but in the docs it states:

Install ESLint either locally or globally.
If you installed ESLint globally, you have to install React plugin globally too. Otherwise, install it locally.

Perhaps you could update the docs to make that more clear, if that is the case

I guess the only other use case is IDE or text editor linters. Which is actually my use case. I'm using Atom's linter-eslint package, which allows you to set a global Eslint install.

Screenshot 2019-07-01 at 21 44 48

Ideally if there is not .eslintrc file in the project, I would like to fall back to some reasonable defaults and since I use React a lot, it seems reasonable to do that.

I have had this working before, so I guess I'm wondering if this is a change in the direction of the package, or if something else has changed, perhaps with my config or whatever.

I'm suggesting that falling back to reasonable defaults is actively harmful - if a project lacks a linting config, anything short of adding linting to the project is hurting the project.

eslint 6 has some changes around it, as noted in eslint's gitter.

Perhaps, but what about a company that has a base linter config for all projects. That seems reasonable to me. If the project does not have its own linter config, then fallback to the company's style guide?

I'll check out the changes to eslint 6.

Then for version tracking, they'd still want to reference that base config in all their projects.

I guess so, but only if they are working with someone outside of the company, in which case they would have a local .eslintrc file in the project folder.

If it's an in-house project, everyone is working from the same .eslintrc file, so there would be no need to track that file.

Anyway we're now having a discussion about process, not about eslint or eslint-plugin-react. Clearly eslint now loads plugins locally, and that's all I really needed to know. Closing this issue.

Why was this closed ? I've just run into the very same issue.
The use case is this, the company doesn't want to add linting to the code repo, but I still want it to run whenever I'm working on the code-base to get whatver utility I can out of it.
Currently looking for a way to tell eslint to look for plugins (react) in the global install folder.

@jekusz if every developer isn't forced to use the linter, then no developer should be permitted to. Projects that aren't linted, shouldn't be. (all projects should, of course, be linted)

@ljharb , do you know how to lint uncreated files now with ESLint 6.x?

With ESLint 5.x, when I created a new file with VSCode (aka "untitled file"), the linter works properly. But now I need to save that file inside a project with ESLint to lint it.

It is possible to lint that kind of file? This is very useful when I'm editing a simple script.

I'm not aware of any use cases for a one-off script where it wouldn't be much better for it to be inside a project with a package.json.

@ljharb the purpose of your comment eludes me. What I'm interpreting is that you frown upon my use case because it doesn't fit in with your project management philosophies ? Surely no author could be so strongly opinionated...

Otherwise, there's a workaround here:
"eslint.options": {
"resolvePluginsRelativeTo":"C:\Users\XXX\AppData\Roaming\npm\node_modules"
},
Check it out at: https://eslint.org/docs/developer-guide/nodejs-api

The purpose of my comment was to answer your question about why it鈥檚 closed. You鈥檙e explicitly avoiding doing the work of convincing your company of the value of linting, depriving all of your colleagues of those benefits, but still keeping them for yourself. I don鈥檛 think it鈥檚 about project management as it is about human relationships.

Either way, eslint - like almost everything else - shouldn鈥檛 be installed globally (this is a community convention/best practice), so it鈥檚 not about my personal beliefs at all.

Glad you found a solution.

image
@ljharb Console warning still has option to install plugin globally!

IMHO, eslint 5 works fine with globally installed plugin, but v6 not. So I think it's bug, and when plugin will change it version from minor to major v2... it can change this behaviour.
And for now it would be grate to fix it.

@sshmyg it鈥檚 an intentional change in eslint 6, not a bug; the console message notwithstanding, don鈥檛 have eslint stuff installed globally.

Since it鈥檚 in a major version of eslint itself, it鈥檚 impossible for us to change it in any way.

The one issue that I reckon is actually a bug is that the path provided in settings isn't resolved properly.
Having a vscode setting as follows:

"eslint.options": {
        "resolvePluginsRelativeTo":"%appdata%\\npm\\node_modules"
    },

gives this error:

Failed to load plugin 'react' declared in '.eslintrc.json': Cannot find module 'eslint-plugin-react'
Require stack:
- C:\Users\<user>\Documents\<someName>\<someName>\%appdata%\npm\node_modules\__placeholder__.js

If the path in the settings file is provided absolute then it works fine which leads to the conclusion that %appdata% doesn't get resolved as it should. Perhaps it's an issue with the extension rather than the plugin.

Sounds like correct reasoning.

Here is my use case: I run my node project in Docker, so I have no need for node_modules outside of Docker. I am not going to run my editor in Docker, but it would be nice if I didn't have to do a node install outside of it just for eslint. Without a local node_modules, Atom supports eslint without react, but it throws errors when I use extends react-app in my local eslint config. So I tried to install eslint and the react plugin globally, which is another option with Atom. But the plugin is not found.
ESLint couldn't find the config "react-app" to extend from.
I would rather not use resolvePluginsRelativeTo, because that would be specific to my environment and the eslint config is part of the project.

You have to run npm install both inside and outside of docker, there鈥檚 just no good way around it.

This is an eslint change, not related to this plugin.

For me this issue occurs when I add a few projects to workspace, but this projects has one common root folder, like on the screen
image

And every of this projects (Project-1 and Project-2) has it's own eslint config etc. This is independents projects but combined in workspace within one root folder (MyProjects).

If I add (Project-1 and Project-2) to workspace without root folder like this
image
, then elsint v6, works as expected.

That seems like an issue with your IDE not setting the right working directory when invoking eslint.

Yeh, sorry it's vscode-eslint bug probably.

I just downgraded to version 5 because I am a use case too.

I maintain a lot of projects for the same company and use globally installed configs because the projects should all follow the same style guide in the same version.

Otherwise I would have to install every config in every project (waste of space, redundancy, potentially different versions in each project).

This directory structure worked in version 5 with globally installed configs:

  • .eslint.rc ([...]"extends": "standard"[...])
  • project1/

    • node_modules/

    • js/

  • project2/

    • node_modules/

    • js/

This was the situation in version 5 (pseudo bash):

$ npm install -g eslint@5 eslint-config-standard
$ cd project1/
$ eslint .
  all fine

This is the current situation in version 6 (pseudo bash):

$ npm install -g eslint@6 eslint-config-standard
$ cd project1/
$ eslint .
OOPS - config "standard" not found

@Tilogorn the way you ensure that is updating the package.json of every project to use the same shared config, not having anything installed globally.

I would still have installed dozens of copies of the same software where one central installation would suffice.

You might solve your problems in a different approach than me. An advantage of eslint I really liked, was, that you had the choice between installing it globally or locally, depending on your individual needs/preferences. This isn't anymore as free as it had been.

Yes, that is both desired and the way the entire node ecosystem works.

You're right, global installs/configs was a bad practice that just happened to work, and the eslint team wisely decided to restrict it.

Some "features" of Node ecosystem are so stupid. Linter isn't a project dependency, it's a code checker, why it should be installed locally having thousands excess files bloating the disc? And it turns out many elementary scripts that are not a part of a project are thrown away. Very bad. Will try reverting to v5

Code checking is a project dependency, in any ecosystem.

Really? Why? I see no sense in having separate linter instances for each project. Continuing this logic we could finish having personal copies of npm and node itself for each 5-line package. Inside its own Docker container.

Anyway the project is wonderful, it saves a lot of time.

Nothing eslint-related should be global - only installed locally per project. Similarly, you shouldn't have a config in your home dir - a project that doesn't have eslint included in it should not have eslint run on it.

In my project:

  • I have created a Linter Docker Image (eslint is installed globally)
  • I mount my project source code in this Lint Docker Image and I execute eslint (this is executed by GitLab-CI)

If eslint is installed locally, node_modules is missing if I mount my project in Docker Image.

I can also move node_modules folder to local installation before execute eslint, but is slower that use eslint installed globally.

@ljharb I don't know why you react so aggressively here. You have somehow decided you should be organizing the entire world's projects according to your personal preference. I ask you to please accept that not everyone has the same preferences as you do.

@johanneswilm everyone indeed has different preferences; that doesn't make all preferences of the same quality (and it definitely doesn't make mine automatically better either).

However, the reason is because it comes from a long experience of terrible (or massively inconvenient) consequences happening from these kinds of practices. Any task in a project that isn't part of the project, that every developer on the project, now and forever, can't easily do - will cause more problems by being used ex machina (ie, by individuals globally installing things) than by not being used at all. Thus, my opinion remains that if a project isn't linted locally, it should not be linted at all.

@ljharb We all have our own experiences. Your life length is limited just as that of the rest of us and so there is just no way that your experience can be worth so much more than everyone elses. If you are the team lead for a particular team you can enforce your rules there and that can actually make sense that everyone on the same team follows certain guidelines. But when you are out on the internet, trying to tell everyone else how to live their lives.. well it's different. Some may just have one single project they are working on by themselves. Others, like me, do not actually use global installs, but are still affected by your changes because of circumstances you cannot possible foresee (running a django/python project with external plugins that also includes JS and needs to put it together in a very specific way that means that the files are not exactly in those places you try to require them to be in).

I don't actually use react, but I came across this because I had this same issue a while back, spent about a week or so over the past 6-9 months trying to to resolve it, and didn't manage to do it until today I came across https://github.com/wintercounter/eslint-global-patch which just removes the restrictions that were imposed with eslint6. So it is technically possible to fix it.

These aren鈥檛 my changes; I鈥檓 not an eslint collaborator.

Actually the way I made it work is to call eslint cli using the --resolve-plugins-relative-to option. And then provide the path to the folder where the global plugins are installed.

What a bizarre hill to die on here.

This let me use my corporate standard over all projects:-

echo 'your config' > ~/.eslintrc.json
yarn global add --verbose eslint
yarn global add --verbose eslint-plugin-react
yarn global add --verbose eslint-plugin-prettier
eslint . --resolve-plugins-relative-to=$(yarn global dir)

@gaving i'm not sure how it's bizarre; eslint itself has deprecated "personal configs" and recommends avoiding global installs.

You can certainly swim upstream with --resolve-plugins-relative-to, but that doesn't change the widely accepted best practice.

@ljharb I dunno, a few lines to enable linting vs modifying 18 sub-projects of the project I'm working on.

But I see there's a huge amount of drama over this so never-mind, thanks for the great software. 馃憤

Was this page helpful?
0 / 5 - 0 ratings