こんにちは、ちょっと前に 3 ヶ月半の育児休業から復帰したくらさわです。 なんと今日で生まれてちょうど半年です!早い!!
こちらの記事は Gunosy Advent Calendar 2021 の 16 日目の記事です。 昨日の記事は yamaYu さんの『EKS Managed Node Group でカーネルパラメータを変更する 』でした。
今回は Visual Studio Code (以下 VS Code) の拡張機能を開発した話 + α を書きたいと思います。 タイトルが全てです。
はじめに
Prettier って便利ですよね。
私の VS Code の User/settings.json
は以下の感じ (一部) で デフォルトフォーマッタを Prettier にし、他のフォーマッタを個別に指定してます。
{ "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "[go]": { "editor.defaultFormatter": "golang.go" }, "[terraform]": { "editor.defaultFormatter": "hashicorp.terraform" } }
最近よく書く yaml もフォーマットできるのでとてもいい感じです。 マークダウンまでフォーマットが効くのでこの記事も Prettier でフォーマットしてます。
そんな、たいていのファイルをフォーマットかけてる私ですが、たまにフォーマットをかけたくない時があります。 git の commit にフォーマットの差分を含めたくない時とかですね。
そういう時に、一時的に Prettier を無視してくれるツールがあったらいいなと、そんな思いで拡張機能を作成しました。 まあ作らなくてもあったんですが...
( 軽く探したんですが、探し方が甘かった。
というか、見つかってしまったら Advent Calendar のネタがなくなるという思いが我が眼を曇らせませた。 )
作成した拡張機能
Ignore Prettier という拡張機能を作成しました。
GitHub のリポジトリは こちら。
機能としては
.prettierignore
に現在 VS Code で開いているファイルを追加する.prettierignore
から現在 VS Code で開いているファイルを削除する
があり、1 と 2 の間で保存すれば一時的に Prettier のフォーマッタを無視できるというとても原始的なものです。
1 の時点で .prettierignore
がなければ作成され, 2 の後に .prettierignore
が空になれば削除するようにしています。
拡張機能作成の流れ
ここからは VS Code 拡張機能の作り方を軽く紹介しようと思います。 公式情報は Your First Extension にあります。
セットアップ
Yeoman と VS Code Extension Generator をインストール
npm install -g yo generator-code
Yeoman を実行
yo code
インタラクティブに質問されるのでそれに答えればプロジェクトが作成されます。
※ 私は Typescript を選択したのでこれ以下はその場合の説明だと思ってください。
プロジェクトを開く
やはり VS Code で開発を進めます。 VS Code でプロジェクトを開いて F5 を押すとデバッグ用の VS Code がまた別に立ち上がるのでそこで動かしながら開発していきます。
ちなみにプロジェクトを VS Code を開いた時に TypeScript + Webpack Problem Matchers がレコメンドされてるかもしれませんがそれがないとテストがうまく動きません。 それをインストールせずにいたらはまりました。
コード
私は今回コマンドを叩いたら処理が実行されるものを作成したのでそこを中心に説明します。
まず package.json に Extension Manifest の項目が追加されています。
コマンドを作成する時に修正する項目は contributes.commands
, activationEvents
の主に 2 つです。
contributes.commands
contributes.commands は公開するコマンドを以下のように定義します。
"contributes": { "commands": [ { "command": "helloworld.helloWorld", "category": "Hello", "title": "World" } ] },
これでコマンドパレットを開いた時に Hello: World
とコマンドが表示され、helloworld.helloWorld
に紐づいた処理が実行されます。
category はなくても大丈夫です。
activationEvents
activationEvents は拡張機能がアクティベートされるイベントを定義します。
以下のようにすると helloworld.helloWorld
のコマンドが実行された時にアクティベートされます。
"activationEvents": [ "onCommand:helloworld.helloWorld" ],
activate 関数
拡張機能がアクティベートされた時に呼ばれる関数が src/extension.ts に定義されています。 はじめに定義されてるものはざっくり以下の感じです。
import * as vscode from "vscode"; export function activate(context: vscode.ExtensionContext) { let disposable = vscode.commands.registerCommand("helloworld.helloWorld", () => { vscode.window.showInformationMessage("Hello World from HelloWorld!"); }); context.subscriptions.push(disposable); }
helloworld.helloWorld
というコマンドに VS Code 内で Hello World from HelloWorld!
と表示する処理を登録しています。
お察しのとおり、 package.json で contributes.commands
に定義した command
と紐づきます。
vscode
には他もいろんな API が定義されています。
詳細は VS Code API にあります。
テスト
テストの公式情報は Testing Extensions にあります。 テスト用の VS Code を開いてテストする感じになります。Selenium とかでブラウザ使って自動テストする感じです。
package.json に test スクリプトが定義されていますが、それをそのまま実行してもテストできません。
いくつか方法があるみたいですが、サイドバーから RUN AND DEBUG
を開いて Extension Tests
を実行するとテストできます。
ちなみに、.vscode/launch.json
に実行される処理の定義があります。
以下一部
{ "configurations": [ { "name": "Extension Tests", "type": "extensionHost", "request": "launch", "args": [ "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" ], "outFiles": [ "${workspaceFolder}/out/**/*.js", "${workspaceFolder}/dist/**/*.js" ], "preLaunchTask": "tasks: watch-tests" } ] }
テストの前処理が preLaunchTask
に見慣れない形式で task が定義されていますが、これは .vscode/tasks.json
に定義されていました。
VS Code の機能みたいです。
参考: https://code.visualstudio.com/docs/editor/tasks
この task を実行する時に前述した TypeScript + Webpack Problem Matchers が必要でした。 インストールしていなかったので、テストが実行できずはまりました。
拡張機能を公開
公式情報は Publishing Extensions にあります。
Azure DevOps のアカウント作成 & Token 発行
公開するには Azure DevOps のアカウントが必要なのでない場合は作成します。 アカウントを作成したら Personal Access Token を発行します。
Publishing Extensions にスクショとかあります。
vsce をインストール
公開には Visual Studio Code Extensions
略して vsce
というパッケージを使用します。
npm install -g vsce
publisher を作成
公開するため Visual Studio Marketplace publisher management page から publisher を作成します。
ここの Name
が、拡張機能のページで表示されます。
そして ID
は拡張機能の Identifier
になります。
settings.json などで使用する esbenp.prettier-vscode
の esbenp
が ID
です。
また publisher は package.json に追加する必要があるので追加します。
ID
を追加します。
publisher を作成したら以下のコマンドでログインできたら成功です。 この時 Personal Access Token を使用します。
vsce login <publisher id>
publish
以下コマンドで公開できます。
vsce publish
もし package.json に足りない項目があったり何か不備があるとエラーになるので修正しましょう。
私は license や repository が package.json に足りませんでした。 あと README をちゃんと書いてなくてもエラーになりました。
成功したら Visual Studio Marketplace publisher management page で確認できます。
お疲れさまでした。
さいごに
今のままだと、おそらく自分の作ったものを使うことはなさそうですが、拡張機能作成を通して色々勉強になったのでやってよかったなと感じています。 これからもこれに懲りずに何か思いついたら作っていきたいです。
ということでお待たせしました。 私の拡張機能より便利なものはこちらです。
インストールすると右下にフォーマットをかける、かけないをトグルできる拡張機能が表示されます。結構有名そうなので知ってる方も多いかもしれません。
そして標準機能は Save Without Formatting
って機能です。
Command + Shift + P
押して save without formatting
って打てば見つかります。
一回フォーマットせずに保存したいだけならこれが一番手軽かもです。
ありがとうございました。