拡張機能の構造
前回のトピックでは、基本的な拡張機能を実行できるようになりました。その内部はどのように機能しているのでしょうか?
「Hello World」拡張機能は3つのことを行います。
onCommand
アクティベーションイベント:onCommand:helloworld.helloWorld
を登録することで、ユーザーがHello World
コマンドを実行したときに拡張機能がアクティベートされるようにします。注: VS Code 1.74.0 以降、
package.json
のcommands
セクションで宣言されたコマンドは、明示的なonCommand
エントリがactivationEvents
になくても、呼び出されると自動的に拡張機能をアクティベートします。contributes.commands
コントリビューションポイント を使用して、コマンドHello World
をコマンドパレットで利用できるようにし、コマンド IDhelloworld.helloWorld
にバインドします。commands.registerCommand
VS Code API を使用して、登録されたコマンド IDhelloworld.helloWorld
に関数をバインドします。
これら3つの概念を理解することは、VS Codeで拡張機能を作成する上で非常に重要です。
- アクティベーションイベント: 拡張機能がアクティブになるイベント。
- コントリビューションポイント: VS Codeを拡張するために、
package.json
の拡張機能マニフェストで行う静的な宣言。 - 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のハンドブックを参照してください。
ただし、「Hello World」拡張機能を理解するために不可欠なpackage.json
とextension.ts
に焦点を当てましょう。
拡張機能マニフェスト
すべてのVS Code拡張機能には、拡張機能マニフェストとしてpackage.json
が必要です。package.json
には、scripts
やdevDependencies
などのNode.jsフィールドと、publisher
、activationEvents
、contributes
などのVS Code固有のフィールドが混在しています。すべてのVS Code固有のフィールドの説明は、拡張機能マニフェストリファレンスに記載されています。以下にいくつかの最も重要なフィールドを示します。
name
とpublisher
: VS Codeは
を拡張機能の一意のIDとして使用します。たとえば、Hello WorldサンプルにはID. vscode-samples.helloworld-sample
があります。VS CodeはこのIDを使用して拡張機能を一意に識別します。main
: 拡張機能のエントリポイント。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"
}
}
注: 拡張機能がVS Codeバージョン1.74より前を対象としている場合、
onCommand:helloworld.helloWorld
をactivationEvents
に明示的にリストする必要があります。
拡張機能のエントリファイル
拡張機能のエントリファイルは、activate
とdeactivate
の2つの関数をエクスポートします。登録されたアクティベーションイベントが発生すると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() {}