无法在Docker容器中使用TypeScript启动React [英] Unable to start React with TypeScript in Docker container
问题描述
我正在尝试 npm run start
一个使用-template typescript
创建的React应用程序.因此,已经安装了Typescript(作为React依赖项),但是我的Docker容器抱怨一个通用错误消息,即不会安装TypeScript.因此,我无法在Docker容器中启动应用程序.
I'm trying to npm run start
a React application which was created with --template typescript
.
Typescript is therefore installed (as a React dependency) but my Docker container complains with a generic error message that TypeScript wouldn't be installed. I'm therefore unable to start the application inside a Docker container.
当我在容器外部启动应用程序(使用相同的 package.json
)时,一切正常.
Everything works, when I start the application (with the same package.json
) outside the container.
> frontend@0.1.0 start /app
> react-scripts start
It looks like you're trying to use TypeScript but do not have typescript installed.
Please install typescript by running npm install typescript.
npm ERR! Exit status 1
我通过 npm install typescript
添加了TypeScript,并重建了Docker容器.但它仍然显示错误消息.
I added TypeScript via npm install typescript
and rebuilded the Docker container. But it still shows the error message.
即使手动添加了 typescript
作为依赖项(即使在容器内直接调用 npm install typescript
!),该容器仍抱怨无法找到TypeScript(这似乎不正确,因为我可以验证TypeScript是否已安装在容器内,因为 tsc -version
向我显示了正确的输出).
Even after adding typescript
manually as a dependency (even inside the container with a direct call to npm install typescript
there!), the container complained about not being able to find TypeScript (which doens't seem to be true as I can validate that TypeScript was installed inside the container as tsc -version
shows me the correct output).
我的 Dockerfile
看起来像这样:
FROM node:15.4.0-alpine3.12
# set working directory
ARG app_path=/app
WORKDIR ${app_path}
# add `node_modules/.bin` to $PATH
ENV PATH ${app_path}/node_modules/.bin:$PATH
# set Docker port
EXPOSE 3000
# copy configs, no need to copy src files as they get bind mounted later on (see docker-compose)
COPY package*.json ./
COPY tsconfig.json ./
# install all app dependencies
RUN npm install --silent
# validate typescript installation
RUN tsc --version
我的 docker-compose.yaml
文件如下所示:
version: '3.8'
services:
frontend:
build:
context: ./frontend
dockerfile: ../Dockerfile
image: frontend:dev
container_name: dev_frontend_react
ports:
- 4000:3000
command: ['npm', 'run', 'start']
volumes:
- ${HOST_PROJECT_PATH}/frontend:/app
# add a virtual volume to overwrite the copied node_modules folder as the
# container installs its own node_modules
- node_modules:/app/node_modules
environment:
- NODE_ENV=development
restart: unless-stopped
volumes:
node_modules:
name: frontend_node_modules
同样的问题,无法解决的问题
我在StackOverflow上找到了相同问题的另一种解决方案:要求在构建Docker时安装已经安装的Typescript图片
但是此解决方案是将项目硬复制到容器中并创建实际的构建.但是该解决方案对我来说是不可接受的,因为它阻止了React的热重载功能正常工作.
But this solution is hard-copying the project into the container and creating an actual build. But that solution is not acceptable for me as it prevents the hot reload feature of React from working.
推荐答案
在构建Docker映像期间(即,在Dockerfile中),您正在将依赖项安装到容器内部的 node_modules
文件夹中(运行npm install --silent
).类型脚本( tsc --version
)在安装时起作用.
During Docker image build (i.e. in the Dockerfile) you are installing the dependencies in to the node_modules
folder inside the container (RUN npm install --silent
). Type script (tsc --version
) works as it gets installed there.
稍后,在docker-compose文件中,您要用主机中的文件夹替换 node_modules
文件夹.因此,有效地,来自Dockerfile的命令无效.
Later, in the docker-compose file, you are replacing the node_modules
folder with a folder from the host machine. So, effectively, the commands from the Dockerfile have no effect.
我不确定您的目标是什么,但是我可以看到几种选择:
I'm not sure what your goal is, but I can see several options:
- 如果您希望docker容器将依赖项安装到主机上的文件夹(?)中,则需要在容器启动时执行此操作,而不是在构建映像时执行
- 如果您只想使用主机文件夹中的依赖项,请确保存在
typescript
- 如果您的目标是在docker上运行该应用程序,但仍然能够编辑和热重载该应用程序,请尝试单独安装
src
文件夹(但是您将无法添加新的依赖项)
- if you want the docker container to install dependencies into the folder on the host machine (?), you need to do it when the container is being started, not when the image is being build
- if you just want to use dependencies from the host folder, make sure that the
typescript
is there - if your goal is to run the app on docker but still be able to edit and hot-reload the app, try mounting the
src
folder alone (but then you won't b able to add new dependencies)
更新:
实际上,您的解决方案应该可以工作.Docker-compose应该将文件从容器内的 node_modules
复制到已安装的卷中.不过有一个陷阱:只有在新创建卷时才执行(请参见使用容器填充卷).因此,要解决该问题,请尝试删除该卷并重新运行docker compose:
Actually your solution should work. Docker-compose should copy files from the node_modules
inside the container into the mounted volume. There is one gotcha though: it does it only when the volume is newly created (see populate a volume using a container). So, to solve the problem, try removing the volume and rerun docker compose:
docker volume rm frontend_node_modules
不幸的是,每次依赖关系发生任何变化时,您都需要这样做.或者,您可以使用:
Unfortunately you need to do it every time there are any changes to the dependiences. Alternatively you can use:
docker-compose down -v
也将删除卷(默认情况下, docker-compose down
不会删除卷,因此 -v
开关)
which will remove volumes as well (by default docker-compose down
does not remove volumes, thus the -v
switch)
这篇关于无法在Docker容器中使用TypeScript启动React的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!