使用 Docker 简化前端开发
Docker 是一款出色的工具,它可以帮助开发人员以标准化的方式更高效地构建、部署和运行应用程序。对于前端应用程序,我们只需要 Docker 镜像进行本地开发,因为我们会将其部署到静态托管服务提供商。在这种情况下,我们可以不使用自定义 Docker 镜像吗?我们能获得与不使用 Docker 时相同的开发体验吗?是的,这比你想象的要容易。
要求
假设我们只需按下“启动”按钮,所有程序即可运行。此设置可以是任何由 React、Vue 或 Angular CLI 生成的应用程序。为了演示,我将使用我的Vue Todo 应用程序。
在开发过程中,我们将执行以下步骤:
- 安装依赖项
npm install
- 使用以下命令启动应用程序
npm start
- 修改文件并在浏览器中检查更改
- 在编辑器中使用模块的代码完成功能
- 添加新的依赖项
package.json
并安装它
自定义 Docker 文件
如果你在网上搜索“使用 Docker 进行前端开发”,你会发现很多文章都使用了自定义 Docker 镜像。让我们来看看它是如何工作的。
Docker 文件首先定义我们将基于其构建的基础镜像 (Node.js 12.x) ( FROM
),并将工作目录设置为/app
文件夹 ( WORKDIR
)。所有以RUN
或开头的命令CMD
都将以此文件夹作为默认工作目录。
下一步是复制源文件(COPY
)并安装依赖项。我们将package.json
与其他文件分开复制。为什么?因为 Docker 在多次构建镜像时会缓存 Dockerfile 的每个步骤。当我们不修改任何内容并再次构建镜像时,由于步骤已被缓存,因此它不会执行任何操作。如果我们更改 Javascript 文件,Docker 将运行 中的命令COPY . /app
。当我们修改package.json
文件时,Docker 将重新运行 中的命令COPY package.json /app
。
默认情况下,容器内特定端口上运行的应用程序在主机上不可用。我们必须使该端口可用(EXPOSE
)。只有这样,我们才能在浏览器中输入 URL(http://localhost:8900)并查看结果。
要运行此映像,我们必须构建它并运行创建的容器。
# Build the image: docker build -t <image-name> <relative-path-to-dockerfile>
docker build -t client .
# Run the image: docker container run -p <host port:container port> <image-name>
docker container run -p 8900:8900 client
缺点
上述 Docker 镜像可以工作,但是存在多个缺点:
-
容器内生成的文件在主机上不可见,只能在容器内部查看。这意味着我们无法
node_modules
在主机上看到该文件夹,因此编辑器中无法使用代码补全功能。我们无法将生成的文件提交package.lock.json
到源代码管理,因为它在主机上也不可用。 -
当依赖项和文件发生变化时,我们必须停止、构建并重新运行容器。我们失去了实时重载的能力。
了解 Docker Compose
Docker 可以构建单个镜像并运行构建的容器。Docker Compose 更进一步,可以同时构建和运行多个镜像。在本教程中,我们不会使用 Docker Compose 的众多构建功能;我们仅用它来克服上一个示例的缺点。
虽然我们可以使用前一种方法Dockerfile
来运行 Docker Compose,但我们将以一种跳过自定义镜像写入的方式使用它。
Docker Compose 不使用一系列命令来定义镜像,而是使用YAML 配置文件格式。在services
键下,Vue 应用程序的镜像名为client
。它相当于docker build -t <image-name>
命令中的命名。此处的描述以相同的方式开始:定义基础镜像 ( image
) 并设置工作目录 ( working_dir
)。
关键区别在于volumes
属性。通过使用它,本地文件夹将与容器同步。如果我们npm install
在容器中执行命令,该node_modules
文件夹也会出现在主机上:我们获得了代码补全和锁定文件。
应用程序也在容器中启动(command: sh -c "npm install && npm start"
),需要将端口暴露给主机才能通过浏览器访问(ports
)。
要运行此设置,我们必须构建它并运行构建的容器。
# Build the image and start the container
docker-compose up
Dockerfile
如果你仔细观察这两个解决方案,你会发现它们几乎完全相同。配置文件中的命令和配置字段之间有着很大的关联性docker-compose.yml
。唯一的区别在于它们处理挂载文件的方式,而这正是解决同步问题的关键所在。
概括
在进行本地开发时,快速的反馈循环和代码补全至关重要。如果我们采用纯 Docker 解决方案,则会失去这两者。我们不得不寻求 Docker 的“老大哥”Docker Compose 的帮助来同步文件夹。通过将我们的设置迁移到 Docker Compose,我们恢复了速度和代码补全。希望这个技巧能帮到您,并节省大量的开发时间。
特别感谢 iben帮助我进行设置。
文章来源:https://dev.to/emarsys/frontend-development-with-docker-simplified-254i