102

我想使用分发 Node.js 包(或更新版本的chris-lea ppa),但将 NPM 安装到我的主目录。

这可能看起来很挑剔,但对于使用 polyglot/github 的开发人员来说,这是一种非常惯用的方式来在 Linux 下设置语言运行时/库环境:运行时的发行包,每个用户环境中的 3rd-party 库(参见 virtualenv,RVM - RVM如果您愿意,还将为您构建 Ruby)。如有必要,我将在本地构建节点,但它是一个 PITA,因为 Node 正在成为许多项目的附带开发需求。

4

11 回答 11

214

NPM 已经将本地包安装到您的项目中,但我仍然希望系统远离我的操作系统文件。以下是我建议划分 Nodejs 包的方法:

通过 chris-lea PPA 安装 Nodejs 和 NPM。然后我在我的 homedir 中设置了一个包根来保存节点“全局”包:

 $ NPM_PACKAGES="$HOME/.npm-packages"
 $ mkdir -p "$NPM_PACKAGES"

设置 NPM 使用这个目录来安装它的全局包:

 $ echo "prefix = $NPM_PACKAGES" >> ~/.npmrc

通过将以下内容添加到 .zshrc/.bashrc 中,配置 PATH 和 MANPATH 以查看 $NPM_PACKAGES 前缀中的命令:

# NPM packages in homedir
NPM_PACKAGES="$HOME/.npm-packages"

# Tell our environment about user-installed node tools
PATH="$NPM_PACKAGES/bin:$PATH"
# Unset manpath so we can inherit from /etc/manpath via the `manpath` command
unset MANPATH  # delete if you already modified MANPATH elsewhere in your configuration
MANPATH="$NPM_PACKAGES/share/man:$(manpath)"

# Tell Node about these packages
NODE_PATH="$NPM_PACKAGES/lib/node_modules:$NODE_PATH"

现在,当您执行. 时,npm install -gNPM 会将库安装~/.npm-packages/lib/node_modules到.~/.npm-packages/binPATH

npm install -g像往常一样使用:

[justjake@marathon:~] $ npm install -g coffee-script
... (npm downloads stuff) ...
/home/justjake/.npm-packages/bin/coffee -> /home/justjake/.npm-packages/lib/node_modules/coffee-script/bin/coffee
/home/justjake/.npm-packages/bin/cake -> /home/justjake/.npm-packages/lib/node_modules/coffee-script/bin/cake
coffee-script@1.3.3 /home/justjake/.npm-packages/lib/node_modules/coffee-script

[justjake@marathon:~] $ which coffee
/home/justjake/.npm-packages/bin/coffee
于 2012-10-22T23:51:29.777 回答
36

Jake 的答案发布于 2012 年,虽然有用,但它引用了 Chris Lea 的 Node.js PPA,这些 PPA 自 2015 年 3 月以来不再更新。

以下是我在主目录中安装 Node.js 和 npm 的步骤:

使用nvm安装 Node.js (sudo不需要):

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
source ~/.bashrc
nvm install 7
npm install -g npm  # update npm

现在你可以install -g没有sudo,一切都进入~/.nvm/

或者在没有 nvm 的情况下安装 Node.js(官方说明):

安装 Node.js

  • Node.js v6(截至 2017 年 5 月的当前 LTS):

    curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
    sudo apt-get install -y nodejs
    
  • Node.js v7:

    curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
    sudo apt-get install -y nodejs
    

将 npm 的默认目录更改为本地目录:

mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH="$HOME/.npm-global/bin:$PATH"  # ← put this line in .bashrc
source ~/.bashrc  # if you only updated .bashrc

或者替换.npm-global为您选择的目录。

更新 npm 并检查它是否安装在您的$HOME目录中:

$ npm install npm -g
/home/<username>/.npm-global/bin/npm -> /home/<username>/.npm-global/lib/node_modules/npm/bin/npm-cli.js
/home/<username>/.npm-global/lib
└─┬ npm@3.10.6 
  ├─┬ glob@7.0.5 
  │ └── minimatch@3.0.2 
  ├── npm-user-validate@0.1.5 
  └── rimraf@2.5.3 

现在你可以install -g不用sudo和不用弄乱你的系统文件。

于 2016-09-07T15:18:08.953 回答
6

Just Jake 发布的解决方案很棒。但是,由于 npm > 1.4.10 的错误,它可能无法按预期工作。(见这个这个

解决该错误后,您可以按照以下步骤降级到 npm 1.4.10:

  1. 注释 $HOME/.npmrc 中的前缀行
  2. sudo npm install -g npm@1.4.10
  3. 确保安装了正确版本的 npm ( npm --version)
  4. 取消注释 $HOME/.npmrc 中的前缀行
  5. 继续在您的主文件夹中安装您的全局包!。
于 2014-06-26T13:16:51.223 回答
4

因为 python 已经做得很好了virtualenv,所以我使用nodeenv. 与 相比nvm,您可以为相同的节点版本创建多个环境(例如,节点的两个环境0.10但具有不同的包集)。

ENVNAME=dev1

#  create an environment
python -m virtualenv ${ENVNAME}

# switch to the newly created env
source ${ENVNAME}/bin/activate

# install nodeenv
pip install nodeenv

# install system's node into virtualenv
nodeenv --node=system --python-virtualenv

自述文件非常好: https ://github.com/ekalinin/nodeenv

于 2015-01-19T18:33:23.063 回答
3

我使用@just-jake解决方案一段时间,发现nvm更容易设置。它也是非常强大的解决方案,允许安装和使用不同版本的nodejs.

在 Ubuntu 14.04 或 16.04 上:

  1. 安装用于构建的必备软件包nodejs

    sudo apt-get update
    sudo apt-get install build-essential libssl-dev
    
  2. 安装nvm

    curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh | bash
    

    如果有更新版本的 nvm 可用,您可以在nvm站点上找到实际的安装命令。

  3. nvm安装程序会将引导脚本添加到~/.bashrc,因此您需要重新打开终端来运行它,或者执行以下操作:

    source ~/.bashrc
    
  4. 现在你可以安装任何nodejs你喜欢的版本,在它们之间切换等等。

    用于nvm ls-remote列出可用nodejs版本。

    例如,要安装nodejsv4.2.4,请执行以下操作:

    # install v4.2.4
    nvm install v4.2.4 
    # use nodejs v4.2.4 in the current terminal session
    nvm use v4.2.4
    # use v4.2.4 by default in new terminal session
    nvm alias default v4.2.4
    
于 2015-12-25T23:34:06.437 回答
3

其他答案已经过时的解决方案:2020 年的解决方案是使用NPM_CONFIG_PREFIX环境变量。(查看详情

例如,

$ NPM_CONFIG_PREFIX="$HOME/.npm-packages" npm install -g ios-sim
/Users/<name>/.npm-packages/bin/ios-sim -> /Users/<name>/.npm-packages/lib/node_modules/ios-sim/bin/ios-sim
+ ios-sim@9.0.0
added 108 packages from 68 contributors in 3.094s
于 2020-07-22T02:56:06.683 回答
3

如前所述herehere

npm config set prefix ~
echo export PATH=\$PATH:\~/bin >> ~/.bashrc
. ~/.bashrc
于 2016-09-01T21:17:12.807 回答
2

扩展 Just Jake 和 user1533401 提供的答案:我无法降级,因为我使用共享主机并且节点安装在系统目录中。这也是为什么我要更改 npm 安装全局脚本的目录的原因。对于那些在同一条船上的人,这是我发现的另一个临时修复方法:

npm install -g --prefix=$(npm config get prefix) <package>

错误是 npm 不会读取您的每用户配置文件,但每次安装全局脚本时都指定它来修复它。在这里找到。

于 2014-07-27T20:03:11.333 回答
1

对于类似的问题,我有一个稍微不同的解决方案,这是由于我在npm全局安装,所以我可以在我的 macOS 系统的终端中使用它。我只是在我的存储库的根目录中使用以下命令在本地初始化它:

npm init --yes

这使我能够使用“package.json”和“package-lock.json”文件将节点包安装在 /node_modules 的本地根目录中,而不是在用户的主目录中。

于 2021-04-02T16:47:49.707 回答
0

至少在 Ubuntu 上,系统范围的默认配置npmnpm install --global尝试将软件包安装到/usr/lib/node_modules. 要为您自己的用户帐户设置不同的默认值,请运行以下一次:

mkdir -p ~/.npm/lib/bin
npm config set prefix "~/.npm/lib"

此外,您还需要以下片段.profile

# set PATH so it includes user's private .npm/lib/bin if it exists
if [ -d "$HOME/.npm/lib/bin" ] ; then
    PATH="$HOME/.npm/lib/bin:$PATH"
fi

如果您现在安装一些东西,npm install --global packagename它将最终在正确的位置,并且可以在您的 PATH 中找到(您可能需要注销并重新登录才能使.profile更改生效)。

当然,您可以选择其他目录。例如~/.config/npm,可能对现代系统有意义。

于 2021-08-27T13:29:40.023 回答
0

您可以使用npm-user自动设置npm将软件包安装到用户的目录而不是系统的目录中。不需要root特权。

这是脚本的链接,有关如何使用它的说明以及有关其选项的信息。它适用于 macOS、Linux、*BSD 和 Windows。

你可以像这样运行它:

$ curl -s "https://raw.githubusercontent.com/alexdelorenzo/npm-user/main/npm-user.sh" | bash

运行后, usingnpm install -g <package>会将软件包安装到用户的目录中,而无需使用sudo.

如果您想将其复制并粘贴到控制台中,请使用以下代码:

#!/usr/bin/env bash
# Copyright 2022 Alex DeLorenzo <alexdelorenzo.dev>. Licensed under the GPLv3.
export ROOT="${1:-$HOME}"

export NPM_DIR=".npm-packages"
export NPM_ROOT="$ROOT/$NPM_DIR"
export NPM_BIN="$NPM_ROOT/bin"
export NPM_MAN="$NPM_ROOT/share/man"

export BASH_RC="$HOME/.bashrc"
export ZSH_RC="$HOME/.zshrc"
export DEFAULT_RC="$BASH_RC"

export RC_ERR=1
export INDENT=2

set -e

shopt -s expand_aliases

alias indent="paste /dev/null - | expand -$INDENT"


quiet() {
  "$@" &> /dev/null
}


expand-tilde() {
  local path="$1" 
  echo "${path/#\~/$HOME}"
}


create-paths() {
  local bin="${1:-$NPM_BIN}"
  local man="${2:-$NPM_MAN}"

  mkdir --parents --verbose "$bin" "$man"
}


set-prefix() {
  npm config set prefix "$NPM_ROOT"
}


get-vars() {
  local bin="${1:-$NPM_BIN}"
  local man="${2:-$NPM_MAN}"

  cat <<EOF
export PATH="\$PATH:$bin"
export MANPATH="\${MANPATH:-\$(manpath)}:$man"
export NPM_PACKAGES="$NPM_ROOT"
EOF
}


already-added() {
  local rc="${1:-$DEFAULT_RC}"
  local bin="${2:-$NPM_BIN}"
  local man="${2:-$NPM_MAN}"

  local vars="$(get-vars "$bin" "$man")"
  quiet grep "$vars" "$rc"
}


main() {
  local rc="$(expand-tilde "${1:-$DEFAULT_RC}")"
  local bin="$(expand-tilde "${2:-$NPM_BIN}")"
  local man="$(expand-tilde "${3:-$NPM_MAN}")"

  printf "Creating %s and %s\n" "$bin" "$man"
  create-paths "$bin" "$man" || {
    printf "Couldn't create paths: %s and %s.\n" "$bin" "$man" 
    return $RC_ERR
  }
  
  printf "Setting npm prefix.\n"
  set-prefix || {
    printf "Couldn't set prefix.\n"  
    return $RC_ERR
  }

  if ! already-added "$rc" "$bin" "$man"; then
    printf "Writing to %s.\n" "$rc"
    get-vars "$bin" "$man" >> "$rc"
 
  fi || {
    printf "Unable to write to %s.\n" "$rc"
    printf "Add the following to your shell's configuration file:\n\n"

    get-vars "$bin" "$man" | indent
    return $RC_ERR
  }

  printf "Done.\n\n"
  printf "To load the changes in this shell, run:\n"
  printf "\tsource %s\n" "$rc"
}


main "$2" "$3" "$4"
于 2022-02-05T07:54:08.137 回答