nvm-sh / nvm

Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions
MIT License
79.67k stars 7.97k forks source link

Allow other package managers for `default-packages` installation #2169

Open muuvmuuv opened 4 years ago

muuvmuuv commented 4 years ago

I have recently switched to pnpm and would like to install my default global packages to be installed with it instead of npm to avoid alias issues. Same goes for people that prefers yarn.

ljharb commented 4 years ago

Neither ships with node, however.

nvm requires npm (which ships with node, so it always exists) for a number of things. It’d be a lot of added complexity to allow an alternative - especially since the command name and structure is different, at least for yarn - and it would be highly inappropriate to hardcode handling specific nonstandard package manager CLIs.

muuvmuuv commented 4 years ago

In case of pnpm, it would just require npm i -g pnpm after that everything is just mapping actions like install => add. For example have a look at my PR at ionic CLI: https://github.com/ionic-team/ionic-cli/pull/4330

For yarn<2 I guess this should be the same, all above 2 (so speaking of berry) requires more work, sure.

I see your point but saying "nonstandard package manager" is wrong. This just forces everyone to use NPM here and IMO this should be a user choice. Yarn at least is highly used by many developers and pnpm goes into a good direction too. Sure both are not integrated into Node but this has other reasons and is a personal choice.

Maybe we can do that just for that one use case. NVM can still use NPM for internal stuff but let the user choose a different PM for the default-packages file. This would just require minimal mapping for npm install and one installation step before parsing the file.

  1. check PM choice => pnpm
  2. install different PM => npm install --global pnpm
  3. get install command => pnpm add --global
  4. parse list
  5. install packages
ljharb commented 4 years ago

If you believe it should be a user choice, convince node to make it one - nvm is a node version manager, node only ships with npm.

muuvmuuv commented 4 years ago

Sure, Good point but I think the development circle at Node is larger than at NVM. There are already issues at Node about Yarn to be the default package manager but closed because of too little attention, and they had been opened years ago where yarn and pnpm haven't been that popular.

At least even if they would add it, NVM would need an option for it as well, so I would leave this issue open until Node supports selecting a different PM.

ljharb commented 4 years ago

If node adds support for that, then nvm would be forced to to maintain compatibility :-)

(I'm not sure the issue needs to stay open if that's the way forward)

muuvmuuv commented 4 years ago

Upstream issue: https://github.com/nodejs/node/issues/15244

OlaoluwaM commented 1 year ago

In the meantime, here is a workaround I current use. These functions can be added to your shell config files (.zshrc or .bashrc, etc.). Feel free to customize as needed. Though note that I use >| instead of > because I have > set such that it fails if the file already exists, >| is a temporary override: https://askubuntu.com/a/236521

function backupGlobalNpmPkgs() {
  pnpm ls -g | tail --lines +6 | awk '{print $1}' >|"$DOTS/npm/global-npm-pkgs.txt"
}

function installBackedUpGlobalNpmPkgs() {
  while read -r line; do
    pnpm add -g $line
  done <"$DOTS/npm/global-npm-pkgs.txt"
}

function uninstallBackedUpGlobalNpmPkgs() {
  while read -r line; do
    pnpm rm -g $line
  done <"$DOTS/npm/global-npm-pkgs.txt"
}

function updateNodeTo() {
  nextNodeVer="$1"
  prevNodeVer="$(node -v)"

  echo -e "Backing up global npm packages...\c"
  backupGlobalNpmPkgs
  echo "Done!"

  echo "Removing global npm packages for current node version..."
  uninstallBackedUpGlobalNpmPkgs

  echo "Installing latest node version..."
  nvm install "$nextNodeVer" --latest-npm
  nvm alias default "$nextNodeVer"
  echo -e "Installation complete\n"

  echo "Reinstalling pnpm..."
  corepack enable
  corepack prepare pnpm@latest --activate
  echo -e "Done\n"

  echo -e "Finalizing pnpm installation...\c"
  sleep 2
  echo "Done!"

  echo "Reinstalling global packages from previous node version with pnpm..."
  installBackedUpGlobalNpmPkgs
  echo -e "Done!\n"

  echo "Removing previous node version..."
  nvm uninstall "$prevNodeVer"
  echo "Done!"
}