Cursorを使ってVSCodeの拡張機能を作成してみた
Cursorを使ってVSCodeの拡張機能を作成してみた
はじめに
現在の職場環境ではセキュリティポリシーの関係で、ChatGPTやGitHub Copilotなどの一般的なAIツールを自由に使用することができません。しかし、VSCodeの拡張機能は社内で承認されているため、この制約の中でも開発効率を上げる方法として、Cursorを活用してVSCode拡張機能を開発することにしました。この記事では、その開発過程で直面した課題と解決策、そして学んだことを共有します。
目次
拡張機能のテンプレート作成
開発環境
- VSCode 1.70.2
- Cursor(Claude 3.5 Sonnet搭載)
- Node.js 16.14.0
- TypeScript 4.7.4
- React 18.2.0
- Mantine 5.10.0
- React Flow 11.5.6
実施したこと
最初のステップとして、VSCode拡張機能の基本的なテンプレートを作成することから始めました。
- Cursorのcomposerに「VSCodeの拡張機能テンプレートを作成してほしい。環境としてReact, TypeScript, Mantine, React Flowを使用したい。WebViewを使ってUIを構築したい」と詳細にリクエスト
- 生成されたコードをVSCodeのデバッグ機能でテスト
- 基本的なUIコンポーネントの配置と動作確認
直面した問題と解決策
最初の大きな障壁は、デバッグ時にコマンドパレットで指定されたコマンドが表示されないという問題でした。何度も試行錯誤した結果、原因が判明しました。
原因:
-
package.json
に指定されたVSCodeのエンジンバージョンが^1.80.0
と最新で、使用しているCursorのVSCodeエンジン(1.70.2
)と互換性がなかった -
activationEvents
の設定が古い形式で記述されていた
解決策:
-
package.json
のengines.vscode
を^1.70.0
に下げて互換性を確保 -
activationEvents
をonCommand:extension.showPrismaVisualizer
形式に修正
"engines": {
- "vscode": "^1.80.0"
+ "vscode": "^1.70.0"
},
"activationEvents": [
- "*"
+ "onCommand:extension.showPrismaVisualizer"
],
教訓:
- AIツールを使う際は、使用する環境のバージョンを明示的に指定することが重要
- 以前にも別プロジェクトでTailwindCSS v3.3.0の最新機能を使ったところ、社内環境のv3.0.0と互換性がなくエラーが発生した苦い経験があります
- 生成されたコードは必ず実際の環境でテストし、必要に応じて調整する必要がある
prisma.schemaの読み込みとモデル作成
このフェーズでは、実際に拡張機能の中核となる機能を実装しました。私たちのチームではPrismaを使ったプロジェクトが多く、新メンバーがデータベース構造を理解するのに時間がかかっていたため、この問題を解決する拡張機能を作ることにしました。
実装した機能
- ワークスペース内のprisma.schemaファイルを自動検出する機能
- ファイルを選択して読み込み、パースする機能
- モデル定義を抽出し、構造化されたデータとして保持する機能
- 各モデルのフィールド、型、関連性を表形式で表示する機能
function parsePrismaSchema(content: string) {
const models: PrismaModel[] = [];
const modelRegex = /model\s+(\w+)\s+{([^}]*)}/g;
let match;
while ((match = modelRegex.exec(content)) !== null) {
const modelName = match[1];
const modelBody = match[2];
const fields = parseModelFields(modelBody);
models.push({ name: modelName, fields });
}
return models;
}
このフェーズでは特に大きな問題はなく、Cursorが提案したコードをベースに機能を拡張していくことができました。テスト用のprisma.schemaファイルを用意し、正しくパースできることを確認しました。
工夫した点
- 複雑なリレーション(1対多、多対多など)も正確に解析できるよう正規表現を工夫
- コメント行を適切に無視する処理を追加
- エラーハンドリングを強化し、不正なスキーマファイルでも落ちないように実装
React Flowによるフロー作成
パースしたPrismaモデルの情報を視覚的に表現するため、React Flowを使ってER図のような形で表示する機能を実装しました。
実装した機能
- 各モデルをノードとして表示
- モデル間のリレーションをエッジ(線)として表示
- ノードには各フィールドの情報(名前、型、必須かどうか)を表示
- ズームイン/アウト、ドラッグ&ドロップでの移動機能
- モデルをクリックすると詳細情報を表示するサイドパネル
直面した問題と解決策
第2の障壁は、ノードをつなぐエッジの描画がうまくいかないという問題でした。特に、リレーションの方向性が正しく表示されませんでした。
原因:
- React Flow v11の実装方法に誤りがあった
- エッジのsourceとtargetの指定方法が間違っていた
- マーカーエンドの設定が不適切だった
解決策:
- 公式ドキュメントを詳細に確認し、正しい実装方法を学習
- エッジの定義を修正
const edges = relationships.map(rel => ({
id: `e-${rel.source}-${rel.target}`,
source: rel.source,
target: rel.target,
+ type: 'smoothstep',
+ markerEnd: {
+ type: MarkerType.ArrowClosed,
+ width: 20,
+ height: 20,
+ },
+ style: { stroke: '#555' },
+ labelStyle: { fill: '#333', fontSize: 12 },
+ label: rel.type,
}));
この修正により、リレーションの方向性と種類(1対多、1対1など)が視覚的に明確になりました。
最終的な状態としては下図のようになりました。
追加した機能
開発を進めていく中で、当初は想定していなかったものの、実際に使ってみると非常に便利だと感じたため、いくつかの機能を追加実装しました:
- モデルのグループ化機能(関連するモデルをまとめて表示)
- レイアウトの自動整列機能(複雑なスキーマでも見やすく配置)
- エクスポート機能(PNG画像として保存可能)
まとめと今後の展望
Cursorを活用してVSCode拡張機能を開発してみて、いくつかの重要な気づきがありました。
- AIツールを使って開発する際は、使いたいライブラリやツールのバージョンをきちんと指定しておくことが大切
- これを怠ると、思わぬところでハマってしまう
- AIが生成したコードはそのまま信じ込まずに、必ず動作確認をして、公式ドキュメントと照らし合わせるべき
- 特にReact Flowのようなライブラリは、実装方法を正確に理解していないと期待通りの結果が得られない
- VSCode拡張機能は日々の業務を効率化するための強力な武器になり得る
- プライベートでは使えるAIツールが職場では制限されている環境でも、拡張機能という形で効率化ツールを提供できるのは大きなメリット
- WebViewを活用することで、VSCodeという限られた環境の中でも、リッチなUIを持つアプリケーションが実現可能
- React FlowによるER図の可視化は、その良い例
今後の展望
今後追加したい機能としては
- スキーマの変更履歴を追跡し、変更点をハイライトする機能
- マイグレーションファイルとの連携機能
- 実際のデータベースに接続し、テーブルごとのレコード数を表示する機能
- コード生成機能の強化(リポジトリ名が示すように、最終的にはコード生成ツールとしての機能も充実させたい)
AIツールの制約がある環境でも、VSCode拡張機能という形で開発効率化ツールを提供できることがわかりました。今後も業務効率化のためのツール開発を続けていきたいと思います。
Discussion