适用于 Linux 的 Windows 子系统 (WSL) 使用与 Windows 共享的 Node.js 安装:Node.js npm 和 npx 二进制文件不起作用

Seb*_*que 5 ubuntu node.js npm windows-10 windows-subsystem-for-linux

我最近搬到了 Windows + WSL 环境(顺便说一下,WSL 进展得非常好)。这样做的主要原因是拥有一个用于开发的 Linux 环境,并拥有用于其他应用程序和游戏的 Windows,而无需重新启动我的计算机(之前有一个双启动设置)。

在安装过程中,我发现大多数 Windows 安装的二进制文件都可以从 WSL 执行。因此,不是重复安装(例如:在 Windows 中安装 java 和 maven 以使用 Eclipse IDE,然后在 WSL 中单独安装它以在终端中使用它)我可以在 Windows 中安装 java jdk 并将二进制文件符号链接到 WSL共享 jdk 安装,这完美无缺)。但是对 node 做同样的事情,发生 node npm 和 npx 二进制文件不起作用:(

我想要一个可以使用nvm windows管理的单节点安装。所以我通过以下方式开始安装:

在 WSL 中,我配置了我的/etc/wsl.conf,遵循Nick Janetakis 指南(感谢Nick),以便将 Windows 驱动器安装在/而不是/mnt/

/etc/wsl.conf

[automount]
root = /
options = "metadata"
Run Code Online (Sandbox Code Playgroud)

然后在windows中安装节点:

C:\Windows\system32> nvm install 10.15.0
... installing process...
C:\Windows\system32> nvm use 10.15.0
...success message...
C:\Windows\system32> node -v
v10.15.0
C:\Windows\system32> npm -v
6.4.1
Run Code Online (Sandbox Code Playgroud)

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

C:\Windows\system32> where node
C:\Program Files\nodejs\node.exe

C:\Windows\system32> where npm
C:\Program Files\nodejs\npm
C:\Program Files\nodejs\npm.cmd

C:\Windows\system32>where npx
C:\Program Files\nodejs\npx
C:\Program Files\nodejs\npx.cmd
Run Code Online (Sandbox Code Playgroud)

所以在 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
Run Code Online (Sandbox Code Playgroud)

和...

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
Run Code Online (Sandbox Code Playgroud)

伟大的!(注意:由于节点安装在 Windows 上,因此在 WSL 上时,您必须在磁盘驱动器中使用它,在这种情况下为 /d)。但...

user@host:~$ npm -v
internal/modules/cjs/loader.js:583
throw err;
^

Error: Cannot find module 'C:\home\user\bin\node_modules\npm\bin\npm-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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

Ans*_*ark 0

我有自己的开发环境,所以无法在你的相同环境上进行测试。但是,我建议您检查“Program Files”下的 npm 在 WSL 上是否运行良好。

user@host:~$ /c/Program\ Files/nodejs/npm -v
Run Code Online (Sandbox Code Playgroud)

就我而言,运行上述命令时会发生另一个错误。

Error: EINVAL: invalid argument, uv_pipe_open
Run Code Online (Sandbox Code Playgroud)

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

并且,关于模块路径问题,似乎是由路径引起的;原始的 npm(在 Program Files 下)和您的符号链接具有不同的当前路径。

我将原来的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
...
Run Code Online (Sandbox Code Playgroud)

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

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