Windows Subsystem for Linux (WSL) using shared Node.js installation with Windows: Node.js npm & npx binaries not working

非 Y 不嫁゛ 提交于 2020-07-06 19:56:31

问题


I have recently moved to a Windows + WSL environment (WSL is going very good by the way). The main reason of doing this is to have a Linux environment for development and having Windows for other apps & games without having to reboot my computer (had a dual-boot setup before).

In the setup process, I found most of the Windows installed binaries can be executed from WSL. So instead of duplicating installations (eg: installing java and maven in Windows in order to use Eclipse IDE and then installing it in WSL separately to use it in the terminal) I could just install java jdk in Windows and symlink the binaries to WSL in order to share the jdk installation, this worked flawlessly). But doing the same with node, happens that node npm and npx binaries are not working :(

I wannted to have a single node installation which I could manage using using nvm windows. So I started the installation the following way:

In WSL, I configured my /etc/wsl.conf, following Nick Janetakis guide here (thanks Nick) in order to mount Windows drives at / instead of /mnt/:

/etc/wsl.conf

[automount]
root = /
options = "metadata"

Then installed node in 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

Everything working as expected so far. The next step is to symlink the windows node binaries to WSL. The binaries are located at:

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

So inside WSL terminal (remember that my disks are mounted at /c not /mnt/c as the default behaviour):

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

And...

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

Great! (Note: as node is installed on windows, when being on WSL you must use it inside a disk drive, /d in this case). But...

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)

Now that's the reason I'm writing this. The error is clear, npm is trying to find npm-cli.js in a path which is a wired mix of the npm symlink location inside a windows path.

Is there a way to tell npm/npx the correct Windows path where it must find its files from WSL?

Sorry for the long question but due to the very particular setup I considered that contextualization necessary.


回答1:


I have my own development environment, so I couldn't test it on the same environment of yours. But, I suggest that you should check whether npm under "Program Files" works well on WSL.

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

In my case, another error occurs when running above command.

Error: EINVAL: invalid argument, uv_pipe_open

If it is the same on your environment, you may solve this issue first.

And, about module path issue, it seems to be caused by path; the original npm(under Program Files) and your symbolic link have different current path.

I modified the original npm as below:

#!/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
...

If you run the original npm and your symbolic link, $basedir will shows different results, and it causes module path issue.

If you can solve the first issue(uv_pipe_open error), how about adding the nodejs directory on your path instead of symbolic links?




回答2:


Any workaround? I have met the same situation where I hope to share the same node and npm between WSL and Windows, as I want to run them in a terminal (WSL) and in IDEA (Windows) at the same time.

I found that npm cannot be run through drviers, like using npm under C:/, which has been installed under F:/, resulting in an error:

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)

However, we always work in one driver, which means we can install npm under the common used driver (F:/ for me), and make an alias to run it inside the driver via relative path:

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


来源:https://stackoverflow.com/questions/54034404/windows-subsystem-for-linux-wsl-using-shared-node-js-installation-with-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!