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

[FEATURE] npm ci --global is not supported #7224

Closed
2 tasks done
klebba opened this issue Feb 15, 2024 · 9 comments
Closed
2 tasks done

[FEATURE] npm ci --global is not supported #7224

klebba opened this issue Feb 15, 2024 · 9 comments
Labels
Bug thing that needs fixing Needs Triage needs review for next steps Release 10.x

Comments

@klebba
Copy link

klebba commented Feb 15, 2024

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

Current Behavior

When trying npm ci --global the following is returned: npm ERR! npm ci does not work for global packages.

Expected Behavior

I'm trying to migrate a command line tool from Yarn. Currently I would run
yarn install ./my-cli-tool-written-in-nodejs --global --frozen-lockfile
...and this command installs my package globally while strictly adhering to the contents of my lock file. Seemingly equivalent to --frozen-lockfile is npm ci but this command does not appear to support this behavior.

In #5698 this topic was left unresolved and closed, yet the problem persists. Thats for considering.

Steps To Reproduce

npm ci $package --global

Environment

  • npm 10.2.4
  • node v21.6.1
  • macOS 14.2.1
@klebba klebba added Bug thing that needs fixing Needs Triage needs review for next steps Release 10.x labels Feb 15, 2024
@ljharb
Copy link
Contributor

ljharb commented Feb 15, 2024

npm ci requires a package.json, which doesn't exist for globally installed packages.

Also, npm install and npm ci are mutually exclusive, you use one or the other.

@klebba
Copy link
Author

klebba commented Feb 15, 2024

npm ci requires a package.json

Per the docs here: https://docs.npmjs.com/cli/v10/commands/npm-ci

This command is similar to npm install, except it's meant to be used in automated environments such as test platforms, continuous integration, and deployment -- or any situation where you want to make sure you're doing a clean install of your dependencies.

This is exactly what I want to use npm ci for

The project must have an existing package-lock.json or npm-shrinkwrap.json.
If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.

Makes sense; my project has both a package.json and package-lock.json to inform the global installation of my CLI tool. Notably Yarn does the right thing here; it globally installs my package using yarn.lock — it's not clear why npm ci cannot do this. Instead the behavior forces us to accept that npm install may rewrite my package-lock.json during continuous integration of my globally installed CLI tool. This isn't really acceptable.

Also thanks for pointing out the mistake in my sample; the command I want to run is npm ci not npm ci install

@ljharb
Copy link
Contributor

ljharb commented Feb 15, 2024

Best practice is to not install anything globally, especially in a CI environment. Instead, you install it locally and invoke it with npx.

The entire purpose of npm ci is to delete and reinstall local node_modules. It's just conceptually nonsense to use it with -g.

@klebba
Copy link
Author

klebba commented Feb 15, 2024

@ljharb are you a maintainer of npm or npm ci?

@ljharb
Copy link
Contributor

ljharb commented Feb 15, 2024

@klebba nope! but that doesn't make any of my statements less true.

@klebba
Copy link
Author

klebba commented Feb 15, 2024

I see. Well, you know, that's just like uh, your opinion, man.

As long as npm install --global is a supported feature it is rather bizarre to randomly admonish issue reporters about "best practices" and "nonsense" use cases.

@ljharb
Copy link
Contributor

ljharb commented Feb 15, 2024

npm install -g is supported. npm ci -g is not, by design, since its inception.

Teaching best practices is a gift - it's trying to help you.

@wraithgar
Copy link
Member

npm ci installs a package as a dependency of the global namespace. It is fundamentally different than installing the dependencies for a package. There is no global package.json, so there is no ci that could be done at that level.

For cli tools in which you wan to dictate exactly what is installed when your package is installed (which npm itself does) you want to bundle your dependencies. Please note that yarn et al don't support that. You may also be thinking of a shrinkwrap which does what you are describing.

@klebba
Copy link
Author

klebba commented Feb 29, 2024

Thanks for your reply. Yarn does support what I want; I already use it like this:

yarn install ./my-cli-tool-written-in-nodejs --global --frozen-lockfile

According to npm ci docs the command should satisfy the use case:

This command is similar to npm install, except it's meant to be used in automated environments such as test platforms, continuous integration, and deployment --

or any situation where you want to make sure you're doing a clean install of your dependencies.

The project must have an existing package-lock.json or npm-shrinkwrap.json.

Yes

If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.

Yes

npm ci can only install entire projects at a time: individual dependencies cannot be added with this command.

Yes

If a node_modules is already present, it will be automatically removed before npm ci begins its install.

Yes

It will never write to package.json or any of the package-locks: installs are essentially frozen.

Yes

Thanks for pointing out npm shrinkwrap — this does seem like what I need. In fact now it's not clear to me why I would use npm ci instead of npm install if I want to adhere to lockfile contents. I guess something about whether or not the lockfile is publishable?

I could update this ticket or open another with adjusted suggestions:

  1. Update the npm ci command docs to indicate that npm ci is not/will never be able to install packages globally, instead refer users to adopt npm shrinkwrap and use npm install to accomplish this task.
  2. Consider addressing / reconciling these two confusing statements:

use npm ci when you need to strictly adhere to the contents of your lockfile defined in package-lock.json OR npm-shrinkwrap.json for a local install

use npm install when you need to strictly adhere to the contents of your lockfile defined ONLY in npm-shrinkwrap.json for a global install

As I write this I also wonder: why can't I use npm install to strictly adhere to my package-lock.json (e.g. frozen install)?

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 10.x
Projects
None yet
Development

No branches or pull requests

3 participants