Skip to content
New issue

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

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

Already on GitHub? # to your account

How to install global npm tools that are available across all node versions #109

Closed
nikitavoloboev opened this issue Jun 4, 2019 · 23 comments

Comments

@nikitavoloboev
Copy link

Say I ran npm install --global prettier

It gets installed into Users/nikivi/.fnm/node-versions/latest/installation/lib since I am currently using latest version of node (fnm use latest).

But if I fnm use v10.15.0 and run npm list -g --depth 0. I dont get any packages. This is very annoying.

Is it possible to make it so that all globally installed packages I have are available to me no matter what node version I use?

@ljharb
Copy link

ljharb commented Jun 4, 2019

It’s a very very bad idea to share global installs across node versions, and it won’t even work most of the time due to incompatibilities across node versions.

@nikitavoloboev
Copy link
Author

So I guess the best idea is to make sure to install things on latest and when switching node versions for specific projects, forget about globally installed tools until you go back to latest.

I don't want to install tools 2 or 3 times for each node version. :(

@ljharb
Copy link

ljharb commented Jun 4, 2019

In general I’d recommend not installing anything globally anyways - everything should be installed locally per project.

@Schniz
Copy link
Owner

Schniz commented Jun 5, 2019

I agree with @ljharb - I don't use global installations and I'm okay with it. When I really want to make something global, I have a ~/npmbin directory that I install stuff there, but it is mostly empty (other than esy/pesy and @ranyitz's qnm). Try to avoid global installations at all costs, especially with projects like Prettier, which actually change your code. You don't want to run an old version of Prettier or to mismatch the project format, right?

I thought about making a different binary, and providing something like gnpm --node=v10 prettier, and then it'd install on that specific Node and use this binary to run prettier. But I think it's out of fnm scope, and I'd love to see an open source that does it and uses fnm underneath. I'm ready to assist with anything we need to support this, whether it's in just programming in ReasonML or to add some commands to fnm to support getting data out of it (fnm inspect versions --format=json or something)

@Schniz Schniz closed this as completed Jun 5, 2019
@Schniz
Copy link
Owner

Schniz commented Jun 5, 2019

If you need any help, ping me on the Twitter, Reason Discord, Email, whatever! I'd be happy to help 😄

@nikitavoloboev
Copy link
Author

If I install my global packages under latest and then decide to update latest, first of all, how would I do that? Is it by running fnm install latest again?

And if I do run it again and supposedly latest node version will be upgraded, I still keep all my global npm tools? (npm list -g --depth 0)

@Schniz
Copy link
Owner

Schniz commented Jun 5, 2019

fnm doesn't store latest anywhere: it is a link to the latest version in https://nodejs.org/dist:

✡ ~/Code  FNM_LOGLEVEL=debug fnm install latest
Looking for node latest for darwin x64
Downloading https://nodejs.org/dist/latest/node-v12.4.0-darwin-x64.tar.xz to /Users/galsc/.fnm/downloads/v12.4.0.tar.xz
Extracting /Users/galsc/.fnm/downloads/v12.4.0.tar.xz to /Users/galsc/.fnm/node-versions/v12.4.0
Version v12.4.0 was successfuly downloaded

I think you better off have a $HOME/npmbin directory and add $HOME/npmbin/node_modules/.bin to your $PATH. That would be the easiest way possible to achieve what you want 😄

@nikitavoloboev
Copy link
Author

I think you better off have a $HOME/npmbin directory and add $HOME/npmbin/node_modules/.bin to your $PATH

How do I then install stuff to it with npm install -g?

@nikitavoloboev
Copy link
Author

Also for some reason all my globally installed packages now live here:

var/folders/5l/5s7qw5ld1xxglm0094_hyh_c0000gn/T/fnm-shell-5057514/bin

i.e. var/folders/5l/5s7qw5ld1xxglm0094_hyh_c0000gn/T/fnm-shell-5057514/bin/prettier or /var/folders/5l/5s7qw5ld1xxglm0094_hyh_c0000gn/T/fnm-shell-5057514/bin/npm .

I didn't change anything.

I would expect them to live under /Users/nikivi/.fnm/current/bin

@nikitavoloboev
Copy link
Author

Also this fails:

~/.fnm
❯ fnm ls
The following versions are installed:
* system
* v10.15.0 (default)
* latest

~/.fnm
❯ fnm default latest
fnm: unknown command `default'.
Usage: fnm COMMAND ...
Try `fnm --help' for more information.

~/.fnm
❯ fnm --version
1.11.0

~/.fnm

Although I believe default option should already be in 1.11.

@nikitavoloboev
Copy link
Author

I also don't get how or why /var/folders/5l/5s7qw5ld1xxglm0094_hyh_c0000gn/T/fnm-shell-5057514/bin was injected into my $PATH.

@Schniz
Copy link
Owner

Schniz commented Jun 6, 2019

for some reason all my globally installed packages now live here:

var/folders/5l/5s7qw5ld1xxglm0094_hyh_c0000gn/T/fnm-shell-5057514/bin

i.e. var/folders/5l/5s7qw5ld1xxglm0094_hyh_c0000gn/T/fnm-shell-5057514/bin/prettier or /var/folders/5l/5s7qw5ld1xxglm0094_hyh_c0000gn/T/fnm-shell-5057514/bin/npm .

I didn't change anything.

I would expect them to live under /Users/nikivi/.fnm/current/bin

I also don't get how or why /var/folders/5l/5s7qw5ld1xxglm0094_hyh_c0000gn/T/fnm-shell-5057514/bin was injected into my $PATH.

This is how fnm works with multiple shells (--multi). Every new shell creates a new symlink on a temp directory that links to the current Node version. This is how we get very easy, performant and "native" way to use different Node versions across multiple shells. realpath /var/folders/5l/5s7qw5ld1xxglm0094_hyh_c0000gn/T/fnm-shell-5057514/bin will show you where it is really linked to.

How do I then install stuff to it with npm install -g?

You don't, you install in that specific directory. This is easier to understand and maintain over global installations which always feel clunky and problematic. You can make a bash function like:

npmig() {
  cd $HOME/npmbin
  npm install --save $@
  cd -
}

Although I believe default option should already be in 1.11.

I just released 1.12 which has this feature 😄

@nikitavoloboev
Copy link
Author

just released 1.12 which has this feature

can you update brew formula too? :)

@nikitavoloboev
Copy link
Author

npmig() {
cd $HOME/npmbin
npm install --save $@
cd -
}

This is very handy, thanks

@nikitavoloboev
Copy link
Author

npmig() {
cd $HOME/npmbin
npm install --save $@
cd -
}

Is it possible to uninstall things from this directory via npm -g uninstall <name> command?

And is it possible to make npm list -g --depth 0 work with this approach?

@Luxcium
Copy link

Luxcium commented May 18, 2022

I probably did not read enough but can someone point to me how to automate the reinstallation of npm packages in an automated fashion or point me to the answer is it is stated above and I missed it ???

@webpro
Copy link

webpro commented Dec 16, 2022

This suits my needs:

npm update -g

Note: Globally installed packages are treated as if they are installed with a caret semver range specified.
So if you require to update to latest you may need to run npm install -g [<pkg>...]

From: https://docs.npmjs.com/cli/v9/commands/npm-update#updating-globally-installed-packages

@kud
Copy link

kud commented Aug 22, 2023

I agree with @ljharb - I don't use global installations and I'm okay with it. When I really want to make something global, I have a ~/npmbin directory that I install stuff there, but it is mostly empty (other than esy/pesy and @ranyitz's qnm). Try to avoid global installations at all costs, especially with projects like Prettier, which actually change your code. You don't want to run an old version of Prettier or to mismatch the project format, right?

I thought about making a different binary, and providing something like gnpm --node=v10 prettier, and then it'd install on that specific Node and use this binary to run prettier. But I think it's out of fnm scope, and I'd love to see an open source that does it and uses fnm underneath. I'm ready to assist with anything we need to support this, whether it's in just programming in ReasonML or to add some commands to fnm to support getting data out of it (fnm inspect versions --format=json or something)

I also try to avoid global packages. However, some packages are tools/utils I need anywhere in my shell like those ones (npminstall is a shortcut in my script to install them globally):

npminstall tldr
npminstall nodemon
npminstall jake
npminstall vtop
npminstall http-server
npminstall serve
npminstall hicat # command-line syntax highlighter — https://www.npmjs.com/package/hicat
npminstall figlet-cli
npminstall tmi       # too many images
npminstall trash-cli # can be a conflict with mas dependencies
npminstall svgo
npminstall fraktur           # write with great font
npminstall weinre            # debugger for web pages — http://people.apache.org/~pmuellr/weinre-docs/latest/
npminstall pageres-cli       # responsive website screenshots — https://github.com/sindresorhus/pageres
npminstall npm-check-updates # check if npm modules are updated
npminstall npm-check         # check if npm modules are updated
npminstall npm-upgrade       # check if npm modules are updated
npminstall react-native-cli
npminstall gulp-cli
npminstall markdown-live
npminstall caniuse-cmd
npminstall imagemin
npminstall speed-test
npminstall fast-cli
npminstall localtunnel            # expose localhost to world — https://github.com/localtunnel/localtunnel
npminstall Automattic/cloudup-cli # cloudup
npminstall uncss                  # remove useless css
npminstall how2                   # stackoverflow from the terminal
npminstall iterm2-tab-set         # set iTerm2 tab color, title, and/or badge
npminstall gh-pages               # deploy on gh-pages — https://github.com/tschaub/gh-pages
npminstall diff-so-fancy          # Good-lookin' diffs. Actually… nah… The best-lookin' diffs. — https://github.com/so-fancy/diff-so-fancy
npminstall fkill-cli              # Fabulously kill processes. — https://github.com/sindresorhus/fkill-cli
npminstall import-cost
npminstall gnomon
npminstall lighthouse # Auditing, performance metrics, and best practices for Progressive Web Apps - https://github.com/GoogleChrome/lighthouse
npminstall typescript@next
npminstall prettier
npminstall ntl   # Npm Task List: Interactive cli menu to list/run npm tasks - https://github.com/ruyadorno/ntl
npminstall fkill # Fabulously kill processes. Cross-platform.  - https://github.com/sindresorhus/fkill-cli
npminstall kmdr  # Learn CLI commands with kmdr explain - https://kmdr.sh
npminstall bodybuilder
npminstall fixme
npminstall git-branch-select
npminstall envinfo
npminstall vercel
npminstall jscodeshift
npminstall fx # https://github.com/antonmedv/fx
npminstall zx
npminstall web-ext
npminstall aicommits
npminstall nativefier

How do you manage (install or update) those global packages depending on the node version you use in your shell? Let's say the latest for any shell and the specific version for any node/frontend project? Do I need to install them again for each node version?

@kud
Copy link

kud commented Aug 22, 2023

If I understood well:

When you install a global package while using a specific version of Node.js with fnm, the package is installed in a directory associated with that specific version.

If you install a global package while using the system version of Node.js, it will be accessible from any version of Node.js that you use with fnm. This can have advantages in terms of simplicity, it may also introduce risks if the different Node.js versions are not compatible with the package.

In summary, if you want global packages to be tied to a specific version of Node.js, you should install them while that version is active with fnm. If you want them to be available across all versions, you can install them using the system version of Node.js.

@cow1337killer3
Copy link

There's no reason not to install global npm packages. Any project that relies on a specific version of the package should be specifying that in the package.json, along with the node version etc

@jedwards1211
Copy link

There are definitely some little helper commands I write for Node that I want to be on my PATH so I can run them anywhere. Not tool like prettier that would be a bad idea to install globally, just helper commands I use that run manually to accomplish various things.

It would be great to have some tool that simplifies picking/installing a compatible version of Node for such commands and running them with that version, even if I've activated a different version in my current shell session. There are probably ways I could manage that with my own bin scripts, but if a tool like nvm or fnm provided a helper for it, it would be awesome. It's up to users to know when it's wise to install a command globally versus within a specific project.

@trallnag
Copy link

but if a tool like nvm or fnm provided a helper for it, it would be awesome.

Volta supports this https://docs.volta.sh/guide/understanding#managing-your-toolchain

@Tylopilus
Copy link

there are lots of reasons to install global packages, most of them are CLI's. e.g. https://www.npmjs.com/package/yalc and so on.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants