扩展剖析(Extension Anatomy)

在上一个主题中,你已经可以让一个基本的扩展运行。它是如何在引擎下工作的呢?

Hello World扩展有做了3 件事:

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

一般来说,您的扩展将使用Contribution Points和 vscode API 的组合来扩展 vscode的功能。扩展功能概述主题可帮助你找到正确的Contribution Point和 vscode API 。

让我们仔细查看 Hello World 样例的源代码,从中理解上述概念。

扩展文件结构

  1. .
  2. ├── .vscode
  3. ├── launch.json // Config for launching and debugging the extension
  4. └── tasks.json // Config for build task that compiles TypeScript
  5. ├── .gitignore // Ignore build output and node_modules
  6. ├── README.md // Readable description of your extension's functionality
  7. ├── src
  8. └── extension.ts // Extension source code
  9. ├── package.json // Extension manifest
  10. ├── tsconfig.json // TypeScript configuration

你可以阅读更多有关配置文件的资料:

  • launch.json用于配置 vscode调试
  • tasks.json用于定义 vscode任务
  • tsconfig.json 这是Typescript的配置文件,详情请参阅TypeScript手册

然而,让我们专注于package.jsonextension.ts这两个文件,这是理解 Hello World扩展的关键!

(扩展清单)Extension Manifest

每个 vscode扩展都必须有一个 package.json文件作为 扩展清单package.json文件中包含了一系列Node.js 中的字段,比如 scriptsdevDependencies,也包含了vscode特有的字段,比如publisheractivationEventscontributes。您可以在扩展清单参考中找到所有有关vscode特定字段的描述。以下是一些最重要的字段:

  • namepublisher : vscode使用 <publisher>.<name> 作为每个扩展的独一无二的ID。举个例子:Hello World扩展有ID vscode-samples.helloworld-sample 。vscode使用ID来唯一识别你的插件。
  • main: 扩展的入口文件。
  • activationEventscontributes激活事件贡献点
  • engines.vscode: 这指定了扩展所依赖的 vscode API 的最低版本。
  1. {
  2. "name": "helloworld-sample",
  3. "displayName": "helloworld-sample",
  4. "description": "HelloWorld example for VS Code",
  5. "version": "0.0.1",
  6. "publisher": "vscode-samples",
  7. "repository": "https://github.com/microsoft/vscode-extension-samples/helloworld-sample",
  8. "engines": {
  9. "vscode": "^1.51.0"
  10. },
  11. "categories": ["Other"],
  12. "activationEvents": ["onCommand:helloworld.helloWorld"],
  13. "main": "./out/extension.js",
  14. "contributes": {
  15. "commands": [
  16. {
  17. "command": "helloworld.helloWorld",
  18. "title": "Hello World"
  19. }
  20. ]
  21. },
  22. "scripts": {
  23. "vscode:prepublish": "npm run compile",
  24. "compile": "tsc -p ./",
  25. "watch": "tsc -watch -p ./"
  26. },
  27. "devDependencies": {
  28. "@types/node": "^8.10.25",
  29. "@types/vscode": "^1.51.0",
  30. "tslint": "^5.16.0",
  31. "typescript": "^3.4.5"
  32. }
  33. }

扩展入口文件(Extension Entry File)

扩展入口文件会导出两个函数,activatedeactivate 。 当你注册的Activation Event发生时会执行activatedeactivate则让你在扩展停用之前,有机会进行一些清理工作。对于许多扩展,显式的清理工作不是必要的,因此,可以移除deactivate这个函数。但是,如果扩展需要在vscode关闭,扩展被禁用或卸载执行操作,则这个方法会助你一臂之力。

vscode扩展 API 在@types/vscode类型定义中声明。vscode类型定义的版本由package.json中的字段exgines.vscode的值来控制。vscode类型为您提供了自动补全、查看定义以及其他TypeScript特色功能。

  1. // The module 'vscode' contains the VS Code extensibility API
  2. // Import the module and reference it with the alias vscode in your code below
  3. import * as vscode from 'vscode';
  4. // this method is called when your extension is activated
  5. // your extension is activated the very first time the command is executed
  6. export function activate(context: vscode.ExtensionContext) {
  7. // Use the console to output diagnostic information (console.log) and errors (console.error)
  8. // This line of code will only be executed once when your extension is activated
  9. console.log('Congratulations, your extension "helloworld-sample" is now active!');
  10. // The command has been defined in the package.json file
  11. // Now provide the implementation of the command with registerCommand
  12. // The commandId parameter must match the command field in package.json
  13. let disposable = vscode.commands.registerCommand('helloworld.helloWorld', () => {
  14. // The code you place here will be executed every time your command is executed
  15. // Display a message box to the user
  16. vscode.window.showInformationMessage('Hello World!');
  17. });
  18. context.subscriptions.push(disposable);
  19. }
  20. // this method is called when your extension is deactivated
  21. export function deactivate() {}