如何开发 VSCode 内置扩展:从零开始构建最简扩展

本文旨在为希望进行 VSCode 二次开发的开发者提供一个开发 VSCode 内置扩展的指南。内置扩展指的是那些在 VSCode 打包分发时默认启用的扩展。

文章目录

    • 前期准备
    • 前置知识
    • 最简扩展的快速搭建
      • [1. 扩展文件结构](#1. 扩展文件结构)
      • [2. 配置清单文件:`package.json`](#2. 配置清单文件:package.json)
      • [3. 编译配置:`tsconfig.json`](#3. 编译配置:tsconfig.json)
      • [4. 扩展入口源文件:`extension.ts`](#4. 扩展入口源文件:extension.ts)
      • [5. 编译构建配置(额外步骤)](#5. 编译构建配置(额外步骤))
    • 测试扩展加载与激活
      • [1. 启动开发构建](#1. 启动开发构建)
      • [2. 启动 VSCode 客户端](#2. 启动 VSCode 客户端)
      • [3. 实时热更新测试](#3. 实时热更新测试)
    • 总结

前期准备

  1. 克隆最新版本的 VSCode 源代码
  2. 执行 npm install 命令安装项目依赖
  3. 创建新分支,例如 ext/eva

前置知识

在开始内置扩展的搭建流程之前,对 VSCode 的扩展构建背景知识做个简单的介绍。

shell 复制代码
.
├── build # 构建脚本目录
│   ├── gulpfile.extensions.js # 扩展的构建任务
│   └── gulpfile.js # 真正的 Gulp 任务入口,加载其他的 `gulpfile.*.js`
├── extensions # 扩展根目录
│   ├── esbuild-webview-common.mjs # 扩展 WebView 通用 esbuild 配置
│   ├── shared.webpack.config.mjs # 扩展核心(Node)通用 Webpack 配置
│   └── tsconfig.base.json # 扩展通用 TypeScript 配置文件
└── gulpfile.js # Gulp 入口文件,直接加载 build/gulpfile.js

VSCode 使用 Gulp 管理构建流程,其中:

  • Webpack 负责打包扩展 Node.js 代码
  • ESBuild 负责打包扩展 WebView 代码

其中 build/gulpfile.extensions.js 文件主要定义了以下构建任务:

  • clean-extension-${name}:清除指定扩展的 out 目录
  • transpile-extension:${name}:将 TypeScript 代码转译为 JavaScript
  • compile-extension:${name}:执行完整编译(包含类型检查)
  • watch-extension:${name}:监听文件变更自动触发构建(错误不会中断进程)

这些任务基于 compilations 数组中声明的扩展 tsconfig.json 配置文件,为每个扩展单独生成。同时提供以下全局任务来并行处理所有扩展:

  • transpile-extensions
  • compile-extensions
  • watch-extensions

:关于 VSCode Web 扩展的构建流程较为复杂,将另文详述,此处不再展开。

最简扩展的快速搭建

为了熟悉 VSCode 内置扩展的搭建流程,我们先实现一个最简单的内置扩展。

1. 扩展文件结构

在一个极简的扩展中,你只需要以下文件。在 VSCode 项目的根目录的 extensions 目录,并在其中创建你的扩展目录,例如 eva

bash 复制代码
.\extensions\eva
├── package.json
├── src
│   └── extension.ts
└── tsconfig.json

2. 配置清单文件:package.json

首先,在 extensions\eva 目录下创建一个 package.json 文件,作为 VSCode 扩展的清单文件:

json 复制代码
{
  "name": "eva",
  "publisher": "sysiya",
  "displayName": "Eva",
  "description": "AI Coder for your peer-program",
  "version": "0.0.1",
  "private": true,
  "license": "MIT",
  "engines": {
    "vscode": "1.106.x"
  },
  "activationEvents": [
    "*"
  ],
  "main": "./out/extension.js",
  "scripts": {
    "compile": "gulp compile-extension:eva",
    "watch": "gulp watch-extension:eva"
  }
}

配置说明:

  • publishername 共同定义了扩展的唯一 ID,格式为 {publiser}.{name},在本例中即 sysiya.eva
  • engines.vscode 声明了扩展所采用的 VSCode Extension API 版本。
  • activationEvents: ["*"] 声明了扩展会随着 VSCode 启动而默认激活。
  • main 声明了本地扩展的入口文件,它是经过 bundle 后的 JavaScript 文件。
  • scripts.compilescripts.watch 定义了编译和开发热更新命令,它们采用的是 VSCode 原生的 Gulp 扩展编译任务。

3. 编译配置:tsconfig.json

extensions/eva/tsconfig.json 文件扩展了 VSCode 的扩展基础 TypeScript 配置文件 extesions/tsconfig.base.json

json 复制代码
{
  "extends": "../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./out"
  },
  "include": [
    "src/**/*",
    "../../src/vscode-dts/vscode.d.ts"
  ]
}

该配置文件的作用包括:

  1. 声明 tsc 编译的输出目录为 ./out 目录,即 extensions/eva/out 目录。
  2. 声明需要编译的 TypeScript 源文件位于 extensions/eva/src/ 目录下。
  3. 包含 ../../src/vscode-dts/vscode.d.ts 文件,该文件是 VSCode Extension API 的 TS 类型定义文件,用于引入类型。

4. 扩展入口源文件:extension.ts

最后是扩展入口的源文件 extensions/eva/src/extension.ts

ts 复制代码
/*---------------------------------------------------------------------------------------------
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
  console.log(`${context.extension.id} activated`);
}

在这个文件中:

  • import * as vscode from 'vscode'; 导入了 VSCode Extension API,它是 VSCode 在 Extension Host 为每个扩展注入的 API。
  • activate 函数是扩展激活时执行的函数,这里它获取并输出了扩展的 ID。

5. 编译构建配置(额外步骤)

为了让 VSCode 在编译时将我们新建的扩展纳入其中,还需要编辑 build/gulp.extesions.js 文件,将扩展的 tsconfig.json 路径加入编译列表:

js 复制代码
const compilations = [
...
'extensions/eva/tsconfig.json',
...
]

测试扩展加载与激活

1. 启动开发构建

在 VSCode 项目根目录下运行 npm run watch 命令执行开发构建:

shell 复制代码
$ npm run watch
...
[watch-extensions] [23:15:59] Finished compilation extensions with 0 errors after 53057 ms
[watch-client    ] [23:17:12] Finished compilation with 0 errors after 123835 ms
[watch-client    ] [23:17:13] Starting compilation...
[watch-client    ] [23:17:13] Finished compilation with 0 errors after 16 ms

看到类似输出,说明 VSCode 内置扩展与客户端已成功编译。

2. 启动 VSCode 客户端

根据你的操作系统执行相应的命令启动 VSCode 客户端:

shell 复制代码
# Windows
.\scripts\code.bat

# macOS/Linux
./scripts/code.sh

在启动命令的输出中,你可以看到 Extension Host 的输出 sysiya.eva activated,表明扩展已激活:

shell 复制代码
[25704:1017/233429.934:INFO:CONSOLE:100] "%c[Extension Host] %csysiya.eva activated %c(at console.<anonymous> (file:///d:/Code/open-source/vscode/out/vs/workbench/api/common/extHostConsoleForwarder.js:45:22)) color: blue color:  color: grey", source: vscode-file://vscode-app/d:/Code/open-source/vscode/out/vs/base/common/console.js (100)

你也可以在启动的 VSCode 客户端中,使用 Ctrl + Shift + U 打开 Output 面板,选择 Extension Host 的日志并筛选 eva,来查看输出。

此外,使用 Ctrl + Shift + I 打开 Developer Tools 窗口也能看到日志输出。

3. 实时热更新测试

由于我们启动了 npm run watch,当修改文件后,watch-extension:eva 任务会自动检测文件变更并重新编译。

例如,更新 extensions/eva/src/extension.ts 代码:

ts 复制代码
// ...
export function activate(context: vscode.ExtensionContext) {
  console.log(`${context.extension.id} activated`);
  console.log(context.extension.packageJSON); // 额外添加的输出
}

等待扩展编译完成,一般 100ms 左右即可完成编译。

在 VSCode 客户端中使用 Ctrl + R 重新加载窗口,然后查看 Developer Tools,日志输出将随之更新。

总结

通过以上步骤,我们成功创建了一个最简单的 VSCode 内置扩展。关键要点总结:

步骤 关键文件 作用
1. 创建扩展结构 extensions/eva/ 扩展根目录
2. 配置清单 package.json 定义扩展元数据和配置
3. 配置编译 tsconfig.json TypeScript 编译配置
4. 编写逻辑 src/extension.ts 扩展核心逻辑
5. 集成构建 gulp.extensions.js 集成到 VSCode 构建系统

这种开发方式让你能够:

  • ✅ 与 VSCode 源码一起编译
  • ✅ 享受 TypeScript 类型检查
  • ✅ 使用 VSCode 内置的构建系统
  • ✅ 实现热重载开发体验

接下来你可以在此基础上添加更多功能,如命令、视图、语言支持等,打造功能丰富的 VSCode 扩展。


进一步学习资源:

希望这篇指南能帮助你顺利开始 VSCode 内置扩展的开发之旅!

相关推荐
CHH32135 小时前
在 Mac/linux 的 VSCode 中使用Remote-SSH远程连接 Windows
linux·windows·vscode·macos
楚韵天工6 小时前
宠物服务平台(程序+文档)
java·网络·数据库·spring cloud·编辑器·intellij-idea·宠物
呱呱巨基6 小时前
vim编辑器
linux·笔记·学习·编辑器·vim
Aevget9 小时前
「Java EE开发指南」用MyEclipse开发的EJB开发工具(二)
java·ide·java-ee·eclipse·myeclipse
AI视觉网奇11 小时前
pycharm 默认终端设置 cmd
ide·python·pycharm
ii_best11 小时前
IOS/ 安卓开发工具按键精灵Sys.GetAppList 函数使用指南:轻松获取设备已安装 APP 列表
android·开发语言·ios·编辑器
yudiandian201416 小时前
03 Eclipse 配置 JDK 环境
java·ide·eclipse
彦楠17 小时前
IDEA实用快捷键
java·ide·intellij-idea
热爱生活的五柒19 小时前
vscode左边打开文件后会覆盖上一个打开的文件,有什么不覆盖的方法
ide·vscode·编辑器