React 热重载在 docker 容器中不起作用

bor*_*res 16 docker reactjs docker-compose

我正在尝试使用 docker 设置 React,但由于某种原因我无法让热重载工作。目前,如果我创建一个文件,它会重新编译,但如果我更改文件中的某些内容,它不会重新编译。另外,我没有更改任何包或配置文件,该项目是使用npx create-react-app projectname --template typescript.

\n

通过在线研究,我发现我需要添加CHOKIDAR_USEPOLLING=true到 .env 文件,我尝试了这一点,但它不起作用,我尝试将 .env 放置在所有目录中,以防我将其放置在错误的目录中。我还将它添加到 docker-compose.yml 环境中。

\n

除此之外,我还尝试将react-scripts降级到4.0.3,因为我发现这个也不起作用。

\n

我还尝试在本地更改文件,然后检查它是否也在 docker 容器内发生更改,确实如此,所以我很确定我的 docker 相关文件是正确的。

\n

版本

\n
    \n
  • 节点 16.14
  • \n
  • Docker 桌面 4.5.1(Windows)
  • \n
  • 反应17.0.2
  • \n
  • 反应脚本 5.0.0
  • \n
\n

目录结构

\n
project/\n\xe2\x94\x82   README.md\n\xe2\x94\x82   docker-compose.yml    \n\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80frontend/\n    \xe2\x94\x82   Dockerfile\n    \xe2\x94\x82   package.json\n    \xe2\x94\x82   src/\n    \xe2\x94\x82   ...\n\n
Run Code Online (Sandbox Code Playgroud)\n

Dockerfile

\n
FROM node:16.14-alpine3.14\n\nWORKDIR /app\n\nCOPY package.json .\nCOPY package-lock.json .\nRUN npm install \n\nCMD ["npm", "start"]\n
Run Code Online (Sandbox Code Playgroud)\n

docker-compose.yml

\n
services:\n  frontend:\n    build: ./frontend\n    ports:\n      - "3000:3000"\n    volumes:\n      - "./frontend:/app"\n      - "/app/node_modules"\n    environment:\n      CHOKIDAR_USEPOLLING: "true"\n
Run Code Online (Sandbox Code Playgroud)\n

小智 36

如果您使用的是 Windows 并使用 React-scripts 5.xx 或更高版本,则 CHOKIDAR_USEPOLLING 不起作用。按以下方式更改 package.json:

    "scripts": {
    ...
    "start": "WATCHPACK_POLLING=true react-scripts start",
    ...
  }
Run Code Online (Sandbox Code Playgroud)

  • 在 docker-compose 中的 nodejs-instance 中添加了“WATCHPACK_POLLING=true”作为环境,热重载对我有用,现在我什至不需要重新加载网站,内容在编辑和保存文件后自动刷新。谢谢! (3认同)

Han*_*ian 9

当您想要将应用程序打包到容器中以准备部署时,您拥有的 Dockerfile 非常有用。这对于开发来说不太好,因为您希望将源代码放在容器之外并让正在运行的容器对源代码中的更改做出反应。

我所做的就是保留用于打包应用程序的 Dockerfile,并且仅在完成后才构建它。

在开发时,我通常可以完全不需要 dockerfile,只需运行一个容器并将源代码映射到其中即可。

例如,这是我用来运行节点应用程序的命令

docker run -u=1000:1000 -v $(pwd):/app -w=/app -d -p 3000:3000 --rm --name=nodedev node bash -c "npm install && npm run dev"
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它只运行一个标准的节点映像。让我详细介绍一下该命令的不同部分:

-u 1000:10001000是我在主机上的UID和GID。通过使用相同的 ID 运行容器,容器创建的任何文件都将在主机上归我所有。

-v $(pwd):/app将当前目录映射到容器中的/app目录

-w /app将容器中的工作目录设置为/app

-d分离运行

-p 3000:3000将容器中的3000端口映射到主机上的3000端口

--rm当容器退出时将其移除

-name=nodedev给它一个名字,这样我就可以杀死它而不用查找名字

最后有一个容器命令,bash -c "npm install && npm run dev"它首先安装任何依赖项,然后运行 ​​package.json 文件中的开发脚本。该脚本以热重载的模式启动节点。


Car*_*and 7

轮询不是我的问题——观察 docker 输出,我发现它重新编译正确。我的问题与热加载器中的网络有关。我发现浏览器正在尝试打开一个返回节点服务器的 websocket,ws://localhost:3000/sockjs-node但无论我的计算机上的网络设置如何,这都不会路由回 docker 容器。我添加了

WDS_SOCKET_HOST=127.0.0.1
Run Code Online (Sandbox Code Playgroud)

到环境变量。重启后浏览器连接成功ws://127.0.0.1:3000/sockjs-node,热重载正常。

这与使用类似于原始帖子的 docker-compose 解决方案有关。我还可以使用 docker run 方法的变体来制作东西,但启动速度要慢得多。