React 热重载在 docker 容器中不起作用
React hot reload doesn't work in docker container
我正在尝试使用 docker 设置 React,但由于某种原因我无法让热重载工作。目前,如果我创建一个文件,它会重新编译,但如果我更改文件中的某些内容,它不会。另外,我没有更改任何包或配置文件,项目是用 npx create-react-app projectname --template typescript
.
生成的
通过在线研究,我发现我需要将 CHOKIDAR_USEPOLLING=true
添加到 .env 文件中,我试过了但没有用,我尝试将 .env 放在所有目录中以防万一把它放在错误的地方。我还将它添加到 docker-compose.yml 环境中。
除此之外,我还尝试将 react-scripts 降级到 4.0.3,因为我发现 this,这也没有用。
我还尝试在本地更改文件,然后检查它是否也在 docker 容器内更改,确实如此,所以我很确定我的 docker 相关文件是正确的。
版本
- 节点 16.14
- Docker 桌面版 4.5.1 (Windows)
- 反应 17.0.2
- 反应脚本 5.0.0
目录结构
project/
│ README.md
│ docker-compose.yml
│
└───frontend/
│ Dockerfile
│ package.json
│ src/
│ ...
Docker文件
FROM node:16.14-alpine3.14
WORKDIR /app
COPY package.json .
COPY package-lock.json .
RUN npm install
CMD ["npm", "start"]
docker-compose.yml
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
volumes:
- "./frontend:/app"
- "/app/node_modules"
environment:
CHOKIDAR_USEPOLLING: "true"
我曾经遇到过同样的问题,这个问题在我的 Dockerfile 中工作目录是 /var/app/ 而在我的 docker-compose.yml 中我将当前工作目录安装到 /var/app/frontend,我刚刚删除了那个 /frontend 并且工作正常。请检查你的。谢谢
您拥有的 Dockerfile 非常适合将您的应用程序打包到容器中以准备部署。如果您希望将源放在容器之外并让 运行ning 容器对源中的更改做出反应,这对于开发来说不是很好。
我所做的是保留用于打包应用程序的 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"
如您所见,它只是 运行 一个标准节点图像。让我来看看命令的不同部分:
-u 1000:1000
1000是我在主机上的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"
的命令,它首先安装任何依赖项,然后 运行s package.json 文件中的开发脚本。该脚本以热重新加载的模式启动节点。
如果您使用 Windows 并使用 react-scripts 5.x.x 或更高版本,则 CHOKIDAR_USEPOLLING 无法正常工作。按以下方式更改您的 package.json:
"scripts": {
...
"start": "WATCHPACK_POLLING=true react-scripts start",
...
}
轮询不是我的问题——观察 docker 输出我发现它重新编译正确。我的问题与热加载器中的网络有关。我发现浏览器正在尝试打开一个 websocket 返回到节点服务器 ws://localhost:3000/sockjs-node
但无论我的计算机上的网络设置如何,这都不会路由回 docker 容器。我加了
WDS_SOCKET_HOST=127.0.0.1
到环境变量。重启后浏览器成功连接ws://127.0.0.1:3000/sockjs-node
,热重载正常
这与使用类似于原始 post 的 docker-compose 解决方案有关。我也可以使用 docker 运行 方法的变体来制作东西,但启动速度要慢得多。
我正在尝试使用 docker 设置 React,但由于某种原因我无法让热重载工作。目前,如果我创建一个文件,它会重新编译,但如果我更改文件中的某些内容,它不会。另外,我没有更改任何包或配置文件,项目是用 npx create-react-app projectname --template typescript
.
通过在线研究,我发现我需要将 CHOKIDAR_USEPOLLING=true
添加到 .env 文件中,我试过了但没有用,我尝试将 .env 放在所有目录中以防万一把它放在错误的地方。我还将它添加到 docker-compose.yml 环境中。
除此之外,我还尝试将 react-scripts 降级到 4.0.3,因为我发现 this,这也没有用。
我还尝试在本地更改文件,然后检查它是否也在 docker 容器内更改,确实如此,所以我很确定我的 docker 相关文件是正确的。
版本
- 节点 16.14
- Docker 桌面版 4.5.1 (Windows)
- 反应 17.0.2
- 反应脚本 5.0.0
目录结构
project/
│ README.md
│ docker-compose.yml
│
└───frontend/
│ Dockerfile
│ package.json
│ src/
│ ...
Docker文件
FROM node:16.14-alpine3.14
WORKDIR /app
COPY package.json .
COPY package-lock.json .
RUN npm install
CMD ["npm", "start"]
docker-compose.yml
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
volumes:
- "./frontend:/app"
- "/app/node_modules"
environment:
CHOKIDAR_USEPOLLING: "true"
我曾经遇到过同样的问题,这个问题在我的 Dockerfile 中工作目录是 /var/app/ 而在我的 docker-compose.yml 中我将当前工作目录安装到 /var/app/frontend,我刚刚删除了那个 /frontend 并且工作正常。请检查你的。谢谢
您拥有的 Dockerfile 非常适合将您的应用程序打包到容器中以准备部署。如果您希望将源放在容器之外并让 运行ning 容器对源中的更改做出反应,这对于开发来说不是很好。
我所做的是保留用于打包应用程序的 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"
如您所见,它只是 运行 一个标准节点图像。让我来看看命令的不同部分:
-u 1000:1000
1000是我在主机上的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"
的命令,它首先安装任何依赖项,然后 运行s package.json 文件中的开发脚本。该脚本以热重新加载的模式启动节点。
如果您使用 Windows 并使用 react-scripts 5.x.x 或更高版本,则 CHOKIDAR_USEPOLLING 无法正常工作。按以下方式更改您的 package.json:
"scripts": {
...
"start": "WATCHPACK_POLLING=true react-scripts start",
...
}
轮询不是我的问题——观察 docker 输出我发现它重新编译正确。我的问题与热加载器中的网络有关。我发现浏览器正在尝试打开一个 websocket 返回到节点服务器 ws://localhost:3000/sockjs-node
但无论我的计算机上的网络设置如何,这都不会路由回 docker 容器。我加了
WDS_SOCKET_HOST=127.0.0.1
到环境变量。重启后浏览器成功连接ws://127.0.0.1:3000/sockjs-node
,热重载正常
这与使用类似于原始 post 的 docker-compose 解决方案有关。我也可以使用 docker 运行 方法的变体来制作东西,但启动速度要慢得多。