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

[BUG] npm install doesn't install local scripts for the top-level project. #3488

Closed
1 task done
NfNitLoop opened this issue Jul 1, 2021 · 9 comments
Closed
1 task done
Labels
Bug thing that needs fixing Needs Triage needs review for next steps Release 7.x work is associated with a specific npm 7 release

Comments

@NfNitLoop
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

When I run npm install in a project that has a "bin" section in package.json, the binary(s) specified doesn't get created in node_modules/.bin.

Expected Behavior

I'd expect a script to be created in node_modules/.bin/ since that's the behavior documented at
https://docs.npmjs.com/cli/v7/configuring-npm/package-json#bin

To use this, supply a bin field in your package.json which is a map of command name to local file name. On install, npm will symlink that file into prefix/bin for global installs, or ./node_modules/.bin/ for local installs.

A user on StackOverflow seems to have found that this case is excluded intentionally in code, but couldn't find a reason.

The code and the documentation are mismatched currently, in a way that eats developer time. One or the other should probably be updated so that they match. (IMO, I'd prefer a script be installed in this case, because sometimes I want to use a package's script without installing it globally!)

Steps To Reproduce

  1. In any environment, AFAICT, with a simple script like example.js:
#!/usr/bin/env node

console.log("Hello, world!")
  1. And a package.json that references it:
{
  "name": "npm-bug",
  "version": "1.0.0",
  "description": "",
  "main": "example.js",
  "bin": "example.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
  1. Run npm install

  2. And observe that there's no script created in node_modules/.bin/


Aha. Recreating this fresh, I may have found the reasoning behind this exception -- if you have no dependencies, there isn't a node_modules/ or node_modules/.bin/ directory to install the script into.

However, that's probably the rare case. Often, such packages will have dependencies, so node_modules/.bin/ will exist, which makes the script's absence from it all the more confusing.

Environment

  • OS: Windows 10
  • Node: v14.17.0
  • npm: 7.19.0 (But I also observed this behavior on 6.14.x)
@NfNitLoop NfNitLoop added Bug thing that needs fixing Needs Triage needs review for next steps Release 7.x work is associated with a specific npm 7 release labels Jul 1, 2021
@zackw
Copy link

zackw commented Jul 1, 2021

if you have no dependencies, there isn't a node_modules/ or node_modules/.bin/ directory to install the script into.

... but then why not just create node_modules/.bin/ if it hasn't been created yet?

@NfNitLoop
Copy link
Author

@zackw I agree. That seems like the least surprising behavior. Definitely less surprising than silently not installing a binary anywhere.

@wraithgar
Copy link
Member

Duplicate of #3446

@wraithgar wraithgar marked this as a duplicate of #3446 Jul 1, 2021
@NfNitLoop
Copy link
Author

@wraithgar i did find #3446 when I did my initial bug search, but this appears to be a separate case.

  1. In that issue, the user says the example works in v6, but breaks in v7. This issue is broken in both.
  2. In that issue, the user is adding a dependency to an existing package. This issue details a problem with “bin” being ignored for the top-level package.

@wraithgar
Copy link
Member

You're right this seems to be a separate issue. However I'm not sure this is a bug. A module is not going to need itself installed in its own node_modules/.bin is it? The entries in there will be available to npm while you're in that package:

~/D/n/gar-create-test (main↑1|…) $ cat package.json|jq .bin
{
  "create-test": "index.js"
}
~/D/n/gar-create-test (main↑1|…) $ npm run create-test

> @gar/create-test@2.0.0 create-test
> node index.js

Gar's test create script version 2.0.0

That /.bin is only needed (and thus created) when you install the package somewhere else.

@wraithgar
Copy link
Member

In the docs https://docs.npmjs.com/cli/v7/configuring-npm/package-json#bin "On install" means "when the package is installed" not "when npm install is ran for the package itself". We can make the docs more clear there.

@NfNitLoop
Copy link
Author

  1. If this is intended behavior, then at a minimum it would seem a bug that the docs read as if this should work.

  2. But even if you don’t consider it a bug, it seems like an odd inconsistency to keep and document as an exception instead of just making it work like the other cases.

For an example use case, I’m using/debugging a plugin for the protocol buffer compiler, protoc. Protoc allows you to specify the path to a plug-in, but it must be a single executable/script. So “npm run …” doesn’t work in this case.

@NfNitLoop
Copy link
Author

… (but would work if I had installed the plug-in as a dependency. Which is an odd inconsistency!)

@wraithgar
Copy link
Member

Docs will be clarified #3491. It is intended. Referring manually to the things in node_modules/.bin (or anything in node_modules is not recommended.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug thing that needs fixing Needs Triage needs review for next steps Release 7.x work is associated with a specific npm 7 release
Projects
None yet
Development

No branches or pull requests

3 participants