无法在Docker容器中使用TypeScript启动React [英] Unable to start React with TypeScript in Docker container

查看:189
本文介绍了无法在Docker容器中使用TypeScript启动React的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆