【入門編】VS Codeの「拡張機能開発」入門:自分専用のコマンドを追加して、面倒な繰り返し作業を自動化しよう – 軽量・高機能テキストエディタ生産性向上バイブル

こんにちは!日々のコーディング、本当にお疲れ様です。

突然ですが、皆さんは毎日の開発作業の中で「あー、またこの定型コードを手で書いてるな……」「ファイル名から特定のフォーマットに変換してリネームする作業、毎回面倒だな……」と感じたことはありませんか?

世の中には便利な拡張機能が溢れていますが、「かゆいところに手が届く、うちのプロジェクト専用の小さな自動化ツール」というのは、なかなか見つからないものです。

「ないなら、自分で作ってしまえばいい。」

そう聞くと、「なんだか難しそう」「TypeScriptとかよく分からないし……」と身構えてしまうかもしれません。でも、安心してください。実はVS Codeの拡張機能開発は、私たちが普段書いているWebフロントエンドやNode.jsの知識があれば、驚くほど簡単かつスピーディに始められます。

今回は、数ある拡張機能の中でも最も基本となる「自分専用のカスタムコマンドを追加して、面倒な繰り返し作業を自動化する第一歩」を、プロのアーキテクトの視点も交えながら、優しく丁寧に解説していきます。

これをマスターすれば、明日のあなたの開発スタイルが劇的に変わりますよ。一緒に手を動かしていきましょう!

—

なぜ「自分専用の拡張機能」を作るべきなのか?

多くのエンジニアは、定型作業を効率化するためにシェルスクリプト(BashやPowerShell)を書いたり、VS Codeのタスクランナーを設定したりします。それらも素晴らしいアプローチです。

しかし、VS Codeの「拡張機能」としてロジックを組み込むことには、決定的なアドバンテージがあります。

1. GUIとシームレスに統合できる: コマンドパレット(`Ctrl+Shift+P` / `Cmd+Shift+P`)やエディタの右クリックメニューから、いつでもワンタッチで呼び出せる。
2. エディタのコンテキストを利用できる: 「今開いているファイルのパス」「選択中のテキスト」「ワークスペースのルートディレクトリ」といったVS Code内部の強力なAPIを直接叩いて料理できる。
3. チーム全体へ瞬時に共有・資産化できる: `.vsix`というパッケージ形式にして共有するか、社内マーケットプレイスに置くだけで、チーム全員が同じ自動化の恩恵を受けられる。

シェルスクリプトの延長線上にありながら、VS Codeの頭脳と直接対話できるのが拡張機能開発の醍醐味です。

—

開発環境のセットアップ:最強の職人道具を揃える

まずは、拡張機能を作るための土台を整えます。VS Codeの拡張機能は基本的に TypeScript で開発します。型安全な環境でコードを書くことで、APIの仕様迷子を防ぎ、圧倒的な開発生産性を手に入れます。

1. 必要なツールのインストール

以下のツールがマシンにインストールされていることを確認してください(Node.jsのLTS版が入っていればOKです)。

  • Node.js (推奨: LTS版。npmも同梱されています)
  • VS Code (当然、開発対象であり実行環境でもあります)

2. 雛形ジェネレータ(Yeoman)の導入

拡張機能のプロジェクト構造を一瞬で構築するために、スキャッフォールディングツールである Yeoman(ヨーマン) と、VS Code専用のジェネレータをグローバルインストールします。

ターミナル(またはコマンドプロンプト)を開き、以下のコマンドを実行してください。

generator-code(VS Code拡張機能の雛形を作るツール)をYeoman経由でグローバルインストール
npm install -g yo generator-code

このツールが、面倒な設定ファイル(`package.json` や `tsconfig.json` など)の初期設定をすべて肩代わりしてくれます。まさに縁の下の力持ちです。

—

Yeomanで拡張機能の「雛形」を生成する

環境が整ったら、いよいよプロジェクトの生成です。ターミナルで以下のコマンドを叩いてください。

yo code

コマンドを実行すると、対話形式でいくつか質問されます。以下のように選択・入力していきましょう(方向キーで選択し、Enterで確定します)。

1. What type of extension do you want to create?

  • ➔ `New Extension (TypeScript)` (型安全に開発するため、必ずTypeScriptを選びましょう)

2. What’s the name of your extension?

  • ➔ `my-first-extension` (拡張機能の名前です。お好みの名称でどうぞ)

3. What’s the identifier of your extension?

  • ➔ `my-first-extension` (識別子。そのままEnterでOKです)

4. What’s the description of your extension?

  • ➔ `A simple extension to automate my daily routine.` (簡単な説明文)

5. Initialize a git repository?

  • ➔ `Yes` (Git管理にしておくと安心です)

6. Which package manager to use?

  • ➔ `npm` (お好みですが、今回は標準的なnpmを選択)

数秒待つと、カレントディレクトリに `my-first-extension` というフォルダが生成されます。
それでは、生成されたプロジェクトをVS Codeで開きましょう!

code my-first-extension

—

プロジェクト内部の構造を理解する

VS Codeが立ち上がったら、左側のエクスプローラーからファイル構成を覗いてみてください。拡張機能の心臓部となる重要なファイルは、主に以下の2つです。

1. `package.json`

  • 拡張機能の「設計図」です。名前やバージョンだけでなく、「この拡張機能はどんなコマンドを登録し、どこに表示するか」というメタデータを定義します。

2. `src/extension.ts`

  • 拡張機能の「頭脳(ロジック)」です。コマンドが実行されたときに実際に何を行うかをTypeScriptで記述します。

—

HelloWorldからカスタマイズへ:コードの核心に迫る

生成された初期状態のままで、すでに「Hello World」というコマンドが動くようになっています。まずはこれを動かしてみましょう。

1. デバッグ実行のやり方

1. VS Codeで `my-first-extension` を開いた状態で、キーボードの `F5` キーを押します。
2. すると、「Extension Development Host」 というタイトルの新しいVS Codeウィンドウが自動で立ち上がります。これが、あなたの開発中の拡張機能をテスト実行するための「サンドボックス環境」です。

2. コマンドを動かしてみる

3. 新しく立ち上がったウィンドウで、`Ctrl+Shift+P` (Macは `Cmd+Shift+P`)を押してコマンドパレットを開きます。
4. `Hello World` と入力してEnterを押してみてください。
5. 右下に 「Hello World from my-first-extension!」 というトースト通知(ポップアップ)が表示されましたか?

おめでとうございます!これであなたは、VS Codeの拡張機能をビルドして動かす一連のライフサイクルを完全に手に入れました。

—

実践:自分専用の「便利コマンド」を自作してみる

初期のHello Worldが動いたところで、次はこれを「実務で使える実用的なコマンド」に書き換えてみましょう。

今回は、「現在エディタで開いているファイルのファイル名(パス付き)を、Markdownのリンク形式 `[ファイル名](パス)` に変換してクリップボードにコピーする」 という、地味ながら毎日のドキュメント書きでめちゃくちゃ重宝する機能を作ります。

1. `package.json` でコマンドを登録する

まずは設計図である `package.json` を開き、コマンドのタイトルや識別子を定義し直します。
`contributes.commands` の部分を探し、以下のように書き換えてください。

{
“name”: “my-first-extension”,
“displayName”: “My First Extension”,
“version”: “0.0.1”,
“engines”: {
“vscode”: “^1.80.0”
},
“categories”: [
“Other”
],
“activationEvents”: [],
“main”: “./out/extension.js”,
“contributes”: {
“commands”: [
{
“command”: “my-first-extension.copyMarkdownLink”, // コマンドの固有ID
“title”: “Copy as Markdown Link” // コマンドパレットに表示される名前
}
]
},
“scripts”: {
“vscode:prepublish”: “npm run compile”,
“compile”: “tsc -p ./”,
“watch”: “tsc -watch -p ./”
},
“devDependencies”: {
“@types/vscode”: “^1.80.0”,
“@types/node”: “16.x”,
“typescript”: “^5.0.0”
}
}

2. `src/extension.ts` でロジックを実装する

次に、`src/extension.ts` を開いて、実際の処理を記述します。
元々書かれているコードをすべて消去し、以下のコードに書き換えてください。各行のコメントで、VS Code APIがどのように動いているかを丁寧に解説しています。

import as vscode from ‘vscode’;

// 拡張機能が有効化されたとき(コマンドが初めて呼ばれたときなど)に一度だけ実行される関数
export function activate(context: vscode.ExtensionContext) {
console.log(‘拡張機能「my-first-extension」が正常に起動しました!’);

// package.jsonで定義したコマンドIDと、実行される処理(コールバック関数)を紐付ける
const disposable = vscode.commands.registerCommand(‘my-first-extension.copyMarkdownLink’, async () => {

// 1. 現在アクティブに開いているエディタ情報を取得する
const editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showWarningMessage(‘現在開いているアクティブなファイルがありません。’);
return;
}

// 2. 開いているファイルのワークスペースからの相対パスを取得する
const fileUri = editor.document.uri;
const workspaceFolder = vscode.workspace.getWorkspaceFolder(fileUri);

let relativePath = fileUri.fsPath;
if (workspaceFolder) {
// ワークスペース内であれば、相対パスに変換してスラッシュ区切りに正規化する
relativePath = vscode.workspace.asRelativePath(fileUri);
relativePath = relativePath.replace(/\\/g, ‘/’);
}

// 3. ファイル名のみを抽出する
const fileName = fileUri.path.split(‘/’).pop() || ‘file’;

// 4. Markdownのリンク形式文字列を組み立てる
const markdownLink = `[${fileName}](${relativePath})`;

// 5. システムのクリップボードに文字列をコピーする
await vscode.env.clipboard.writeText(markdownLink);

// 6. ユーザーに成功したことを優しく通知する
vscode.window.showInformationMessage(`Copied to clipboard: ${markdownLink}`);
});

// 拡張機能が破棄されるときにメモリリークを防ぐため、購読リストに登録しておく
context.subscriptions.push(disposable);
}

// 拡張機能が無効化されたときに呼ばれるクリーンアップ関数
export function deactivate() {}

—

動作確認:自作コマンドの切れ味を体感する

コードを書けたら、いよいよテストです。

1. デバッグ中の拡張機能ホストウィンドウを一度閉じます。
2. 開発元の元のVS Codeウィンドウに戻り、`F5` キーを押して再度デバッグビルド&起動を行います。
3. 新しく立ち上がった拡張機能ホスト側で、適当なMarkdownファイルやテキストファイルを開きます。
4. `Ctrl+Shift+P` (Macは `Cmd+Shift+P`)を押し、「Copy as Markdown Link」 と入力して実行!
5. 右下に通知が出たら、適当なメモ帳や別のファイルで `Ctrl+V` (ペースト)してみてください。

どうでしょうか?
`[index.ts](src/index.ts)` のような美しいMarkdownリンクが、一瞬でクリップボードから吐き出されたはずです。

これが、あなたが自分の手で作り上げた、世界に一つだけの自動化ツールです。

—

アーキテクトからのワンポイントアドバイス:ここから先へ進むために

今回作成した拡張機能は、あなたのローカル環境で動くプロトタイプです。これをさらに実務でバリバリ使えるレベルに引き上げるためのヒントをいくつかお伝えします。

  • キーボードショートカットの割り当て:

`package.json` の `contributes.keybindings` を設定することで、`Ctrl+Alt+M` などのショートカットキーでこのコマンドを即座に呼び出せるようになります。

  • パッケージングと配布 (`vsix`):

`npm install -g vsce` を使ってパッケージングツールを入れると、`vsce package` コマンド一発で `.vsix` ファイルが生成されます。これをチームメンバーにチャットで送るだけで、誰でもあなたの作った自動化ツールをインストールできるようになります。

「面倒だな」「また同じ作業してるな」と思ったその瞬間こそが、新しい拡張機能を思いつく最大のチャンスです。

ぜひ今回のコードをベースに、自分やチームのワークフローを爆速にするオリジナルコマンドをたくさん作ってみてください。あなたの毎日のコーディングが、もっと楽しく、もっとスマートになることを心から応援しています!

タイトルとURLをコピーしました