VS Code插件项目剖析

210 阅读2分钟

项目目录

使用命令`tree -I "node_modules|test|.git" -a`打印文件夹目录
.
├── .eslintrc.json
├── .gitignore
├── .vscode
│   ├── extensions.json
│   ├── launch.json // 用于启动和调试插件的配置
│   ├── settings.json
│   └── tasks.json // 用于编译TypeScript的构建任务的配置
├── .vscodeignore
├── CHANGELOG.md
├── README.md // 插件文档描述
├── package-lock.json
├── package.json // 插件清单
├── src
│   └── extension.ts // 插件源代码
├── tsconfig.json // TypeScript配置
└── vsc-extension-quickstart.md

项目剖析

主要文件

extension.tspackage.json

Hello World插件做了什么事情

项目初始化的Hello World插件主要做了以下三件事:

  • 注册onCommand 激活事件Activation EventonCommand:helloworld.helloWorld,因此当用户运行Hello World命令时扩展程序被激活。
  • 使用contributes.commandsContribution Point使得命令Hello World在命令面板中可用,并将它绑定到命令IDhelloworld.helloWorld
  • 使用commands.registerCommandVS Code API将函数绑定到已注册的命令IDhelloworld.helloWorld

因此,理解这三个概念对于在VS Code中开发自己的插件至关重要:

插件入口文件extension.ts

插件入口文件extension.ts导出两个函数:activatedeactivateactivate在你注册的激活事件发生时执行,而deactivate让你可以在你的插件被停用或卸载之前进行一些清理操作。

// 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() {}

插件清单

每个VS Code插件必须有一个package.json文件作为其插件清单。package.json不仅包含了Node.js的一些字段,例如scriptdevDependencies等,还包括了VS Code特有的字段,例如publlisheractivationEventscontributes等。

下面是插件清单里较为重要的字段:

  • namepublisher,VS Code使用<publisher>.<name>作为插件的唯一ID。例如,Hello World项目的ID为vscode.helloworld
  • main 插件入口文件
  • activationEventscontributes:激活事件Activation Events 和 Contribution Points.
  • engins.vscode:指定插件所依赖的VS Code API的最低版本
{
  "name": "helloworld",
  "displayName": "helloworld",
  "description": "HelloWorld example for VS Code",
  "version": "0.0.1",
  "publisher": "vscode",
  "engines": {
    "vscode": "^1.71.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [
    "onCommand:helloworld.helloWorld"
  ],
  "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 ./",
    "pretest": "npm run compile && npm run lint",
    "lint": "eslint src --ext ts",
    "test": "node ./out/test/runTest.js"
  },
  "devDependencies": {
    "@types/vscode": "^1.71.0",
    "@types/glob": "^7.2.0",
    "@types/mocha": "^9.1.1",
    "@types/node": "16.x",
    "@typescript-eslint/eslint-plugin": "^5.31.0",
    "@typescript-eslint/parser": "^5.31.0",
    "eslint": "^8.20.0",
    "glob": "^8.0.3",
    "mocha": "^10.0.0",
    "typescript": "^4.7.4",
    "@vscode/test-electron": "^2.1.5"
  }
}