vscodeの拡張機能を作ってみた

6 min read読了の目安(約5700字

経緯

vscodeの拡張機能を作成したので、基本的な使い方をまとめようと思います。

vscodeはElectronを使っているのでjavaScriptで拡張機能も作ることができます。

https://www.electronjs.org/

今から紹介する方法は2021/3月時点での方法です。

調査

まずどのように、作成するのか調査を行いました。調査なんて言い方をすると大ごとのように感じますが、単純にググっただけです。

以下の記事を参考にしました。

https://www.atmarkit.co.jp/ait/articles/1511/30/news030.html

https://qiita.com/sfp_waterwalker/items/b2cbdbe1119ea46ab25e

https://qiita.com/rma/items/8c53077d1355ab8fa4c6

https://ao-system.net/note/65

ざっくりとした流れとしては、

  • npmのインストール
  • yo generator-codeのインストール
  • yo generator-codeを実行しプロジェクトの作成
  • 実装
  • vsceを使用してパッケージファイルの作成
  • パッケージファイルのインストール

となります。

開発

npmのインストール

OS等によりインストール方法が異なるのでここでは割愛します。ググればいくらでも出てきますのでネット上の記事を参考にしてください。

パッケージのインストール

  • yo generator-codeのインストール
  • vsceのインストール

を行います。といってもコマンドを叩くだけです。

npm install yo generator-code --save-dev

ドッカーの使用について

Dockerを使用する場合は、コンテナ上で上の手順を行ってもvsceの設定で上手く動きません。

なぜ上手く行かなかったのか調査を行っていないのでわかりませんが、githubのリポジトリが用意されているようなのでそちらを活用してください(私は試していないので詳しいことはわかりません)。

https://github.com/microsoft/vscode-vsce

プロジェクトの作成

npx yo code

でプロジェクトを作成します。以下のようにプロジェクト名などいくつか設定に関する質問があるので、質問に答えていってください。
全て答えると必要なファイルが生成されます。

% npx yo code

     _-----_     ╭──────────────────────────╮
    |       |    │   Welcome to the Visual  │
    |--(o)--|    │   Studio Code Extension  │
   `---------´   │        generator!        │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |     
   __'.___.'__   
 ´   `  |° ´ Y ` 

Unable to fetch latest vscode version: Error: [object Object]
? 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) 
? What's the name of your extension? hoge
? What's the identifier of your extension? hoge
? What's the description of your extension? fuga
? Initialize a git repository? No
? Bundle the source code with webpack? No
? Which package manager to use? npm

Writing in ...app/markdown_extension/hoge...
   create .vscode/extensions.json
   create .vscode/launch.json
   create .vscode/settings.json
   create .vscode/tasks.json
   create src/test/runTest.ts
   create src/test/suite/extension.test.ts
   create src/test/suite/index.ts
   create .vscodeignore
   create README.md
   create CHANGELOG.md
   create vsc-extension-quickstart.md
   create tsconfig.json
   create src/extension.ts
   create package.json
   create .eslintrc.json

実装

主に編集していくのはextension.tspackage.jsonです。必要に応じてテストなどを追加してください。

extension.ts

このファイルに機能を記述していきます。言語はjavaScriptかtypeScriptです。今回は、プロジェクト作成の際にtypeScriptを選んだのでそちらでの記述になります。

以下は、プロジェクト生成時に自動で作成されるものです(コメントアウトの英文は日本語に適当訳しています)。
コメントを見れば大体どのようなことをしているかわかると思います。

これを参考に、VS Code API | Visual Studio Code Extension API等を活用しながら作成していきます。

extension.ts
// vscodeのモジュールを読み込みます。
import * as vscode from 'vscode';

// 拡張機能が有効になった時、以下が実行されます。
export function activate(context: vscode.ExtensionContext) {

	// コンソールを使用してエラーなどを出力します。
	console.log('Congratulations, your extension "hoge" is now active!');

	// 以下のメソッドがvscodeからコマンド等で実行されます。
	let disposable = vscode.commands.registerCommand('hoge.helloWorld', () => {
		// 右下にインフォメーションボックスを使用してメッセージを表示
		vscode.window.showInformationMessage('Hello World from hoge!');
	});
  // 拡張機能が使用されなくなったときに、リソース開放を行うための、設定。
	context.subscriptions.push(disposable);
}

// 拡張機能が無効になった時呼び出されます。
export function deactivate() {}

package.json

package.jsonを設定してあげる必要があります。
activationEventsにextension.tsで作成した機能を追加し、contributesでコマンドやショートカットキーを割り振ることで実行できるようになります。

package.json
{
	"name": "hoge",
	"displayName": "hoge",
	"description": "fuga",
	"version": "0.0.1",
	"engines": {
		"vscode": "^1.46.0"
	},
	"categories": [
		"Other"
	],
	"activationEvents": [
		"onCommand:hoge.helloWorld"
	],
	"main": "./out/extension.js",
	"contributes": {
		"commands": [
			{
				"command": "hoge.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"
	},
  // (略)
}

実行

パッケージを作成する前にvscodeのデバッグモードで実行してみることができます。
その前にtypeScriptファイルなので、JavaScriptにコンパイルする必要があります。

hoge % npm run compile
> hoge@0.0.1 compile /hoge
> tsc -p ./

これで./out/にファイルが出力されるのでF5で実行してあげると別ウィンドウが開き、実行結果を確認することができます。
デバッグ実行

MacだとCmd + Shift + Pでコマンドパレットを開き、Hello Worldコマンドを実行します。
コマンド実行

プロジェクト作成時はインフォメーションウィンドウを表示するように実装されているので、右下にメッセージが表示されます。
実行結果

パッケージ化

パッケージの出力

hoge % npx vsce package
npx: 64個のパッケージを3.416秒でインストールしました。
Executing prepublish script 'npm run vscode:prepublish'...

> hoge@0.0.1 vscode:prepublish /hoge
> npm run compile


> hoge@0.0.1 compile /hoge
> tsc -p ./

 WARNING  A 'repository' field is missing from the 'package.json' manifest file.
Do you want to continue? [y/N] y
 DONE  Packaged: /hoge/hoge-0.0.1.vsix (6 files, 2.74KB)

パッケージのインストール

code --install-extension hoge-0.0.1.vsix

これで通常でも拡張機能が使えます。

自作した拡張機能

最後に私が今回作ったマークダウン内で選択(ドラッグ)したURLのタイトルを取得し、マークダウンのリンク表示に変換する拡張機能のリポジトリを紹介しておきます。
ここでは

  • エディタの操作
  • 選択(ドラッグ)情報の取得
  • ショートカットコマンドの登録
  • 実行条件の追加(実行できるファイルや選択時のみの指定)
  • JavaScriptでsnippetを動的に生成
  • サーバサイドでのDOM操作

を行っているので参考になれば見てみてください。

https://github.com/bkc-tomi/markdown-linker