vsce 打包工具
插件开发完成后,需要把源码、资源与清单文件打包成 .vsix 安装包,才能分发给用户或上传到 Marketplace。vsce(VS Code Extension 工具)正是完成这件事的官方命令行工具。
安装 vsce
vsce 是官方发布的 Node.js 包,全局安装即可:
npm install -g @vscode/vsce验证安装:
vsce --version如果不想全局安装,也可以用 npx 直接调用:
npx @vscode/vsce package登录配置
vsce login 用于保存发布者凭据,之后发布时不再重复输入:
vsce login mypublisher执行后会要求粘贴 Personal Access Token(PAT),令牌保存在本机配置文件中,后续 vsce package 与 vsce publish 都会读取。
| 命令 | 作用 |
|---|---|
vsce login | 保存发布者与令牌 |
vsce logout | 清除已保存的发布者 |
vsce ls | 列出将被打包的文件 |
vsce package | 打包为 .vsix |
vsce publish | 打包并上传到 Marketplace |
打包 vsix 文件
在插件项目根目录(含 package.json)执行:
vsce package输出示例:
DONE Packaged: my-extension-1.0.0.vsix (1.2 MB)输出产物
.vsix 本质是一个 ZIP 压缩包,内部结构如下:
my-extension-1.0.0.vsix
├── extension/
│ ├── package.json # 插件清单
│ ├── dist/ # 编译后的 JS
│ ├── README.md
│ └── CHANGELOG.md
├── [Content_Types].xml
└── extension.vsixmanifest用户可以通过 VS Code 扩展面板的「Install from VSIX...」直接安装,不需要经过 Marketplace。
指定输出路径
默认产物生成在当前目录,用 --out 指定路径:
vsce package --out dist/my-extension-1.0.0.vsix--out 的值可以是目录(自动命名为 名称-版本.vsix)或完整文件名。--out 目录不存在时会自动创建。
常用打包选项
| 选项 | 说明 |
|---|---|
--out <path> | 指定产物路径 |
--no-dependencies | 不打包 node_modules 中的依赖 |
--skip-license | 跳过许可证确认(打包前交互式询问) |
--allow-missing-repository | 允许缺少 repository 字段 |
--githubBranch <branch> | 指定 GitHub 分支,用于生成仓库链接 |
.vscodeignore 白名单规则
vsce package 默认把项目目录下几乎所有文件都打进包里。源码、测试、文档与开发依赖会让安装包臃肿,需要 .vscodeignore 排除。它的语法与 .gitignore 相同,放在项目根目录:
# 开发与构建产物
node_modules/**
dist/**
# 源码与测试
src/**
test/**
tests/**
**/*.ts
**/*.map
# 版本控制与 IDE 配置
.git/**
.github/**
.gitignore
.vscode/**
.idea/**
# 文档与杂项(可选保留 README)
*.md
!README.md
!CHANGELOG.md
docs/**
# 配置文件
*.config.js
tsconfig.json
yarn.lock
package-lock.json通配符语义
| 通配符 | 含义 | 示例 |
|---|---|---|
* | 匹配文件名,不跨目录 | *.map 匹配根目录所有 map 文件 |
** | 跨目录匹配任意层级 | src/** 匹配 src 下所有内容 |
? | 匹配单个字符 | file?.js 匹配 file1.js |
! | 排除后再重新包含 | !README.md 恢复 README |
目录结尾 / | 只匹配目录 | node_modules/ 排除整个目录 |
注意保留的文件
.vscodeignore 只影响打包内容,不影响发布。发布时 Marketplace 要求 README.md 与 LICENSE(若声明了许可证)必须存在,CHANGELOG.md 会展示在插件页。因此即使排除了 *.md,也要用 ! 规则把它们保留下来。
验证打包内容
打包前先检查会包含哪些文件:
vsce ls
vsce ls --treenode_modules/ (1 file, 0.1 MB)
dist/
dist/extension.js
dist/extension.js.map
package.json
README.md用 --tree 能看到目录层级,比逐个猜要直观得多。排除规则配置正确后,vsce ls 输出的应只有必需文件。
打包体积优化
一个干净插件的 .vsix 通常只有几十到几百 KB。体积暴增往往来自依赖被错误打包。
生产依赖 vs 开发依赖
package.json 中 dependencies 会随插件打包进 .vsix 并在运行时安装,devDependencies 不会:
{
"dependencies": {
"axios": "^1.6.0"
},
"devDependencies": {
"typescript": "^5.3.0",
"@types/vscode": "^1.85.0",
"esbuild": "^0.19.0"
}
}- 运行时需要
require的库放dependencies - 编译、类型、打包工具放
devDependencies
许多插件其实没有运行时依赖(编译后是纯 JS),dependencies 保持空即可。
排除开发依赖的硬性手段
如果团队习惯把所有依赖装进 dependencies,可在 .vscodeignore 里强制排除:
node_modules/**
# 仅保留运行时依赖
!node_modules/axios/**更稳妥的做法是把 node_modules 全部排除,再用 --no-dependencies 打包确认体积:
vsce package --no-dependencies检查打包后体积
打包完成后立即检查产物大小,异常增长要追查原因:
ls -lh *.vsix也可以解压查看占用空间最大的文件:
unzip -l my-extension-1.0.0.vsix | sort -k1 -rn | head -20常见的体积杀手:
| 原因 | 处理 |
|---|---|
把 typescript 装进 dependencies | 移到 devDependencies |
打包了 src/** 源码 | 在 .vscodeignore 排除 |
| 打包了全部 node_modules | 按需保留生产依赖 |
残留 .map 源码映射 | 排除 **/*.map |
| 图片资源过大 | 压缩图片或按需引入 |
体积目标参考
| 插件类型 | 合理体积 |
|---|---|
| 纯 JS 功能型插件 | 10 - 200 KB |
| 带图标的主题插件 | 100 - 500 KB |
| 带原生二进制依赖 | 几 MB 以上,需评估 |
体积不是越小越好,但每个多余的 KB 都会拖慢下载与安装。发布前把体积控制在合理区间,是插件专业度的体现。
依赖处理细节
嵌套依赖与锁定版本
打包时 vsce 会把 dependencies 及其传递依赖一起纳入。生产环境建议锁定版本:
npm install --save-exact axios锁定的版本能保证用户拿到的运行行为与测试时一致。
可选依赖与平台差异
含原生模块(如 fsevents、sharp)的依赖会产生平台差异。若插件只面向 Node 运行时,尽量用纯 JS 实现;确需原生模块时,.vscodeignore 按平台排除非目标产物:
# 仅保留 Windows 与 Linux 的二进制
!node_modules/sharp/lib/win32/**打包前自动编译
发布前必须先编译 TypeScript。vsce 支持 vscode:prepublish 脚本,在 package 与 publish 之前自动执行:
{
"scripts": {
"vscode:prepublish": "npm run compile"
}
}打包失败排查
| 错误 | 原因 | 处理 |
|---|---|---|
publisher 缺失 | package.json 缺少发布者 | 补上 publisher 字段 |
| 图标不是 PNG | icon 字段指向非 PNG | 使用 PNG 且小于 256KB |
| LICENSE 缺失 | 声明了 license 但无许可证文件 | 添加 LICENSE 文件或移除字段 |
| README 渲染错误 | README 内嵌 HTML 不合法 | 检查尖括号等特殊字符 |
| 版本已存在 | 尝试重复发布同一版本 | 递增版本号 |
打包是发布链路的第一步,产物质量直接决定用户安装体验。.vscodeignore 与依赖配置到位,插件就能以最精简的体积交付。