New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local vs. Global installation #6732

Closed
ilyavolodin opened this Issue Jul 21, 2016 · 22 comments

Comments

Projects
None yet
8 participants
@ilyavolodin
Member

ilyavolodin commented Jul 21, 2016

This has been brought up many times before, but the resolution was never reached. Currently if you install ESLint globally, all of the plugins need to be installed globally. And visa-versa for local installation. I believe shareable configs do not to be installed globally any more, but will be relative to the configuration file itself.
We've had suggestions to have global installation of ESLint fall back to local, if one is available. Previously we said that team feels that this would be just as confusing as the current behavior. I want to check if that's still the case. We constantly get issues/chat questions about plugin not found error.

@kaicataldo

This comment has been minimized.

Member

kaicataldo commented Jul 21, 2016

I think some of the cognitive dissonance for our users is that I see a lot of us advocate using a local installation (myself included), while our documentation says to install globally. We've talked in the past about how having to understand npm and the difference between a local and global installation is a barrier for entry, but I feel like most users end up having to overcome that hurdle anyway when they get confused by the error mentioned by @ilyavolodin. It's definitely a recurring thing in the chatroom as well as in our GitHub issues.

Would it be too confusing if we actually changed our installation instructions to accurately reflect that we generally recommend using a local installation as best practice? We could even add a note describing the alternate situations in which a user might want a global installation and a link to some reading material on the difference between local and global installations in npm. I just don't think it's right that users can follow our directions and end up being confused/stuck - it's not a good user experience and seems like a pretty negative first interaction with the tool.

I feel like our written docs not matching how most projects use ESLint (and how many of us recommend using it) might end up being a more frustrating and confusing thing for users to have to grapple with than having to learn how npm works, given that that's researchable (and we can provide links for the user in our own documentation).

@mysticatea

This comment has been minimized.

Member

mysticatea commented Jul 22, 2016

For what it's worth, I have written a tutorial of ESLint in Japanese before: The first step to using ESLint.
In this tutorial, it's using global-installed eslint to explain, but there is a big note ("In fact, we recommend a use of local-installed eslint, but this article uses global-installed eslint to make this explanation easy.") in installation section, and the note introduces the article which explains pros/cons of local-installed eslint.

@kaicataldo

This comment has been minimized.

Member

kaicataldo commented Aug 1, 2016

@eslint/eslint-team Any other thoughts on this? Would love to make some headway here :)

@markelog

This comment has been minimized.

Member

markelog commented Aug 1, 2016

This is how grunt-cli/gulp staff works right? Also JSCS worked in the same way, I think it is more confusing to see plugin not found errors.

So strong +1 from me to fix this

@himdel

This comment has been minimized.

himdel commented Aug 1, 2016

Just a note - falling back to local is exactly what gulp does. And given its popularity, I'd argue it's equally confusing to do something different..

Definitely +1 on encouraging local installs, since it's impossible to work on more than 1 project with global..

@nzakas

This comment has been minimized.

Member

nzakas commented Aug 1, 2016

Previously, there was some strong feelings that we should support this, but we found a lot of complexity when it came time for implementation. I think everyone would still be in favor, we just really need a solid technical proposal to consider. For reference, here's the previous discussion: #3993 (it's a long read, but covers a lot of the concerns).

@kaicataldo we did change the installation instructions in the readme to address this.

@markelog

This comment has been minimized.

Member

markelog commented Aug 1, 2016

Can someone summarize that thread?

@kaicataldo

This comment has been minimized.

Member

kaicataldo commented Aug 2, 2016

@nzakas Ah, I see - the "Getting Started" page on the site still has the old instructions (and we send users there a lot!). Maybe we can copy the readme changes over - I think that would solve my concern above.

@kaicataldo

This comment has been minimized.

Member

kaicataldo commented Jan 9, 2017

Is there any reason we can't use the logic that @mysticatea's https://www.npmjs.com/package/eslint-cli employs in core?

@nzakas

This comment has been minimized.

Member

nzakas commented Jan 10, 2017

If you search through old issues, you'll find the previous discussion on the complexities of bringing that into core.

@omeid

This comment has been minimized.

omeid commented Mar 12, 2017

The current implementation is completely counter-intuitive and meaningless.

A project specific installation is allowed to make assumptions about the global scope (As in, the developer machine it runs on)? Why?

But the global install is not allowed to use the plugins installed for the very project it is being run on? how does that even make any sense?

I couldn't find any hard and real technical issues blocking this, can someone please link?

@mysticatea

This comment has been minimized.

Member

mysticatea commented Mar 12, 2017

IMO, we cannot assume the proper version of ESLint to be installed in global scope. A project might use 3.x, Another project might use 2.x. It might be not able control for some reason. So I recommend to use local installation for each project and declare it with package.json.

@omeid

This comment has been minimized.

omeid commented Mar 14, 2017

@mysticatea That is a no problem.
The global install when used for a project should act as a proxy to the local install. like gulp, react-native, et al.

See: eslint-cli, what eslint's official CLI should do.

@omeid

This comment has been minimized.

omeid commented Mar 14, 2017

Aside from the assumed technical issues and the discussion thereof. Plugins are effectively project specific code, and so in no way different than .eslintrc from a project scoping point of view, they're effectively an extension of .eslintrc.

If there is an argument to be made for global plugins only for globally installed cli, that should also hold true for eslintrc, otherwise any argument for for plugins being attached to the "installation" instead of the project's package.json/eslintrc is pointless.

@not-an-aardvark

This comment has been minimized.

Member

not-an-aardvark commented Oct 29, 2017

I'd like to revisit this discussion because I think the current behavior is a significant pain point for new users. People are very frequently confused because ESLint isn't finding their local plugins (it's by far the most common problem that people ask about on Gitter -- I'd estimate that a new user asks about it every few days).

The two potential issues discussed in #3993 were:

  • If someone uses eslint and then switches directories, and then they use eslint -v, they might be confused about what version was run if global installations call the local installation.
  • If someone actually wants to run a global installation of ESLint on a directory where ESLint is also locally installed, it might be difficult for them to do so if global installations call the local installation.

I acknowledge that these are legitimate concerns. However:

  • Based on how frequently users are confused by the status quo, it seems very unlikely to me that these issues would cause more confusion than we already have, since they only occur for somewhat rare user interaction and use cases.
  • Neither of these problems are specific to ESLint; they would also apply to many other tools such as babel-cli and grunt. I think mimicking the way that other tools work here would lead to decreased user confusion overall.

So I'm proposing that we adopt a similar approach to what other tools use: when ESLint is run globally from the command line, it automatically looks for a local installation from the CWD, and runs that instead if it finds the installation. This would be implemented as part of bin/eslint.js (it wouldn't affect CLIEngine).

@mysticatea

This comment has been minimized.

Member

mysticatea commented Oct 29, 2017

I have a concern. It's that ESLint has core rules. The core rules are updated on most every minor version. So the difference of versions between global and local is relatively serious. People can see "a rule not found" error or "invalid rule options" error instead of "command not found" error (eslint-cli reports "Please install ESLint by npm install eslint --save-dev" in that case. It's more user-friendly). I think that ESLint needs a display to distinguish which is running.

Also, I'm not sure that the feature (finding local-installed ESLint) will reduce questions about ESLint isn't finding their local plugins because the feature does not find local-installed plugins directly. It will show the same error as current if ESLint is not installed in local. I think we can make a special message if local plugins are found but global ESLint is running, but it's a separate issue.

I think mimicking the way that other tools work here would lead to decreased user confusion overall.

Grunt, gulp and karma seem to separate CLI command to *-cli package in their doc. Babel-cli looks to do require("babel-core") and use it simply to me.

@omeid

This comment has been minimized.

omeid commented Oct 30, 2017

All the concerns in regards to version mismatch is pointless.

  • If a project has an eslint setup, it is according to the version installed for that project, not the arbitrary version on any given developers computer.

  • If a project does not have a local install, then of course, there is no version mismatch.

@mysticatea

This comment has been minimized.

Member

mysticatea commented Oct 31, 2017

@omeid Of course, it's no problem if a user has set up correctly. However, the main topic on this is about making user-friendly behavior if a user makes a wrong setup. I.e., if a user installed ESLint into global but plugins into local, ESLint shows the error message "ESLint couldn't find the plugin (and detail description)", but We have gotten questions about that frequently. We should consider what is user-friendly behavior under wrong setups.


In getting started page, many popular tools (babel, webpack, gulp, grunt, karma, ) recommend local installation strongly and several tools (gulp, grunt, karma, ) introduce *-cli package for CLI command in additionally. ESLint seems an exception. (browserify and rollup are using global installation, but those are always using local-installed plugins)

I think:

  • We can update our getting started page with only local installation and eslint-cli as follow other tools.
  • We can move the eslint-cli package into eslint org.

Also, I think:

  • Maybe we can move --init feature into the eslint-cli package to reduce core size in future.
@omeid

This comment has been minimized.

omeid commented Nov 1, 2017

@mysticatea But that is the problem. eslint when run against a local project must invoke the local install. eslint plugins have a peer dependency on eslint, so it must be install locally anyways, if you haven't, your setup is broken.

@mysticatea

This comment has been minimized.

Member

mysticatea commented Nov 1, 2017

@omeid Yes. Global-installed ESLint does not find local-installed plugins. But as I said, the feature (global-installed ESLint finds and runs local-installed ESLint) does not solve the problem. Global-installed ESLint still does not find local-installed plugins if local-installed ESLint was not found. Users must install ESLint into project local as same as current.

@omeid

This comment has been minimized.

omeid commented Nov 2, 2017

Users must install ESLint into project local as same as current.

Indeed, but that is required by eslint plugins anyways, they all have eslint as peer dependency.

@nzakas

This comment has been minimized.

Member

nzakas commented Sep 21, 2018

Unfortunately, it looks like there wasn't enough interest from the team or community to implement this change. While we wish we'd be able to accommodate everyone's requests, we do need to prioritize. We've found that issues failing to be implemented after 90 days tend to never be implemented, and as such, we close those issues. This doesn't mean the idea isn't interesting or useful, just that it's not something the team can commit to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment