无法在 Docker 容器中使用 TypeScript 启动 React

IT技术 reactjs typescript docker
2022-07-26 23:31:30

我正在尝试npm run start使用--template typescript. 因此安装了 Typescript(作为 React 依赖项),但我的 Docker 容器抱怨说不会安装 TypeScript 的一般错误消息。因此,我无法在 Docker 容器中启动应用程序。

package.json当我在容器外启动应用程序(使用相同的 )时,一切正常。

错误

> 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

我通过添加 TypeScriptnpm install typescript并重建了 Docker 容器。但它仍然显示错误消息。

即使在typescript手动添加作为依赖项之后(甚至在直接调用npm install typescript那里的容器内!),容器仍然抱怨无法找到 TypeScript(这似乎不是真的,因为我可以验证 TypeScript 安装在容器tsc -version向我展示了正确的输出)。

代码

我的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 的热重载功能工作。

1个回答

在 Docker 镜像构建期间(即在 Dockerfile 中),您将依赖项安装到容器内node_modules的文件夹( ) 中。类型 script ( ) 在安装时工作。RUN npm install --silenttsc --version

稍后,在 docker-compose 文件中,您将node_modules使用主机中的文件夹替换该文件夹。因此,有效地,来自 Dockerfile 的命令无效。

我不确定您的目标是什么,但我可以看到几个选项:

  • 如果您希望 docker 容器将依赖项安装到主机上的文件夹中(?),您需要在容器启动时执行此操作,而不是在构建映像时执行
  • 如果您只想使用主机文件夹中的依赖项,请确保typescript存在
  • 如果您的目标是在 docker 上运行应用程序但仍然能够编辑和热重新加载应用程序,请尝试src单独安装文件夹(但您将无法添加新的依赖项)

更新:

实际上,您的解决方案应该有效。Docker-compose 应该将文件从node_modules容器内部复制到挂载的卷中。但是有一个问题:只有在新创建卷时才会这样做(请参阅使用容器填充卷)。因此,要解决此问题,请尝试删除卷并重新运行 docker compose:

docker volume rm frontend_node_modules

不幸的是,每次依赖项发生任何更改时,您都需要这样做。或者,您可以使用:

docker-compose down -v

这也将删除卷(默认情况下docker-compose down不删除卷,因此-v切换)