Open15

VSCode エクステンション開発チュートリアルをやってみる

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Yeoman のインストール

Yeoman 懐かしい、こんなところで再会するとは。

コマンド
npm install --global yo generator-code

グローバルにインストールしたくない場合は下記でも良いようだ。

コマンド
npx --package yo --package generator-code -- yo code
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

プロジェクトの生成

コマンド
yo code
1 番目の質問
? What type of extension do you want to create? (Use arrow keys)
❯ New Extension (TypeScript) 
  New Extension (JavaScript) 
  New Color Theme 
  New Language Support 
  New Code Snippets 
  New Keymap 
  New Extension Pack 
  New Language Pack (Localization) 
  New Web Extension (TypeScript) 
  New Notebook Renderer (TypeScript) 
2 番目の質問
? What's the name of your extension? () HelloWorld
3 番目の質問
? What's the identifier of your extension? (helloworld)
4 番目の質問
? What's the description of your extension? ()
5 番目の質問
? Initialize a git repository? (Y/n)
6 番目の質問
? Which bundler to use? (Use arrow keys)
❯ none 
  webpack 
  esbuild 
7 番目の質問
? Which package manager to use? (Use arrow keys)
❯ npm 
  yarn 
  pnpm 
8 番目の質問
? Do you want to open the new folder with Visual Studio Code? (Use arrow keys)
❯ Open with `code` 
  Skip 
薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

実行

src/extension.ts で F5 キーを押すと VSCode が立ち上がる。

Ctrl + Shift + P で Hello World を実行すると通知が表示される。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

ソースコードの変更

通知メッセージを「Hello VS Code」に変更する。

src/extension.ts
import * as vscode from "vscode";

export function activate(context: vscode.ExtensionContext) {
  console.log('Congratulations, your extension "helloworld" is now active!');

  let disposable = vscode.commands.registerCommand(
    "helloworld.helloWorld",
    () => {
      vscode.window.showInformationMessage("Hello VS Code");
    }
  );

  context.subscriptions.push(disposable);
}

export function deactivate() {}

変更を反映するには Extension Development Host の方の VSCode で「Developer: Reload Window」を実行すれば良いようだ。

Command + R でも良い。

この状態で Hello World コマンドを実行するとメッセージが変更されたことを確認できる。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Extension Anatomy

Hello World エクステンションは次の 3 つのことをしている。

  • onCommand アクティベーションイベントの登録
  • contributes.commands コントリビューションポイントの使用
  • commands.registerCommand VS Code API の使用

アクティベーションイベント

エクステンションをアクティブにするイベント

コントリビューションポイント

package.json に記載される

VS Code API

エクステンションのコードで使用する VS Code の機能を呼び出すための API

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Extension File Structure

.
├── .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:デバッグ時の起動設定
  • tasks.json:ビルドタスク設定
  • tsconfig.json:TypeScript 設定

package.json と extension.ts については詳しく見ていく。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Extension Manifest

package.json には下記のような VS Code 固有のフィールドが含まれる。

  • publisher
  • activationEvents
  • contributes

VS Code では <publisher>.<name> がエクステンション固有の ID として使用される。

main フィールドはエクステンションのエントリーポイントを指定する。

contributes フィールドはエクステンションが寄与するポイントを指定する。

engines.vscode は VS Code の利用可能な最小バージョンを指定する。

VS Code のバージョンが 1.74以前の場合は onCommand のアクティベーションイベントを明示的に指定する必要がある。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

Extension Entry File

https://code.visualstudio.com/api/get-started/extension-anatomy#extension-entry-file

エクステンションのエントリーポイントのファイルでは activate と deactivate の 2 つの関数をエクスポートしている。

activate はエクステンションをインストール/有効化した時や VS Code の起動時などに呼び出されるようだ。

一方 deactivate はエクステンションをアンインストール/無効化した時や VS Code の終了時などに呼び出されるようだ、deactivate はエクステンションによっては何もしなかったり無かったりする。

薄田達哉 / tatsuyasusukida薄田達哉 / tatsuyasusukida

おわりに

Get Started のチャプチャーを読み切ることができた。

次に読むべきは Extension Capabilities のようだ。

https://code.visualstudio.com/api/extension-capabilities/overview

このチャプターではいくつかのカテゴリに分けて API やコントリビューションポイントを紹介してくれるようだ。

このチャプターくらいは一読してから何かを作ってみるのが良さそうだ。