VSCode のエクステンションは通常は Node で開発しますが、バンドラーのアウトプットを工夫することで、Deno でも開発できます。
VSCode 向けに Deno スクリプトをバンドルする際に気を付けることは以下の点です。
- VSCode がエクステンションとして読み込めるのは CommonJS 形式のみ
- "vscode" パッケージは vscode 本体への依存なのでバンドルしてはいけない
これを実現するための esbuild の設定は以下のようになります。
import * as esbuild from "npm:esbuild@0.24";
import { denoPlugins } from "jsr:@luca/esbuild-deno-loader@0.11";
import { resolve } from "jsr:@std/path@1";
const result = await esbuild.build({
plugins: [...denoPlugins({
configPath: resolve("path/to/deno.json")
})],
entryPoints: ["src/extension.ts"],
outfile: "out/extension.js",
bundle: true,
external: ["vscode"],
format: "cjs",
});
esbuild.stop();
上のビルドスクリプトを実行すると、src/extension.ts
がビルドされて、ビルド結果が out/extension.js
に出力されます。ビルドの際に、import * as vscode from "vscode"
以外の import 文が全てビルド結果に含まれるため、この状態で、vscode から見て実行可能なスクリプトになります。
なお、@kt3k/pack
を使うと以下のように少し簡潔にビルドコマンドを書くことも出来ます (内部的に上と全く同じビルドが実行されます)
deno -A jsr:@kt3k/pack@0.1.14 src/extension.ts -o out/extension.js --external vscode --format cjs
package.json
の main
に ./out/extension.js
を設定することで、このバンドルを VSCode Extension として実行できます。
また、import * as vscode from "vscode";
を Deno で型チェック出来るようにするためには、以下のように記述します。
// @ts-types="npm:@types/vscode";
import * as vscode from "vscode";
これで、vscode
名前空間に適切な型があたります。また、"vscode" というモジュール指定子はDeno から見た場合は実体がないため、import map でこれを空のファイル (空の empty.ts ファイルを作ってください)に向けておきます。
{
"imports": {
"vscode": "empty.ts"
}
}
以上の設定で、vscode extension 開発を Deno だけを使って行うことができます。
以下のレポジトリは、ここまで説明した設定を使って、ピクセルエディタの VSCode Extension を筆者が開発しているサンプルです。