【入門編】Visual Studio Code拡張機能の作り方
Visual Studio Codeを使っていて、こんな機能があったら便利だなと思うことが良くあります。Visual Studio Codeには拡張機能があり、追加で必要な機能を拡張できるため、たいていの機能は公開されている拡張機能を探せば見つかります。
ただ、とてもニッチ機能など見つからない場合があります。誰かが作ってくれるのを待つのもいいですが、あまりにニッチだと永遠に待つことになってしまいます。
実は、Visual Studio Codeの拡張機能は自分で作成することができます。作成した拡張機能はMarketplaceで公開することもできます。そう。なければ作ってしまえばいいんです。
ということで、ここでは、自分でVisual Studio Codeの拡張機能を作成する方法を記載しています。拡張機能を作るにあたって必要な開発環境のインストールから、簡単な拡張機能を作るまでを紹介します。
Marketplaceへの登録については、また別の機会に紹介したいと思います。
開発環境
まずは開発環境を準備していきます。
環境
- Windows 10
- Visual Studio Code
- Node.js
- Yeoman
- generator-code
インストール
-
Visual Studio Codeをインストールします。
ここからダウンロードし、インストーラーに従ってインストールします。開発するソフトウェアによっては、拡張機能を追加でインストールすることになると思いますが、ここでは省略します。 -
インストールを確認します。
コマンドプロンプトから以下を実行します。バージョンが表示されれば、インストールできています。> code -v 1.39.2 6ab598523be7a800d7f3eb4d92d7ab9a66069390 x64
-
Node.jsをインストールします。
ここからダウンロードしてインストールします。インストーラーに従ってインストールすればオッケーです。 -
インストールを確認する
コマンドプロンプトから以下を実行します。バージョンが表示されれば、インストールできています。> node -v v11.13.0
-
yoをインストールします。
コマンドプロンプトから以下を実行します。> npm install -g yo
-
generator-codeをインストールします。
コマンドプロンプトから以下を実行します。> npm install -g yo generator-code
-
node.jsのパスを確認します。
コマンドプロンプトから以下を実行します。するとパスが表示されるので、これをコピーしておきます。> npm bin -g C:\Users\kissy\AppData\Roaming\npm
-
環境変数NODE_PATHを設定します。
[システムのプロパティ]-[詳細設定]-[環境変数]を開き、[システム環境変数]に環境変数NODE_PATHを追加し、先ほどコピーしたパスを変数値として設定します。 -
これで開発環境の構築は完了です。
HelloWorldの作成と実行
まずは、簡単な拡張機能を作成して実行してみます。ここでは、generator-codeで生成できるひな型のHelloWorldのコード生成~実行までを行います。
ひな型コードを生成する
まずは、ひな型となるコードを生成します。
-
コマンドプロンプトを起動します。
-
ソースコードを保存するディレクトリまで移動します。
-
generator-codeでひな型コードを生成します。
まず、以下のコマンドを実行します。yo code
すると、ひな型コードを生成するために必要な情報を聞かれるので、入力していきます。
_-----_ ╭──────────────────────────╮ | | │ Welcome to the Visual │ |--(o)--| │ Studio Code Extension │ `---------´ │ generator! │ ( _´U`_ ) ╰──────────────────────────╯ /___A___\ / | ~ | __'.___.'__ ´ ` |° ´ Y ` ? What type of extension do you want to create? New Extension (TypeScript) ? What's the name of your extension? HelloWorld ? What's the identifier of your extension? helloworld ? What's the description of your extension? ? Initialize a git repository? No ? Which package manager to use? npm
-
これでひな型コードの生成は終わりです。
拡張機能をデバッグ実行する
以下の手順で拡張機能をデバッグ実行できます。あくまでデバッグ実行なので、通常のVSCにインストールはされません。
-
以下のコマンドを実行し、作成されたひな型コードをVisual Studio Codeで開きます。
cd helloworld code .
-
F5を押してビルド+実行をします。
ただし、この段階では拡張機能は実行されません。拡張機能を実行する新たなVisual Studio Codeのウィンドウが立ち上がるだけです。 -
Control+Shift+Pを押しコマンドパレットを開きます。
コマンドパレットとは、メニューバーの下に現れるコマンドを入力するための小さなウィンドウのことです。 -
コマンドパレットで
Hello World
と入力します。 -
拡張機能が起動され、右下に
Hello World!
のメッセージが表示されます。
サンプルソースの解説
ファイル構成
Yeomanが作成するひな型のソースコード構成は以下の通りです。Visual Studio Code拡張機能の開発で、主に修正するのは「package.json」と「extension.ts」のファイルになります。
ファイル | 内容 |
---|---|
CHANGELOG.md | サンプルの変更履歴 |
package-lock.json | 依存ライブラリのバージョンを固定する |
package.json | 拡張機能の名前/説明/バージョン/エントリーポイント、依存ライブラリを記載する |
README.md | サンプルのreadme |
tsconfig.json | TypeScriptのコンパイル対象やコンパイルオプションを記載する |
tslint.json | TSLint(TypeScriptの静的テストツール)のルールを記載する |
/src/extension.ts | 拡張機能のメインのソースコード |
/src/test/ | 拡張機能のテストコード |
package.json
「package.json」は拡張機能の名前/説明/バージョン/エントリーポイント、依存ライブラリを記載するJSONファイルです。拡張機能に機能追加する際、まず、この「package.json」に機能のイベントや定義を記載していきます。
各項目の概要は以下の通りです。
項目 | 必須 | タイプ | 概要 |
---|---|---|---|
name | ○ | string | 拡張機能の名称(すべて小文字。空白NG。) |
version | ○ | string | SemVer形式のバージョン |
publisher | ○ | string | 作成者名 |
engines | ○ | object | 拡張機能と互換性のあるVSCodeのバージョンを記載 |
categories | string | 拡張機能のカテゴリ(取りえる値:Programming Languages, Snippets, Linters, Themes, Debuggers, Formatters, Keymaps, SCM Providers, Other, Extension Packs, Language Packs, Data Science, Machine Learning, Visualization, Notebooks) | |
activationEvents | array | 拡張機能を有効にするイベント | |
main | string | 拡張機能のエントリーポイント | |
contributes | object | 拡張機能のコントリビュート(機能)の定義 |
例えば、HelloWorldではactivationEvents
とcontributes
は以下のように記載されていると思います。
- activationEvents
"activationEvents": ["onCommand:helloworld.helloWorld"]
- contributes
"contributes": { "commands": [ { "command": "helloworld.helloWorld", "title": "Hello World" } ] },
helloworld.helloWorld
コマンドで拡張機能が有効になるよ、helloworld.helloWorld
コマンドのタイトルはHello World
だよ、ということを定義しています。
helloworld.helloWorld
コマンドを実行したときの動作は、後述するextension.ts
で定義していきます。
その他の項目や詳細については下記のサイトを参照ください。
- Extension Manifest
- package.jsonの仕様が記載されている。
- Activation Events
- activationEventsの仕様が記載されている。
- Contribution Points
- contributesの仕様が記載されている。
extension.ts
extension.ts
は拡張機能の機能を実装していくファイルになります。拡張子がts
となっているように、TypeScriptで実装します。
以下は、HelloWorldのextension.ts
のコードです。拡張機能の実装としては、activate()
とdeactivate()
の2つの関数が実装されています。
activate()
はpackage.json
のactivationEvent
で定義したイベントが発生した際に呼ばれる関数です。deactivate()
は拡張機能が終了する際に呼ばれ、後処理をするタイミングとして使えます。
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "helloworld-sample" is now active!');
let disposable = vscode.commands.registerCommand('helloworld.helloWorld', () => {
vscode.window.showInformationMessage('Hello World!');
});
context.subscriptions.push(disposable);
}
export function deactivate() {}
HelloWorldでは、helloworld.helloWorld
コマンドを実行すると「Hello World!」というメッセージを表示します。メッセージを表示するためには、VSCode APIのshowInformationMessage()
を使います。また、コマンドとして使えるように(コマンドパレットに表示されるように)するために、VSCode APIのregisterCommand()
でコマンド登録しています。
registerCommand()
は戻り値としてdisposableを返します。disposableはコマンドの後処理を行ってくれる関数で、context.subscriptions.push(disposable)
としておくことで、拡張機能が無効になるタイミングでコマンドの後処理を行ってくれます。
エラー発生時の対処法
Visual Studio Code拡張機能を作る際にいくつかハマったので備忘録として記載しておきます。
generator-codeのインストールでエラー
generator-code
をインストールしたところ、インストール後に以下のエラーが発生しました。
npm install -g yo generator-code
...
x NODE_PATH matches the npm root
環境変数NODE_PATHを見ても、パスは設定されているので、無視してyo code
を実行してみたところ、今度は以下のようなエラーが発生しました。
D:\Users\kissy\Documents\Visual Studio Code Extension\HelloWorld>yo code
_-----_ ╭──────────────────────────╮
| | │ Welcome to the Visual │
|--(o)--| │ Studio Code Extension │
`---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? HelloWorld
? What's the identifier of your extension? helloworld
? What's the description of your extension?
? Initialize a git repository? No
? Which package manager to use? npm
events.js:187
throw er; // Unhandled 'error' event
^
AssertionError [ERR_ASSERTION]: Trying to copy from a source that does not exist: C:\Program Files (x86)\Nodist\bin\node_modules\generator-code\generators\app\templates\ext-command-ts/vscode
at EditionInterface.exports.copy (C:\Program Files (x86)\Nodist\bin\node_modules\generator-code\node_modules\mem-fs-editor\lib\actions\copy.js:48:3)
at module.exports._writingCommandTs (C:\Program Files (x86)\Nodist\bin\node_modules\generator-code\generators\app\index.js:666:17)
at module.exports.writing (C:\Program Files (x86)\Nodist\bin\node_modules\generator-code\generators\app\index.js:539:22)
at Object.<anonymous> (C:\Program Files (x86)\Nodist\bin\node_modules\generator-code\node_modules\yeoman-generator\lib\index.js:424:27)
at C:\Program Files (x86)\Nodist\bin\node_modules\generator-code\node_modules\run-async\index.js:25:25
at new Promise (<anonymous>)
at C:\Program Files (x86)\Nodist\bin\node_modules\generator-code\node_modules\run-async\index.js:24:19
at C:\Program Files (x86)\Nodist\bin\node_modules\generator-code\node_modules\yeoman-generator\lib\index.js:425:13
at processImmediate (internal/timers.js:439:21)
Emitted 'error' event on Generator instance at:
at Immediate.<anonymous> (C:\Program Files (x86)\Nodist\bin\node_modules\generator-code\node_modules\yeoman-generator\lib\index.js:433:22)
at processImmediate (internal/timers.js:439:21) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '=='
}
仕方ないので、はじめからやってみようと思い、Node.jsをアンインストール(ついでにNodistもアンインストール)、それからNode.jsを再度インストールからしてみました。それでもやっぱり「npm install -g yo generator-code」をしたところで、「NODE_PATH matches the npm root」が発生してしまいました。。
途方に暮れてもう一度、環境変数NODE_PATHを見てみると、なぜかNODE_PATH自体がありませんでした。
そこで、環境変数NODE_PATHを設定したところ、無事「npm install -g yo generator-code」も「yo code」も成功しました。
通常はNode.jsのインストールで設定されるはずですが、追加されていませんでした。もしかすると、Nodistが悪さをしていたのかもしれません。
とりあえず動いたのでそれ以上は深追いしなかったため、本当の原因は分かっていません。
ビルドが永遠に終わらない
generator-codeのエラーが解決して、ようやく拡張機能開発のひな型を作成できるようになりました。
早速ビルドして実行使用してみたのですが、今度は「ビルド中…」と出たままで、いつまでもビルドが完了しない現象が発生。。
この現象、いろいろとググっても情報が見つからず、またまた途方に暮れることになりました。
ひな型コードを再作成してみたり、PC再起動やyo、generator-codeの再インストールなどもやっては見たものの治らず。結局その後、Visual Studio Codeを再インストールしたら、あっさりとビルドでき実行できました。
うーん。変なところでつまづくことが多いなぁ、と思いながらも、とりあえず動いたから良し。
参考サイト
- VSCode API
- 公式ドキュメント。拡張機能で使用できるAPIリファレンスやガイドが書かれている。
- Your First Extension | Visual Studio Code Extension API
- 公式ドキュメント。拡張機能のHello worldを作る方法が書かれている。
- microsoft/vscode-extension-samples
- 公式サンプル。Hello world他、多数のサンプルが公開されている。
- Visual Studio Code’s Markdown Support
- 公式ドキュメント。VSCのMarkdownの機能仕様が書かれている。
- Markdown Syntax Reference
- 公式ドキュメント。GitHubのMarkdownの仕様が記載されている。
最後まで読んでいただきありがとうございます。
また読んでくださいませ。
そんじゃーね。