Skip to content
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

BREAKING CHANGE(bin): remove command #537

Closed
Tracked by #443
darcyclarke opened this issue Aug 22, 2022 · 12 comments · Fixed by npm/cli#5459
Closed
Tracked by #443

BREAKING CHANGE(bin): remove command #537

darcyclarke opened this issue Aug 22, 2022 · 12 comments · Fixed by npm/cli#5459
Assignees
Milestone

Comments

@darcyclarke
Copy link
Contributor

No description provided.

@styfle
Copy link

styfle commented Aug 24, 2022

Why is this being removed?

kodiakhq bot pushed a commit to vercel/vercel that referenced this issue Aug 30, 2022
This PR removes `npm bin` in favor of a custom implementation since the command will be removed in npm 9.

- Related to npm/statusboard#537
@wraithgar wraithgar self-assigned this Sep 1, 2022
@wraithgar
Copy link
Member

wraithgar commented Sep 1, 2022

npm bin currently does not accurately represent everywhere npm looks for a bin when one is asked for. Providing it as a command invites folks to add it to their $PATH which is discouraged: npm should be finding those, not your os. The bin discovery of npm is more than just looking in the one folder, it actually walks up from whatever folder the package is in, looking for a .bin folder in any node_modules it finds. This is how scripts that call npm run can get the version of a given package they asked for, instead of whichever one "wins" by being hoisted.

In global mode, bin is simply where node is.

wraithgar added a commit to npm/cli that referenced this issue Sep 1, 2022
BREAKING CHANGE: this removes the `npm bin` command

The output of this command is misleading and incomplete.  The `.bin`
resolution of npm is much more nuanced than this command implies, and
the output of `npm bin` is not somthing end users should be dealing
with.  `npm` itself is responsible for running the `bin` entries of
modules, with the exception of global bins, which end up in the same
folder as `node` itself, presumably already in a user's path since they
can run node.

Closes npm/statusboard#537
wraithgar added a commit to npm/cli that referenced this issue Sep 1, 2022
BREAKING CHANGE: this removes the `npm bin` command

The output of this command is misleading and incomplete.  The `.bin`
resolution of npm is much more nuanced than this command implies, and
the output of `npm bin` is not somthing end users should be dealing
with.  `npm` itself is responsible for running the `bin` entries of
modules, with the exception of global bins, which end up in the same
folder as `node` itself, presumably already in a user's path since they
can run node.

Closes npm/statusboard#537
@lukekarrys lukekarrys added this to the v9.0.0 milestone Sep 2, 2022
@styfle
Copy link

styfle commented Sep 3, 2022

If the command is going to be removed, it would be great if the algorithm itself was documented.

wraithgar added a commit to npm/cli that referenced this issue Sep 8, 2022
BREAKING CHANGE: this removes the `npm bin` command

The output of this command is misleading and incomplete.  The `.bin`
resolution of npm is much more nuanced than this command implies, and
the output of `npm bin` is not something end users should be dealing
with.  `npm` itself is responsible for running the `bin` entries of
modules, with the exception of global bins, which end up in the same
folder as `node` itself, presumably already in a user's path since they
can run node.

Closes npm/statusboard#537
@ngraef
Copy link

ngraef commented Nov 16, 2022

(Posting here for visibility.) There is a discussion at npm/feedback#807 to find an alternative for a use case broken by this change.

@nmccready
Copy link

If npm run behaved more like yarn run then I would think this change was acceptable. However npm run still does not execute ./node_modules/.bin it appears.

@nmccready
Copy link

Looks like $(npm root)/.bin is the closest you can get to this now?

@ljharb
Copy link

ljharb commented Nov 17, 2022

@nmccready that's what npx is for.

@nmccready
Copy link

Thank you I will look into this.

@molisani
Copy link

There's a lot of discussion of npm bin here but there's a slightly different use case for npm bin -g. What is the replacement for npm bin -g to find the folder where npm installs globally-available executables?

Providing it as a command invites folks to add it to their $PATH which is discouraged: npm should be finding those, not your os.

Surely the global install path should be in your $PATH variable, right? This was one thing npm bin -g checked for.

@wraithgar
Copy link
Member

Surely the global install path should be in your $PATH variable, right? This was one thing npm bin -g checked for.

The global install path should already be in your path because that is where node itself is. npm is installed into a given version of node alongside the node binary, the assumption being that if you can run node, npm can link bins into the same directory to have them also available to the end user without an extra $PATH entry.

The nuance here comes from the fact that Windows installs node/npm into a different directory structure than osx and linux. There is no bin directory in Windows. There is also no lib in Windows, the node_modules is also an immediate subdirectory of the one in which the node binary lives.

The npm bin command kind of put the cart before the horse and introduced a bit of bad "discovery" of this path based on npm, instead of node.

So for instance in fish shell this would be a more appropriate way of knowing where those bins lived

$ dirname (which node)
/Users/wraithgar/.nvm/versions/node/v18.12.0/bin

They really have nothing to do with npm, but with node itself.

@molisani
Copy link

molisani commented Nov 21, 2022

In the Windows Node installer, it's more than just the different directory structure, the global packages are installed in a completely separate directory from the node installation. Being able to run node does not necessarily mean that the user is also able to run the globally installed packages. Taken from the installer, updating the PATH variable is split into two different "features".

* Add to PATH
  * Node.js and npm - Add Node.js and npm (if installed) to the PATH environment variable
  * npm modules - Add modules that are installed globally by npm to the PATH environment variable. This option works for the current user only.

With a clean install of node on Windows with these two features selected, it will add two separate locations to the PATH:

C:\Program Files\nodejs
C:\Users\<username>\AppData\Roaming\npm

This is because of the value of prefix decided by the builtin config, which is set to %APPDATA%\npm by default:

$ npm config ls
; "builtin" config from C:\Program Files\nodejs\node_modules\npm\npmrc

prefix = "C:\\Users\\<username>\\AppData\\Roaming\\npm"

If I then install a package (ex: typescript) with npm i -g typescript, this installs tsc to C:\Users\<username>\AppData\Roaming\npm\tsc which I'm only able to invoke successfully because of the second new entry in my PATH variable. This logic is entirely custom to npm, as it's derived from npm's prefix config value.

This all works seamlessly in the ideal case, but speaking as someone that handles troubleshooting for a large population of developers that are not always primarily doing Node/npm/JS development, incomplete or inaccurate PATH variables have been an uncommon yet consistent issue. It was useful for us to have npm bin -g as that could prompt the user to add the global package location to their PATH if it wasn't already set (as it would warn with (not in PATH env variable)).

Given the nature of Windows' two-location installation, this does seem like a Windows-only problem. As such, I'm not sure what the cleanest fix would be. For this use case we do not need any of the "non-global" functionality of npm bin without -g that allowed for the aforementioned bad behavior, so I'm not suggesting that this command be added back as it was. If the functionality to check the global install location (and also if that was in the PATH variable) could be added to an existing command (maybe npm prefix -g) or even a new command, that would work well for us. I'd be happy to contribute such a feature (whatever it may look like) if that sounds like a good idea to all involved.

@wraithgar
Copy link
Member

This is very good feedback @molisani thank you for laying it out so clearly. Can you open a new issue in https://github.com/npm/rfcs suggesting we reintroduce a global only bin command? Your last comment can be copy/pasted there as a starting point I think. This closed issue definitely has no greater visibility w/in the org so discussion here is unlikely to result in any npm change.

jehon added a commit to jehon/kiosk that referenced this issue Nov 25, 2022
azu added a commit to textlint/textlint that referenced this issue Feb 21, 2023
Use npx instead of npm bin

npm/statusboard#537
azu added a commit to textlint/textlint that referenced this issue Feb 21, 2023
Use npx instead of npm bin

npm/statusboard#537
lxxxvi added a commit to rubymonstas-zurich/slides.rubymonstas.ch that referenced this issue Sep 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants