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

Posted

技术标签:

【中文标题】适用于 Linux (WSL) 的 Windows 子系统使用与 Windows 共享的 Node.js 安装:Node.js npm 和 npx 二进制文件不起作用【英文标题】:Windows Subsystem for Linux (WSL) using shared Node.js installation with Windows: Node.js npm & npx binaries not working 【发布时间】:2019-05-30 18:11:08 【问题描述】:

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

在设置过程中,我发现大多数 Windows 安装的二进制文件都可以从 WSL 执行。因此,我可以在 Windows 中安装 java jdk 并将二进制文件符号链接到 WSL共享 jdk 安装,这完美无瑕)。 但是对节点做同样的事情,节点 npm 和 npx 二进制文件不工作:(

我想要一个单节点安装,我可以使用 nvm windows 来管理它。所以我开始安装如下:

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

/etc/wsl.conf

[automount]
root = /
options = "metadata"

然后在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

到目前为止一切正常。下一步是将 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

所以在 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

太棒了! (注意: 由于 node 安装在 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)

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

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

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

【问题讨论】:

【参考方案1】:

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

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

internal/modules/cjs/loader.js:638
    throw err;
    ^

Error: Cannot find module 'C:\f\Users\aleen\AppData\Roaming\nvm\v10.21.0\node_modules\npm\bin\npm-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)

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

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

export -f npm

【讨论】:

已创建问题告诉Node:github.com/nodejs/node/issues/34165【参考方案2】:

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

但是,当我按照here 的说明进行操作时,我确实设法让它工作了。请注意,它说它适用于 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

【讨论】:

Ben,在你经历了这个过程之后,npx 对你有用吗?我使用类似的方法在 Ubuntu 中安装 nvm 和 node,与我在 Windows 中安装 nvm 和 node 是分开的。问题是来自 Ubuntu 终端的“which npx”仍然以“/mnt/c/Program Files/nodejs/npx”响应。尝试在 Ubuntu 中运行 npx 会导致错误“/mnt/c/Program Files/nodejs/npx: bin/sh^M: bad intrepreter: No such file or directory”。但是,在 Ubuntu 中运行“哪个节点”会以“/usr/bin/node”响应,当我执行节点命令时,一切似乎都正常。 嗨@Lazor。当我按照这些步骤操作时,我能够让 nvm(和节点)工作,尽管我认为我没有尝试过 npx。然而,当我在 WSL 中做这项工作时,我发现 WSL 是将 Windows 路径添加到 linux 路径的罪魁祸首。幸运的是,当我发布 here 时,WSL 有办法阻止这种行为。希望这会有所帮助! 嗨,本,感谢您的帮助。老实说,我不记得发生了什么变化,但我在 Windows 10 上重新安装了 Ubuntu,一切正常。在安装 nvm 和最新版本的 Node JS 后,npm 和 npx 都可以工作。 这是个好消息@Lazor。我有类似的问题,所以我知道你的感受(以及当你开始工作时的解脱!)【参考方案3】:

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

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

在我的例子中,运行上面的命令时出现另一个错误。

Error: EINVAL: invalid argument, uv_pipe_open

如果你的环境也一样,你可以先解决这个问题。

而且,关于模块路径问题,它似乎是由路径引起的;原始 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
...

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

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

【讨论】:

我建议你检查简单的网络 node.js 程序是否运行良好。我怀疑 Windows 版本的 node.exe 对套接字有不同的实现。 我没有遇到无效参数错误,您使用的是什么设置?使用原始位置的二进制文件以相同的行为结束,但路径不同(WSL 中的窗口)找不到模块'C:\c\Program Files\nodejs\node_modules\npm\bin\npm-cli.js'这里似乎发生了两件事。 npm 脚本无法获取符号链接的规范路径并且具有正确的路径,它需要转换为 Windows 路径:/c/foo/bar/baz > c:/foo/bar/baz。我将尝试修改 npm 脚本来实现这一点。也许这可以成为节点源的 PR? 我在 WSL 上使用 nvm,在 Git Bash 上使用 nvm-windows。 据我所知,Windows 的 Node.js 与 WSL 不完全兼容。并且一些节点模块在 Git Bash 和 WSL 上有不同的实现。所以,我在 WSL 和 Git Bash 上独立设置了 node.js。【参考方案4】:

我所做的是修改了位于 C:\Program Files\nodejs 的 npm bash 文件。

替换这个:

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

有了这个:

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

然后在wsl中保存为unix格式文件。

【讨论】:

以上是关于适用于 Linux (WSL) 的 Windows 子系统使用与 Windows 共享的 Node.js 安装:Node.js npm 和 npx 二进制文件不起作用的主要内容,如果未能解决你的问题,请参考以下文章

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

安装Windows Linux 子系统的方法:适用于windows 11 版本

安装Windows Linux 子系统的方法:适用于windows 11 版本

适用于 Linux 的 Windows 子系统 git mergetool meld UnicodeDecodeError

dockerDocker将运行文件迁移目录

Windows系统中的Linux—WSL安装及简单使用