如何使 nodemon 与 WSL 2 一起工作?

How can nodemon be made to work with WSL 2?

自从使用 Windows 2020 年 4 月 10 日更新从 WSL 1 更新到 WSL 2(然后将 Ubuntu 18 更新到 Ubuntu 20)以来,我一直无法当项目目录中的文件发生更改时,让 nodemon 热重载。当我对 .js 文件进行任何更改时,没有重新启动服务器或在终端输出:

我用 nodemon 启动我的 Node.js 服务器:

NODE_ENV=development DEBUG='knex:*' nodemon --verbose --inspect ./server.js"

如果它有用,这是我的 server.js:

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server started and listening on port ${PORT}`);
});

我什至不确定如何进一步解决此问题以获得有关正在发生的事情的更多有用信息。

根本原因:

WSL2 上的 9P 文件系统协议不完全支持 inotify。

WSL 项目中有几个 github 问题与此相关,但最相关的可能是 #4739

可能的解决方法:

  1. 按照 Simperfy 的建议尝试 nodemon -L (a.k.a. --legacy-watch)。

  2. 尝试从默认的 ext4 文件系统 运行ning(例如 mkdir -p $HOME/Projects/testserver)。请注意,指向 Windows 文件系统的符号链接仍然无效。作为奖励,WSL ext4 文件系统对于像 git 这样的文件密集型操作会快得多。

    您仍然可以通过 \wsl$\ 从 Windows 编辑器和工具访问源代码。

  3. 使用 Visual Studio 代码和 Remote-WSL extension 在 Windows 文件系统上编辑您的源代码。最简单的方法是在 WSL 中导航到您的项目目录,然后 运行ning code ..

    Visual Studio Code 的 WSL 集成确实出于某种原因触发了 inotify。

  4. 如果您不需要任何 WSL2 功能,请将会话降级到 WSL1。我保留了 WSL1 和 WSL2 会话。执行此操作的最佳方法是使用 wsl --exportwsl --import 创建会话备份。您可以随时使用 wsl --set-version 切换 WSL 发行版的版本。

    我确实在 WSL1 上使用 Windows 文件系统下的示例项目对此进行了测试,并且通过 Windows 下的 notepad.exe 之类的基本内容进行编辑仍然会触发 nodemon 重新启动。

更长的答案:

nodemon 在根 (/) ext4 挂载 (例如 $HOME/src/testserver) 上的 WSL2 上为我“开箱即用”。

当我在 WSL/WSL2 创建的默认 /mnt/c 安装下尝试时,它也能正常工作。当然,/mnt/c 在 WSL2 下 慢很多 Edit - 事实证明,我在尝试此操作时使用的是 Visual Studio 代码。从 Windows 文件系统上的其他 Windows 应用程序进行编辑不会触发 nodemon 重新启动。

但是看看你的屏幕截图的第一行,我发现你是从 /c/Users/ 中 运行 宁这个的......我在想也许你创建了这个(也许是 CIFS)挂载尝试解决 WSL2 性能问题 - 这是一个常见的解决方法。

我没有设置 CIFS 挂载,但我能够通过挂载(替换您的 Windows 用户名)重现您的问题:

mkdir $HOME/mnttest
sudo mount -t drvfs 'C:' $HOME/mnttest
cd $HOME/mnttest/Users/Raj/Projects/testserver

运行 nodemon 以与您描述的方式相同的方式从此安装失败 -- 对源的更改未触发重新启动。

然而,运行 nodemon -L 在此挂载上 确实 在更改源文件时触发了重新启动。

也可以通过安装不同的选项来解决这个问题,但我现在还不确定。 编辑 - 似乎不太可能,鉴于 Github.

上的错误报告

此外,您可能想要创建一些 exports/backups WSL 会话。此时为时已晚(对于您之前的安装),但您可以 运行 wsl.exe --export 在升级前创建 Ubuntu 18.04/WSL1 文件系统的备份。您还可以使用 wsl.exe --set-version 更改特定发行版的版本。这可以为您提供更好的“before/after”测试比较。

我正在使用 WSL 2,我通过添加以下环境变量解决了这个问题:CHOKIDAR_USEPOLLING=true.

这就是我的 nodemon 命令:

CHOKIDAR_USEPOLLING=true nodemon index.js

现在您可以保留 WSL2 而不是将您的环境移动到 WSL1。