登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  软件教程

VS Code 用 Dev Container 固化扩展与开发依赖

来源:17golang原创

时间:2026-10-07 06:56:41 304浏览 收藏

最终结果:把 .devcontainer/devcontainer.json 提交到仓库后,团队成员可以让 VS Code 在同一类容器环境中打开项目。基础镜像负责 Node.js 运行时,Features 负责常用 CLI,customizations.vscode 负责容器内扩展和设置,postCreateCommand 负责安装项目依赖。以后换电脑或新成员加入,不再靠一份口头安装清单恢复环境。

VS Code 官方文档:https://code.visualstudio.com/docs/devcontainers/create-dev-container

Dev Container 规范:https://containers.dev/

开始前需要在本机安装 Docker、VS Code 和 Dev Containers 扩展。本文以带 package-lock.json 的 Node.js 项目为例,重点不是“容器能打开”,而是重建后如何证明运行时、工具、扩展、依赖和端口都符合预期。

最终结果:仓库里保存一份可重建环境

devcontainer配置把基础镜像Features扩展设置和项目依赖组合成一致开发环境的说明图
图1:把运行时、工具、扩展、设置和依赖安装写入仓库配置,团队成员通过 Reopen/Rebuild 获得同一套开发环境。

完成后,仓库至少包含以下结构:

project/
├── .devcontainer/
│   └── devcontainer.json   # 容器、扩展、设置和初始化命令
├── package.json            # 项目依赖声明
└── package-lock.json       # 锁定依赖解析结果

devcontainer.json 固化开发环境,lockfile 固化项目依赖解析。两者要一起进入版本控制,才能同时减少“机器差异”和“依赖漂移”。

创建 devcontainer.json

在项目根目录新建 .devcontainer/devcontainer.json。下面的 JSON 保持严格有效,因此没有插入注释;各字段随后逐项解释。

{
  "name": "team-node-workspace",
  "image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/github-cli:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode"
      ],
      "settings": {
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode",
        "eslint.validate": ["javascript", "typescript"]
      }
    }
  },
  "forwardPorts": [3000],
  "portsAttributes": {
    "3000": {
      "label": "Web App",
      "onAutoForward": "notify"
    }
  },
  "postCreateCommand": "npm ci",
  "remoteUser": "node"
}
字段固化内容结果核对
image操作系统和 Node.js 运行时基础node --version 与预期主版本一致
featuresGit、GitHub CLI 等开发工具对应命令在容器内可执行
customizations.vscode容器内扩展与编辑器设置扩展列表存在,保存格式化生效
forwardPorts需要从容器访问的服务端口应用启动后端口可访问
postCreateCommand容器首次创建后的项目初始化npm ci 成功,依赖目录可用
remoteUserVS Code Server 和子进程的容器用户新文件不会意外归 root 所有

为什么扩展要写在 customizations.vscode

本机安装的扩展和容器内扩展是两个环境。语言服务、格式化器、调试器往往需要在容器侧运行,所以不能只要求成员在本机扩展面板里手工安装。把扩展 ID 写进 customizations.vscode.extensions 后,VS Code 创建环境时会按配置安装。

扩展 ID 可以从扩展详情中确认。团队应只加入项目确实需要的扩展:语言服务、格式化、Lint、测试和调试工具适合固化;主题、图标、个人效率工具通常留在个人设置中,避免把偏好误写成项目约束。

开发工具放 Features,项目依赖交给 lockfile

Git、GitHub CLI、Java、Go、Python 等可复用工具适合使用 Dev Container Features。Feature 是可组合的安装与配置单元,能让 devcontainer.json 保持清晰。需要操作系统原生包或自定义构建步骤时,再切换到 Dockerfile。

postCreateCommand 更适合运行依赖仓库文件的初始化命令。示例使用 npm ci,它要求仓库中有 lockfile。若项目没有 package-lock.json,应先建立明确的依赖管理策略,而不是直接把命令换成每次都可能重新解析版本的安装流程。

重新打开与重建的操作流程

  1. 在 VS Code 中打开项目文件夹。
  2. 从命令面板运行 Dev Containers: Reopen in Container。
  3. 等待镜像准备、Feature 安装和 postCreateCommand 完成。
  4. 修改 .devcontainer 下的配置后,运行 Dev Containers: Rebuild Container。
  5. 重建完成后执行验收命令,不以“窗口重新打开”作为唯一成功标准。

第一次进入项目用 Reopen;已经在容器中、但基础镜像、Feature、扩展清单或初始化命令发生变化时用 Rebuild。只重载窗口通常不会重新执行完整容器构建。

中间状态:配置修改后哪些步骤会重新运行

变更建议动作重点观察
扩展或 settings重建并重新打开扩展安装与容器侧设置
image 或 Features重建容器镜像拉取、Feature 安装日志
package-lock.json重新执行 npm ci,必要时重建依赖安装是否与 lockfile 一致
forwardPorts重新打开或重建应用启动后端口转发状态
remoteUser重建容器文件所有者和写入权限

结果验收:五项检查不能只看容器能否打开

Dev Container容器身份Node版本CLI工具扩展清单依赖与端口验收说明图
图2:Dev Container 的验收不止是成功打开,还要核对版本、工具、扩展、依赖和服务端口。

在容器内执行下面的检查。Shell 支持注释,所以每组命令直接标明核对目标:

# 1. 核对容器操作系统和当前用户
cat /etc/os-release
id

# 2. 核对运行时与包管理器版本
node --version
npm --version

# 3. 核对由 Features 或基础镜像提供的 CLI
git --version
gh --version

# 4. 核对容器侧扩展,不要只看本机扩展
code --list-extensions --show-versions | sort

# 5. 核对项目依赖是否完成安装
test -d node_modules && echo "node_modules ready"
npm ls --depth=0

扩展清单中应至少出现 dbaeumer.vscode-eslint 和 esbenp.prettier-vscode。随后启动项目服务,再检查 3000 端口是否能从本机访问。若项目脚本是 npm run dev,可以这样运行:

# 启动项目定义的开发服务,确认端口转发可用
npm run dev

命令是否存在、具体监听地址和端口由项目脚本决定。若服务只监听 127.0.0.1 且框架要求显式开放容器访问,需要按该框架的配置改为合适的监听地址。

异常修正

扩展没有安装到容器

先确认扩展 ID 拼写正确,并位于 customizations.vscode.extensions。然后执行 Rebuild Container。还要区分“本机已安装”和“容器内已安装”,以 code --list-extensions 的容器侧结果为准。

npm ci 失败导致容器初始化中断

检查 package-lock.json 是否存在且与 package.json 匹配。若网络需要代理或私有 registry,不要把令牌明文写入仓库;应通过团队批准的凭据或环境注入方式提供。修正后重新运行初始化命令或重建容器。

新增文件归 root,宿主机无法修改

确认基础镜像存在配置的非 root 用户,并核对 remoteUser。Docker Compose 场景还需要检查服务的 user、挂载目录权限和 UID/GID 映射。权限修正通常需要重建才能完整生效。

修改配置后环境没有变化

仅关闭再打开窗口不一定重建镜像。对于 image、Features、Dockerfile 或用户设置变化,明确运行 Rebuild Container,并在重建日志后重新执行五项验收。

配置该如何归档

  • 提交 .devcontainer/devcontainer.json 和相关 Dockerfile、Compose 文件;
  • 提交 package-lock.json,让依赖安装结果可重复;
  • 在项目 README 记录 Reopen、Rebuild、启动和验收命令;
  • 不要提交访问令牌、私钥、个人代理密码或机器专属路径;
  • 升级镜像、Feature 或运行时后,记录变更原因和验收结果。

交付速查表

检查项通过标准失败后动作
容器身份操作系统、用户和工作目录符合预期检查 image、remoteUser 和挂载
Node 版本团队约定的主版本一致调整镜像标签并重建
CLI 工具Git、gh 等命令可执行修正 Features 或 Dockerfile
VS Code 扩展必需扩展出现在容器清单修正 customizations 并重建
项目依赖npm ci 成功,npm ls 无关键错误检查 lockfile、网络和权限
服务端口应用启动且转发端口可访问检查监听地址、端口和脚本

Dev Container 的价值不是把开发搬进 Docker 就结束,而是把“如何得到可工作的开发环境”变成仓库中可审查、可重建、可验收的配置。只要每次修改后都走一遍版本、扩展、依赖和端口检查,这套环境才能真正成为团队资产。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>