Windows Subsystem for Linux (WSL) 使用共享 Node.js 使用 Windows 安装:Node.js npm 和 npx 二进制文件不起作用



我最近搬到了Windows+WSL环境中(顺便说一句,WSL运行得很好)。这样做的主要原因是有一个Linux开发环境,并有Windows用于其他应用程序&游戏而不必重新启动我的电脑(以前有双启动设置)。

在安装过程中,我发现大多数Windows安装的二进制文件都可以从WSL执行。因此,我不需要重复安装(例如:在Windows中安装java和maven以使用Eclipse IDE,然后在WSL中单独安装以在终端中使用),我只需要在Windows中使用java jdk,并将二进制文件符号链接到WSL以共享jdk安装,这就完美地工作了)但对节点执行相同操作时,节点npm和npx二进制文件不起作用:(

我想安装一个单节点,可以使用nvm窗口进行管理。所以我以以下方式开始安装:

在WSL中,我按照此处的Nick Janetakis指南配置了我的/etc/WSL.conf(感谢Nick),以便在/而不是/mnt/处安装Windows驱动器:

/etc/wsl.conf

[automount]
root = /
options = "metadata"

然后在windows中安装节点:

C:Windowssystem32> nvm install 10.15.0
... installing process...
C:Windowssystem32> nvm use 10.15.0
...success message...
C:Windowssystem32> node -v
v10.15.0
C:Windowssystem32> npm -v
6.4.1

到目前为止一切都如预期。下一步是将windows节点二进制文件符号链接到WSL。二进制文件位于:

C:Windowssystem32> where node
C:Program Filesnodejsnode.exe
C:Windowssystem32> where npm
C:Program Filesnodejsnpm
C:Program Filesnodejsnpm.cmd
C:Windowssystem32>where npx
C:Program Filesnodejsnpx
C:Program Filesnodejsnpx.cmd

因此,在WSL终端内部(请记住,我的磁盘安装在/c而不是/mnt/c作为默认行为):

user@host:~$ mkdir ~/bin
user@host:~$ ln -s /c/Program Files/nodejs/node.exe ~/bin/node
user@host:~$ ln -s /c/Program Files/nodejs/npm ~/bin/npm
user@host:~$ ln -s /c/Program Files/nodejs/npx ~/bin/npx

而且。。。

user@host:/d/tmp$ node -v
v10.15.0
user@host:/d/tmp$ echo "console.log('Hello World');" >> index.js
user@host:/d/tmp$ node index.js
Hello World

太棒了!(注意:由于节点安装在windows上,所以在WSL上时,您必须在磁盘驱动器中使用它,在这种情况下为/d)。但是

user@host:~$ npm -v
internal/modules/cjs/loader.js:583
throw err;
^
Error: Cannot find module 'C:homeuserbinnode_modulesnpmbinnpm-cli.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
at Function.Module._load (internal/modules/cjs/loader.js:507:25)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)

这就是我写这篇文章的原因。错误很明显,npm试图在一个路径中找到npm-cli.js,该路径是windows路径中npm符号链接位置的有线混合。

有没有办法告诉npm/npx它必须从WSL中找到文件的正确Windows路径?

很抱歉问了这么长的问题,但由于设置非常特殊,我认为上下文化是必要的。

我无法在Windows 10中使用Ubuntu 20.04 LTS在WSL中安装npm。

然而,当我按照这里的指示进行操作时,我确实设法使它发挥了作用。请注意,它说它适用于WSL2,但安装节点的步骤在WSL1环境中是有效的(现在是7月20日,我仍然无法在我的Windows 10版本中获得WSL,嗯!)。

简而言之,这个解决方案可以让您在WSL环境中安装nvm(节点版本管理器)。

sudo apt-get install curl
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash

然后,您可以安装一个新版本的节点,默认情况下带有npm,例如

nvm install --lts

有什么解决方法吗?我遇到过同样的情况,我希望在WSL和Windows之间共享相同的节点和npm,因为我希望同时在终端(WSL)和IDEA(Windows)中运行它们。

我发现npm不能通过drviers运行,比如在C:/下使用npm,它已经安装在F:/下,导致错误:

internal/modules/cjs/loader.js:638
throw err;
^
Error: Cannot find module 'C:fUsersaleenAppDataRoamingnvmv10.21.0node_modulesnpmbinnpm-cli.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
at Function.Module._load (internal/modules/cjs/loader.js:562:25)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)

然而,我们总是在一个驱动程序中工作,这意味着我们可以在常用的驱动程序(对我来说是F:/)下安装npm,并通过相对路径创建一个别名在驱动程序中运行:

# ~/.bash_aliases
function npm() {
$(realpath --relative-to="$(pwd)" /mnt/f/Program Files/nodejs)/npm $@
}
export -f npm

整合和扩展现有答案。。。

首先,这里的主要答案是:

  • 不要尝试在WSL/Linux中使用Windows版本的NodeJS。

    这有几个原因:

    1. Windows的NodeJS工具链将期望(a)Windows路径而不是Linux路径(这个问题中出现的问题)

    2. 即使你解决了这个问题(这就像在风车上倾斜),正如@AnselmoPark在对这个答案的评论中指出的那样:

      一些节点模块在[Windows]和WSL 上有不同的实现

      有关其他信息,请参阅此问题及其答案。

  • 相反,在WSL中安装并使用Linux版本的NodeJS工具链。

    这最终就是BenSmith的答案,但我想扩展一下,在您的Linux发行版下,您可以使用任何支持的NodeJS安装方法。例如,在Ubuntu上,你可以从repo安装(但要确保你的发行版有支持的版本或从PPA安装)。

    就我个人而言,我使用n,但同样,您可以选择您最满意的内容。重要的是在WSL2Linux发行版中安装Linux版本。

次要信息,这些答案中还没有涵盖(但在评论中出现了"仍然不起作用")——如果你同时安装了Windows版本和Linux版本(在WSL中),你可能会遇到@Lazor在评论中对这个答案所做的那样的情况。

问题的出现是因为Windows Node为运行Git Bash的用户提供了npm作为shell脚本。但是,此脚本仍然指向Windows版本的工具。

如果Windows NodeJS在路径中的Linux版本之前出现,那么(当然)它将优先。您需要:

  • 确保Linux版本优先
  • 或者删除Windows版本

请不要按照建议(如此答案)从WSL中完全删除所有Windows路径,因为这将严重限制您在WSL中运行Windows应用程序的能力(WSL的一大功能)。

相反,使用Linuxnvm(或n或其他工具)通常足以将Linux NodeJS目录放在路径中的第一个

我有自己的开发环境,所以我无法在与您相同的环境中进行测试。但是,我建议您应该检查"程序文件"下的npm是否在WSL上运行良好。

user@host:~$ /c/Program Files/nodejs/npm -v

在我的情况下,运行上述命令时会发生另一个错误。

Error: EINVAL: invalid argument, uv_pipe_open

如果您的环境也是如此,您可以先解决这个问题。

而且,关于模块路径问题,它似乎是由路径引起的;原始npm(在程序文件下)和符号链接的当前路径不同。

我修改了原来的npm如下:

#!/bin/sh
(set -o igncr) 2>/dev/null && set -o igncr; # cygwin encoding fix
basedir=`dirname "$0"`
echo $basedir  # Added code
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
...

如果运行原始npm和符号链接,$basedir将显示不同的结果,这会导致模块路径问题。

如果你能解决第一个问题(uv_pipe_open错误),那么在你的路径上添加nodejs目录而不是符号链接怎么样?

我修改了位于C:Program Filesnodejs的npm-bash文件。

替换此:

"$NODE_EXE" "$NPM_CLI_JS" "$@"

有了这个:

"$NODE_EXE" "/Program Files/nodejs/node_modules/npm/bin/npm-cli.js" "$@"

然后将其保存为wsl中的unix格式文件。

最新更新