现已推出!阅读有关 11 月份新功能和修复的资讯。

扩展解剖

在上一个主题中,您能够让一个基本扩展运行起来。它是如何工作的呢?

Hello World 扩展做了 3 件事

  • 注册 onCommand 激活事件onCommand:helloworld.helloWorld,因此当用户运行 Hello World 命令时,扩展会被激活。

    注意:VS Code 1.74.0 开始,在 package.jsoncommands 部分声明的命令在调用时会自动激活扩展,而无需在 activationEvents 中显式添加 onCommand 条目。

  • 使用 contributes.commands 贡献点 使命令 Hello World 在命令面板中可用,并将其绑定到命令 ID helloworld.helloWorld
  • 使用 commands.registerCommand VS Code API 将函数绑定到注册的命令 ID helloworld.helloWorld

理解这三个概念对于在 VS Code 中编写扩展至关重要

  • 激活事件:您的扩展变得活跃的事件。
  • 贡献点:您在 package.json 扩展清单中进行的静态声明,用于扩展 VS Code。
  • VS Code API:一组您可以在扩展代码中调用的 JavaScript API。

通常,您的扩展会使用贡献点和 VS Code API 的组合来扩展 VS Code 的功能。 扩展功能概述主题可帮助您为扩展找到正确的贡献点和 VS Code API。

让我们仔细看看 Hello World 示例的源代码,看看这些概念是如何应用于它的。

扩展文件结构

.
├── .vscode
│   ├── launch.json     // Config for launching and debugging the extension
│   └── tasks.json      // Config for build task that compiles TypeScript
├── .gitignore          // Ignore build output and node_modules
├── README.md           // Readable description of your extension's functionality
├── src
│   └── extension.ts    // Extension source code
├── package.json        // Extension manifest
├── tsconfig.json       // TypeScript configuration

您可以阅读有关配置文件的更多信息

  • launch.json 用于配置 VS Code 调试
  • tasks.json 用于定义 VS Code 任务
  • tsconfig.json 请参阅 TypeScript 手册

但是,让我们关注 package.jsonextension.ts,这对于理解 Hello World 扩展至关重要。

扩展清单

每个 VS Code 扩展都必须有一个 package.json 作为其 扩展清单package.json 包含 Node.js 字段(例如 scriptsdevDependencies)和 VS Code 特定字段(例如 publisheractivationEventscontributes)的组合。您可以在 扩展清单参考中找到所有 VS Code 特定字段的描述。以下是一些最重要的字段

  • namepublisher:VS Code 使用 <publisher>.<name> 作为扩展的唯一 ID。例如,Hello World 示例的 ID 为 vscode-samples.helloworld-sample。VS Code 使用 ID 来唯一标识您的扩展。
  • main:扩展入口点。
  • activationEventscontributes激活事件贡献点
  • engines.vscode:这指定了扩展依赖的 VS Code API 的最低版本。
{
  "name": "helloworld-sample",
  "displayName": "helloworld-sample",
  "description": "HelloWorld example for VS Code",
  "version": "0.0.1",
  "publisher": "vscode-samples",
  "repository": "https://github.com/microsoft/vscode-extension-samples/helloworld-sample",
  "engines": {
    "vscode": "^1.51.0"
  },
  "categories": ["Other"],
  "activationEvents": [],
  "main": "./out/extension.js",
  "contributes": {
    "commands": [
      {
        "command": "helloworld.helloWorld",
        "title": "Hello World"
      }
    ]
  },
  "scripts": {
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./"
  },
  "devDependencies": {
    "@types/node": "^8.10.25",
    "@types/vscode": "^1.51.0",
    "tslint": "^5.16.0",
    "typescript": "^3.4.5"
  }
}

注意:如果您的扩展的目标是 1.74 之前的 VS Code 版本,则必须在 activationEvents 中显式列出 onCommand:helloworld.helloWorld

扩展入口文件

扩展入口文件导出两个函数:activatedeactivate。当您注册的激活事件发生时,将执行 activatedeactivate 使您有机会在扩展被停用之前进行清理。对于许多扩展,可能不需要显式清理,并且可以删除 deactivate 方法。但是,如果扩展需要在 VS Code 关闭或禁用或卸载扩展时执行操作,则这是执行此操作的方法。

VS Code 扩展 API 在 @types/vscode 类型定义中声明。 vscode 类型定义的版本由 package.jsonengines.vscode 字段的值控制。 vscode 类型为您在代码中提供 IntelliSense、转到定义和其他 TypeScript 语言功能。

// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
  // Use the console to output diagnostic information (console.log) and errors (console.error)
  // This line of code will only be executed once when your extension is activated
  console.log('Congratulations, your extension "helloworld-sample" is now active!');

  // The command has been defined in the package.json file
  // Now provide the implementation of the command with registerCommand
  // The commandId parameter must match the command field in package.json
  let disposable = vscode.commands.registerCommand('helloworld.helloWorld', () => {
    // The code you place here will be executed every time your command is executed

    // Display a message box to the user
    vscode.window.showInformationMessage('Hello World!');
  });

  context.subscriptions.push(disposable);
}

// this method is called when your extension is deactivated
export function deactivate() {}