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

Posted

技术标签:

【中文标题】如何使 nodemon 与 WSL 2 一起工作?【英文标题】:How can nodemon be made to work with WSL 2? 【发布时间】:2020-12-03 17:46:47 【问题描述】:

自从使用 Windows 10 April 2020 更新从 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`);
);

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

【问题讨论】:

你试过nodemon -L吗? @Simperfy,你说得对,nodemon -L 可以正常工作,谢谢。为什么我需要使用旧版观察者? 在我的回答中添加了“为什么”——事实证明 WSL2 并不完全支持 Windows 文件系统上的 inotify(由 9P 文件系统协议处理)。 【参考方案1】:

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

这就是我的 nodemon 命令的样子:

CHOKIDAR_USEPOLLING=true nodemon index.js

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

【讨论】:

这不是与nodemon -Lnodemon --legacy-watch 在 Simperfy 的原始评论(和我的回答)中提到的效果完全相同,只是需要输入更多内容?但是,如果将环境变量添加到启动脚本中,则可以使用该环境变量在所有会话中将其关闭。 实际上,它对我有用,而传统的手表模式却没有。【参考方案2】:

根本原因:

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

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

可能的解决方法:

    按照 Simperfy 的建议尝试nodemon -L(又名--legacy-watch)。

    尝试从默认的 ext4 文件系统运行(例如 mkdir -p $HOME/Projects/testserver)。请注意,指向 Windows 文件系统的符号链接仍然不起作用。作为奖励,对于像 git 这样的文件密集型操作,WSL ext4 文件系统将更快。 您仍然可以通过 \\wsl$\ 从 Windows 编辑器和工具访问源代码。

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

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

    如果您不需要任何 WSL2 功能,请将会话降级到 WSL1。我保留了 WSL1 和 WSL2 会话。最好的方法是使用wsl --exportwsl --import 创建会话备份。您可以随时使用wsl --set-version 切换 WSL 发行版的版本。 我确实在 WSL1 上使用 Windows 文件系统下的示例项目对此进行了测试,并且在 Windows 下通过诸如 notepad.exe 之类的基本内容进行编辑仍然会触发 nodemon 重新启动。

更长的答案:

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

当我在 WSL/WSL2 创建的默认 /mnt/c 挂载下尝试它时,它也可以正常工作。当然,/mnt/c 在 WSL2 下要慢得多Edit - 原来我在尝试这个时使用的是 Visual Studio Code。从 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 上报告了这方面的错误。

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

【讨论】:

很好的解释,谢谢。正如您所想,它与nodemon --legacy-watch 一样正常工作。你能告诉我如何解决这个问题,这样就不需要传统的观察者了吗? 我执行了cd $HOME/Projects/testserver,然后在没有-l 的情况下运行nodemon,但它再次无法识别文件更改。我应该提到项目是一个符号链接:i.imgur.com/5gzX99G.png 添加了一些除 --legacy-watch 之外的其他解决方法。 此外,符号链接仍然意味着源位于 Windows 文件系统上,并且会出现 inotify 问题(如您所见)。您必须真正使用 WSL2 ext4 文件系统才能获得完整的 inotify 支持。 再次,很好的答案,谢谢。我想提一下,我在导航到 cd $HOME/Projects/testserver 之后(再次 Projects 是一个符号链接),然后在状态栏中输入 code .WSL:Ubuntu 启动 VSCode:i.imgur.com/lv9WQUa.png ,仍然无法识别文件更改(热重载仍然不起作用)。

以上是关于如何使 nodemon 与 WSL 2 一起工作?的主要内容,如果未能解决你的问题,请参考以下文章

Nodemon 与 gulp watch 绑定时崩溃并重新启动两次以上

如何将 nodemon 与 .env 文件一起使用?

如何让 node-inspector 与工头和 nodemon 一起运行?

将 browsersync 与 gulp/nodemon 一起使用

如何使 Zend Framework 2 与 nginx 一起工作?

如何使应用程序与 2 个不同版本的 DLL 一起工作