はじめての VSCode 拡張作成
モチベーション…達人プログラマーで紹介されている一般原則に ETC原則というものがあり、
ファイルを保存するたびに「ETC?」というメッセージを表示するようにし、今入力したコードが変更しやすいものになっているかを考えられるようにしてください。
毎回だと気が変になるというのであれば、10回に1回でもよいでしょう。
これ↑を VSCode で実践したいと思ったため。
やってみるか。
プロジェクトの作成はYeoman(yo)を使用するのが一番簡単です。Yeomanでは予め用意した雛形に則ってプロジェクト初期化を行えるモジュールです。
まずgenerator-codeをグローバルインストールします。これをYoemanで使用するとVS Code拡張のプロジェクトの雛形を生成できます。
npm install -g generator-code
% npm install -g generator-code
added 226 packages in 22s
63 packages are looking for funding
run `npm fund` for details
npm notice
npm notice New minor version of npm available! 10.7.0 -> 10.8.1
npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.8.1
npm notice To update run: npm install -g npm@10.8.1
npm notice
Reshimming asdf nodejs...
npx yo code を実行する
% npx yo code
Need to install the following packages:
yo@5.0.0
Ok to proceed? (y) y
npm warn deprecated are-we-there-yet@1.1.7: This package is no longer supported.
npm warn deprecated npmlog@2.0.4: This package is no longer supported.
npm warn deprecated gauge@1.2.7: This package is no longer supported.
(node:56554) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
_-----_ ╭──────────────────────────╮
| | │ Welcome to the Visual │
|--(o)--| │ Studio Code Extension │
`---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What type of extension do you want to create? (Use arrow keys)
❯ New Extension (TypeScript)
New Extension (JavaScript)
New Color Theme
New Language Support
New Code Snippets
New Keymap
New Extension Pack
New Language Pack (Localization)
New Web Extension (TypeScript)
New Notebook Renderer (TypeScript)
Which bundler to use?
どうしよう。webpack と esbuild って何が違うんだろう?
? Which bundler to use? (Use arrow keys)
❯ unbundled
webpack
esbuild
webpack、babel、esbuildをちゃんと理解したい。より
webpack、babel、esbuildをちゃんと理解したい。
👉FW内部で誰が何のビルド/変換処理を担っているのか → webpack/babelとは?
👉ここ2,3年で台頭してきたesbuildは何がいいのか。
✅webpackが1つのファイル(main.js)にバンドルにしている主な理由は
ES6導入のimport/exportを、バンドルしてES5でも使える形に変換するため。
ES6導入のimport/export構文をブラウザ上で使えるようになった今、必ずしもwebpackで1つのmain.jsにまとめる必要はない。
babelとは
✅JavaScriptのコンパイラ/トランスパイラ。
✅主な目的はES6+コード(Promise/Template Literal)をES5-friendlyコードへの変換。
✅esbuildは、各Content(JS/TS/JSX/JSON/etc)に対して変換処理を担うLoaderが用意されており、各Loaderはesbuildに「JSファイルはこんな感じで変換してくれ」と伝える感じ。
esbuild、なぜ速い?
△ ESModulesを利用するため、一部しかバンドルしないから。
〇 Go言語で書かれている=ネイティブコードであるから。
〇 並行処理で利用可能なCPUコアを使った高速処理。
〇開発時のバンドルのみesbuildを使った事前バンドルを行うため。
うーん、よくわからんな。結局何が違うんだ?まあ esbuild にするか。早いらしいし。
セットアップ結果
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? etc-reminder
? What's the identifier of your extension? etc-reminder
? What's the description of your extension?
? Initialize a git repository? Yes
? Which bundler to use? esbuild
? Which package manager to use? npm
Writing in /Users/kattsun/etc-reminder...
create etc-reminder/.vscode/extensions.json
create etc-reminder/.vscode/launch.json
create etc-reminder/.vscode/settings.json
create etc-reminder/.vscode/tasks.json
create etc-reminder/package.json
create etc-reminder/tsconfig.json
create etc-reminder/.vscodeignore
create etc-reminder/esbuild.js
create etc-reminder/vsc-extension-quickstart.md
create etc-reminder/.gitignore
create etc-reminder/README.md
create etc-reminder/CHANGELOG.md
create etc-reminder/src/extension.ts
create etc-reminder/src/test/extension.test.ts
create etc-reminder/.vscode-test.mjs
create etc-reminder/.eslintrc.json
Changes to package.json were detected.
Running npm install for you to install the required dependencies.
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated glob@8.1.0: Glob versions prior to v9 are no longer supported
added 379 packages, and audited 380 packages in 30s
127 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Your extension etc-reminder has been created!
To start editing with Visual Studio Code, use the following commands:
code etc-reminder
Open vsc-extension-quickstart.md inside the new extension for further instructions
on how to modify, test and publish your extension.
For more information, also visit http://code.visualstudio.com and follow us @code.
? Do you want to open the new folder with Visual Studio Code? Open with `code`
Run Extention を実行してみるが、何もおこらない…。
VS Codeのデバッガーで[Run Extension]をクリック。
すると別ウィンドウが開く
って書いてるのにな…。
package.json を確認。"activationEvents": [],
だった。
activationEvents
では、どのコマンドがどのイベント発生時に呼び出される(アクティベートされる)かを定義します。
と書いてあるので入れてみる。
"activationEvents": [
"onCommand:etc-reminder.helloWorld"
],
すると "This activation event can be removed as VS Code generates these automatically from your package.json contribution declarations." という注意書きがでてきた。
Activation Events | Visual Studio Code Extension API によると
Note: Beginning with VS Code 1.74.0, commands contributed by your extension do not require a corresponding
onCommand
activation event declaration for your extension to be activated.
ということらしい。onCommand
は定義しなくてよさそうだ (ちなみに現バージョンは Version: 1.90.0 (Universal))。
Run Extention を実行してみるが、何もおこらない…。
一回 VSCode を開き直して Run Extention を実行したら別ウインドウが開いた。よかった。
ChatGPT にファイルを保存したときに activate するためのコードの書き方を聞いた。vscode.workspace.onDidSaveTextDocument
を教えてもらったが、例示されたコードに [[registerCommand]] がなかったので動かずに時間を少し溶かしてしまった。
vscode.window.showInformationMessage()
でメッセージ表示をする処理を、vscode.commands.registerCommand
で登録しています。このコマンドの登録処理は必須となります。
(from: かんたん!VS Code拡張機能開発 | DevelopersIO)
↓ で動いた
export function activate(context: vscode.ExtensionContext) {
vscode.workspace.onDidSaveTextDocument((document: vscode.TextDocument) => {
vscode.window.showInformationMessage(`${document.fileName} is ETC?`);
});
const disposable = vscode.commands.registerCommand('etc-reminder.remindEtc', () => {
vscode.window.showInformationMessage('etc-reminder is activated!');
});
context.subscriptions.push(disposable);
}
一旦やりたい挙動は実現できたので拡張機能として使える準備をする。
README をデフォルトから変更する (Usage を書きたかったが、いったん WIP にしておく)。
この状態で、npx vsce package
を実行してみる。
次の
vsce package
を実行してプロジェクトをパッケージします。vsceはVisual Studio Code Extension Managerです。
実行結果
% npx vsce package
Need to install the following packages:
vsce@2.15.0
Ok to proceed? (y) y
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated vsce@2.15.0: vsce has been renamed to @vscode/vsce. Install using @vscode/vsce instead.
(node:16325) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
Executing prepublish script 'npm run vscode:prepublish'...
> etc-reminder@0.0.1 vscode:prepublish
> npm run package
> etc-reminder@0.0.1 package
> npm run check-types && npm run lint && node esbuild.js --production
> etc-reminder@0.0.1 check-types
> tsc --noEmit
> etc-reminder@0.0.1 lint
> eslint src --ext ts
[watch] build started
[watch] build finished
WARNING A 'repository' field is missing from the 'package.json' manifest file.
Do you want to continue? [y/N] y
WARNING LICENSE.md, LICENSE.txt or LICENSE not found
Do you want to continue? [y/N] y
DONE Packaged: /Users/kattsun/ghq/github.com/kattsun44/etc-reminder/etc-reminder-0.0.1.vsix (6 files, 2.8KB)
vsix ファイルの作成を確認。
% ls -lA | grep vsix
-rw-r--r-- 1 kattsun staff 2863 Jun 8 14:06 etc-reminder-0.0.1.vsix
[Extentions] > "…" > [Install from TSIX] をクリックし、上記ファイルを選択
Completed installing etc-reminder extension from VSIX.
インストールできた!使えるようになった!けど文章が畳まれて "ETC?" が読めねえ
できた。