乐于分享
好东西不私藏

写完 VSCode 插件不会调试?搞懂 .vscode 下这两个文件就够了

写完 VSCode 插件不会调试?搞懂 .vscode 下这两个文件就够了

本文由AI创作

AI 哐哐一顿输出,VSCode / Trae CN 插件的代码文件整整齐齐全在那。

插件写完后要在 .vscode 文件夹里, 添加两个文件:

  • launch.json
  • tasks.json

一个管"怎么跑",一个管"跑之前先干嘛"。搞懂它们,真的只要 1 分钟。

如果你不是程序员,直接复制粘贴这篇文章发给 AI 就行。它能看懂,会帮你把调试配置一键搞定。

我最近在用AI写Trae CN的插件, 记录一下怎样调试vscode插件我写的插件是下载github/gitee仓库, 今天又优化了一下插件.

github可以不登录就下载仓库, gitee不登录就不能下载, 我电脑配置了git, 也配置了gitee的密钥, 就能用git下载码云的仓库了.

优化后的插件github-clone-helperhttps://pan.quark.cn/s/5107aeef257f

开始讲解两个文件

`launch.json`:VSCode 怎么启动你的插件?

这个文件只回答一个问题:

按下 F5 后,VSCode 应该用啥姿势把你的插件跑起来?

来看一份最经典的配置:

json
{  "version": "0.2.0",  "configurations": [    {      "name": "Run Extension",      "type": "extensionHost",      "request": "launch",      "args": ["--extensionDevelopmentPath=${workspaceFolder}"],      "outFiles": ["${workspaceFolder}/out/**/*.js"],      "preLaunchTask": "${defaultBuildTask}"    }  ]}

别被这么多行吓到。真正关键的,就下面这几行。

═════════

`type: "extensionHost"` —— 这是核心

这行告诉 VSCode:

"我要启动的不是普通 Node 脚本,而是一个专门用来装插件的宿主进程。"

没有这个,VSCode 根本不知道你在调试插件。

═════════

`request: "launch"` —— 开新窗口,不影响主界面

每次调试,都会新开一个 VSCode 窗口跑你的插件。

你正在写代码的主窗口完全不受影响。 插件崩了?关掉那个窗口就行,主窗口稳得很。

═════════

`args` —— 去哪加载你的插件?

json
"--extensionDevelopmentPath=${workspaceFolder}"

意思是:去当前项目文件夹里加载插件代码。

${workspaceFolder} 是 VSCode 的自动变量,会替换成你的真实项目路径,不用手写。

═════════

`outFiles` —— 90% 的"断点变灰"问题出在这

你的 TypeScript 写完后,会被编译成 JavaScript 放到 out/ 目录。

这行就是告诉调试器:"去 out 文件夹找编译后的代码,才能跟你的源码断点对上号。"

如果你的编译输出目录不叫 out,比如是 dist/ 或者 build/,这里一定要同步改。改不对,断点就永远灰色,根本停不下来。

═════════

`preLaunchTask` —— 启动前先编译

json
"preLaunchTask": "${defaultBuildTask}"

按下 F5,不是直接跑插件,而是先执行一个任务

这个 ${defaultBuildTask} 变量,意思是"默认的构建任务"。

但问题来了——VSCode 怎么知道哪个任务是"默认构建任务"?

答案藏在另一个文件里:tasks.json

═════════

`${defaultBuildTask}` 到底是怎么被解析的?

在 tasks.json 里,每个任务有个 group 字段,用来给任务分类:

group.kind含义
"build"构建任务(编译代码)
"test"测试任务(跑测试用例)
不填普通任务,不属于任何分组

每个类型下,可以有一个默认任务,用 group.isDefault: true 标记。

现在拆开看 ${defaultBuildTask}

default + Build + Task = 默认的构建任务

VSCode 解析时做了三步:

  1. 在 tasks.json 里找出所有 group.kind 为 "build" 的任务
  2. 从中挑出 group.isDefault 为 true 的那个
  3. 取它的 label 值作为最终任务名

对应本文的例子:

text
tasks.json 里有一个任务:  ├── group.kind = "build"        ← 它是构建任务  ├── group.isDefault = true      ← 而且它是默认的  └── label = "compile"           ← 名字叫 compile所以 ${defaultBuildTask} → "compile"相当于 preLaunchTask 写成了 "compile"

VSCode 拿到 "compile",就去 tasks.json 按这个名字找任务,读取它的 command

按下 F5 后、启动插件窗口前,先把这条命令跑完。

编译成功?继续启动。编译失败?调试直接终止,报错给你看。

你也可以直接写 "preLaunchTask": "compile",效果一模一样。用 ${defaultBuildTask} 的好处是:以后改任务名字,只要 isDefault: true 还在,launch.json 根本不用动。

═════════

`tasks.json`:启动之前,要先准备什么?

这个文件回答另一个问题:

跑插件之前,需要先执行什么命令?

典型配置长这样:

json
{  "version": "2.0.0",  "tasks": [    {      "type": "shell",      "command": "npx esbuild src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node",      "options": {        "shell": {          "executable": "cmd.exe",          "args": ["/d", "/c"]        }      },      "group": {        "kind": "build",        "isDefault": true      },      "problemMatcher": [],      "label": "compile"    }  ]}

同样,逐行看重点。

═════════

`type: "shell"` —— 跟你在终端敲命令没区别

以命令行方式执行。就是把你平时在终端里敲的那串命令,交给 VSCode 自动跑。

═════════

`command` —— 整段配置的灵魂

这里用 esbuild 把 src/extension.ts 编译打包成 out/extension.js

几个参数特别值得注意:

  • --bundle:把所有依赖打包成一个文件,不用东找西找
  • --external:vscode这行超级重要。vscode 模块是运行时自带的,绝对不能打包进去,否则会直接报错
  • --format=cjs:VSCode 插件必须用 CommonJS 格式
  • --platform=node:目标是 Node.js 环境,不是浏览器
═════════

`group.isDefault: true` —— 为什么 launch.json 找得到它?

就是因为这行,launch.json 里的 ${defaultBuildTask} 才能精准定位到这个任务。

注意:同一类任务里,有且只能有一个设为默认。

═════════

`label: "compile"` —— 任务的名字

除了被 launch.json 自动调用,你也可以手动触发:

按 Ctrl + Shift + B,在弹出的列表里就能看见它,点一下直接跑。

═════════

一张图看懂它俩怎么配合

text
你按下 F5    │    ▼launch.json 被读取    │    ▼找到 preLaunchTask → 去 tasks.json 找默认构建任务    │    ▼执行 command:编译 TS → JS    │    ├── 编译失败 → 调试终止,看报错    │    └── 编译成功 → 启动新 VSCode 窗口(Extension Development Host)                      │                      ▼                 新窗口加载你的插件                      │                      ▼             原窗口的断点生效,开始调试 🎯

一句话记住:

tasks.json 负责编译,launch.json 负责启动,preLaunchTask 把两者串在一起。

═════════

F5 快捷键 vs 侧边栏按钮,到底有啥区别?

你可能发现了,启动调试有两种方式:

方式操作
按 F5键盘快捷键,一键启动
侧边栏点左侧"运行和调试"图标 → 顶部下拉选配置 → 点绿色播放按钮

本质上,它们做的是同一件事。

都是读取 launch.json,然后启动调试。区别只有一个:

  • F5:跳过选择界面,直接用上一次选中的配置启动(如果只有一个配置,自然就是它)
  • 侧边栏按钮:让你先看到有哪些可选配置,再挑一个启动

举个例子,假设你的 launch.json 里有两个配置:

json
{  "configurations": [    { "name": "Run Extension", ... },    { "name": "Run with Watch Mode", ... }  ]}
  • 按 F5:直接跑上一次用过的那个
  • 点侧边栏按钮:下拉列表里两个都能看到,可以切到 "Run with Watch Mode"

如果只有一个配置,两种方式完全等价。F5 更快。

═════════

按 F5 之前,需要做什么准备?

很多人以为按 F5 前,必须打开 launch.json,或者光标得停留在某个特定文件上。

其实完全不用。

F5 能工作的唯一条件:

当前 VSCode 窗口打开的文件夹(workspace)根目录下,有 .vscode/launch.json

跟你打开什么文件、停在哪个界面、有没有选中代码,统统无关。VSCode 会自动去根目录找这个文件。

按了 F5 没反应?按这个顺序检查:

  1. 当前是不是打开了一个文件夹(不是单个文件)
  2. 该文件夹根目录下有没有 .vscode/launch.json
  3. F5 快捷键有没有被别的插件覆盖(去 File → Preferences → Keyboard Shortcuts 搜 "Start Debugging")
═════════

五个坑,90% 的新手都会踩

坑 1:断点变灰,停不下来?

检查 outFiles 路径,是否跟你的编译输出目录一致。

比如你实际编译到 dist/,但 outFiles 写的是 out/,调试器根本找不到对应文件,断点自然灰色。

═════════

坑 2:改了代码,运行结果没变?

你改的是 .ts 源码,但跑的是编译后的 .js

每次改代码都要重新编译。 所以 preLaunchTask 才这么重要——让你每次按 F5 自动编译,不用手动敲命令。

═════════

坑 3:只想编译,不想调试?

按 Ctrl + Shift + B,直接跑默认构建任务,编译完就停,不启动调试窗口。

═════════

坑 4:`console.log` 打印的东西去哪了?

在 Extension Development Host 窗口(就是那个跑插件的新窗口)里,按 Ctrl + Shift + I 打开开发者工具,去 Console 面板里找。

═════════

坑 5:能不能像前端项目一样,改代码自动重启?

能。

在 launch.json 里加一行:

json
"restart": true

再配合 watch 模式的编译任务(esbuild 加 --watch),保存代码后插件就会自动重启,不用你手动按 F5。

═════════

总结

.vscode 下这两个文件,就是 VSCode 插件调试的全部秘密:

  • tasks.json:定义编译任务,把 TS 变成 JS
  • launch.json:定义调试方式,启动带插件的开发环境
  • preLaunchTask:把它们连起来,每次按 F5 先编译再启动

下次插件跑不起来的时候,别急着搜报错。

回到这两个文件,一行一行对一遍配置,问题大概率就在这里。

═════════

写完插件后,怎么打包给别人用?

调试通了,想发给朋友或者上架?需要打包成 .vsix 文件。

先在 package.json 加 scripts

json
{  "scripts": {    "vscode:prepublish": "npm run compile",    "compile": "esbuild src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node",    "watch": "esbuild src/extension.ts --bundle --outfile=out/extension.js --external:vscode --format=cjs --platform=node --watch"  }}

打包指令

bash
npm run compilevsce package --allow-missing-repository

跑完就会在当前目录生成一个 .vsix 文件,拖进 VSCode 就能安装。

扣子智能体教程

https://space.bilibili.com/26079586