延伸模組解析
在上一個主題中,您已經成功執行了一個基本的擴充功能。那麼它在底層是如何運作的呢?
Hello World 擴充功能做了三件事:
- 註冊
onCommand啟用事件 (Activation Event):onCommand:helloworld.helloWorld,因此當使用者執行Hello World指令時,該擴充功能就會被啟用。注意:自 VS Code 1.74.0 起,宣告在
package.json之commands區段中的指令,在被呼叫時會自動啟用擴充功能,而不需要在activationEvents中顯式註冊onCommand。 - 使用
contributes.commands貢獻點 (Contribution Point),讓Hello World指令可以在命令選擇區(Command Palette)中使用,並將其綁定至指令 IDhelloworld.helloWorld。 - 使用
commands.registerCommandVS Code API,將一個函式綁定到已註冊的指令 IDhelloworld.helloWorld上。
理解這三個概念對於編寫 VS Code 擴充功能至關重要:
- 啟用事件:您的擴充功能啟用的觸發事件。
- 貢獻點:您在
package.json擴充功能清單 (Extension Manifest) 中所做的靜態宣告,用以擴充 VS Code 的功能。 - VS Code API:一組您可以在擴充功能程式碼中呼叫的 JavaScript API。
一般來說,您的擴充功能會結合使用貢獻點與 VS Code API 來擴充 VS Code 的功能。擴充功能能力概覽 (Extension Capabilities Overview) 主題可以幫助您找到適合您擴充功能的貢獻點與 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 偵錯 (Debugging)tasks.json用於定義 VS Code 任務 (Tasks)tsconfig.json請參考 TypeScript 手冊 (Handbook)
不過,我們現在將重點放在 package.json 與 extension.ts 上,這兩者對於理解 Hello World 擴充功能至關重要。
延伸模組資訊清單
每個 VS Code 擴充功能都必須具備一個 package.json 作為其 擴充功能清單。package.json 包含了 Node.js 欄位(如 scripts 與 devDependencies)以及 VS Code 特有的欄位(如 publisher、activationEvents 與 contributes)。您可以在 擴充功能清單參考 (Extension Manifest Reference) 中找到所有 VS Code 特有欄位的說明。以下是一些最重要的欄位:
name與publisher:VS Code 使用<publisher>.<name>作為擴充功能的唯一識別碼。例如,Hello World 範例的 ID 為vscode-samples.helloworld-sample。VS Code 使用該 ID 來唯一識別您的擴充功能。main:擴充功能的進入點 (Entry point)。activationEvents與contributes:啟用事件與貢獻點。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。
擴充功能進入點檔案
擴充功能進入點檔案匯出了兩個函式:activate 與 deactivate。當您註冊的啟用事件發生時,activate 就會被執行。deactivate 讓您有機會在擴充功能被停用前進行清理工作。對於許多擴充功能而言,可能不需要顯式的清理工作,因此可以移除 deactivate 方法。然而,如果擴充功能需要在 VS Code 關閉、或擴充功能被停用或解除安裝時執行某些操作,這就是適合使用該方法的地方。
VS Code 擴充功能 API 宣告於 @types/vscode 型別定義中。vscode 型別定義的版本由 package.json 中 engines.vscode 欄位的值所控制。vscode 型別為您的程式碼提供了 IntelliSense、跳至定義 (Go to Definition) 以及其他 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() {}