eslint: Plugins fail to load when eslint is installed globally
I’ve authored a plugin eslint-no-exclusive-tests that warns if certain Jasmine methods are used (ddescribe, iit
etc.)
When eslint is installed globally (as normal), a module loader error is thrown:
❯ eslint spec.js
module.js:340
throw err;
^
Error: Cannot find module 'eslint-plugin-no-exclusive-tests'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at /usr/local/lib/node_modules/eslint/lib/cli-engine.js:122:26
at Array.forEach (native)
at loadPlugins (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:115:21)
at processFile (/usr/local/lib/node_modules/eslint/lib/cli-engine.js:151:9)
at /usr/local/lib/node_modules/eslint/lib/cli-engine.js:222:30
at walk (/usr/local/lib/node_modules/eslint/lib/util/traverse.js:82:9)
As the docs say to add eslint as a peerDependency, it gets installed locally to the project. If using the local eslint, the plugin runs as expected:
❯ ./node_modules/.bin/eslint spec.js
spec.js
3:0 error Unexpected ddescribe no-exclusive-tests/no-exclusive-tests
package.json
:
...
"devDependencies": {
"eslint": "^0.8.0",
"eslint-plugin-no-exclusive-tests": "^0.2.0"
...
.eslintrc
plugins:
- no-exclusive-tests
rules:
no-exclusive-tests/no-exclusive-tests: 2
About this issue
- Original URL
- State: closed
- Created 10 years ago
- Comments: 38 (18 by maintainers)
I’d like to recommend https://www.npmjs.com/package/eslint-cli
Hi all, I ran into this issue on vim with ‘syntastic’. Since I have to use local eslint, the following is my vim config:
Now the effect between vim and ‘npm run eslint’ is exactly the same.
It’d like to see this reopened. It’s not about global/local, it’s about being able to run
eslint
from the cli of any project and have it work correctly for that project.If anything, the current setup is inconsistent since
eslint
follows the rules of the current project but looks for global plugins. Either the globaleslint
follows global config only, or it follows the full local/hierarchical configuration.Side note: eslint-based xo has this behavior exactly:
gulp, webpack, grunt, etc. all follow the same pattern: global cli invokes the local module version and local plugins. There is no such thing as a global install or global plugins, installing plugins globally makes no sense.
Invoking the locally installed version of eslint (and any plugins) is simpler, purer, and more practical.
Chiming in to say that eslint is pretty much the only widely-used tool in the JS ecosystem that behaves this way. It’s unintuitive and the workaround is not difficult.
I agree that global ESlint + local ‘plugins’ makes sense, the current ‘global + global’ implementation does not. There is a simple use case which applies to the project I’m working on. Let’s say we are using a package from NPM like our own package, or eslint-config-airbnb.
the-project/.eslintrc.json:
{ "extends": "eslint-config-project" }
the-project/node_modules/eslint-config-project/index.js:
module.exports = { "rules": { "no-console": 2 } }
A local copy of eslint runs just fine with ‘npm run eslint’. However, any editor designed to leverage the project-level .eslintrc (any editor with ESlint integration), and which tries and uses a global instance of eslint, fails. For instance, here’s the error when I use emacs:
I think expecting all our IDEs to recognize this use case, or for us to somehow override its PATH, is too much to ask. It seems pretty simple for ESlint to detect this really and use the same project-level name resolution that typical NPM module resolution uses. It just seems like an oversight that it can’t do that.
I’m against the idea of global cli/global plugins. We use plugins to solve local problems or per project basis problems. If two projects sitting in my dev. machine use two different versions of the same plugin , global/global approach might fail.
So that leaves us global/local or local/local approach.
Local/local approach sounds good and safe and a lot reasonable. That should become standard. Encouraging standard approach is good, however, enforcing it is another story.
Well, Local/local approach mostly sounds inconvenient in the context of using IDEs or editors. Most of us want quick feedback, so integrating eslint to IDEs or editors has a lot of benefits. So we customize IDEs to integrate it. However, will most people welcome the idea of having to reconfigure their IDEs or whatever tools whenever they switch project? Some IDEs provide per project configuration, but not all. Some tools are not quite flexible to configure and often our organization or team forces to use certain IDEs or tools, which might be against the idea of “Everything should sit in local”
People are usually stuck with some strange situations, which are often quite against standard thinking…
While sticking to local/local idea as a default standard approach for eslint, but providing global/local solution will be quite generous and absolutely beneficial for certain users.
I can run global gulp from path using local modules. I can not run global eslint from path using local modules. Eslint claims to focus on extensibility, so loading extensions should be a priority. To discuss if this is an issue or not for a tool like this is absurd, so this is my last comment.