VSCode Extension を開発して、実際に自分の VSCode へインストールしてみた

Visual Studio Code Advent Calendar 2018 23日目、ついに拡張機能に手を付けてみたしょっさんです、こんにちは。
本日 12月23日は、めでたいことにかしゆかの誕生日です。時限式の拡張機能が準備できないかと、四苦八苦してみました。

# ベースのソースコードを準備する

当たり前のように[Your First Extension](https://code.visualstudio.com/api/get-started/your-first-extension)から、ベースとなるソースコードを準備します。

`yo`と`generator-code`を導入してみたら、次のとおりでした。

```bash
$ npm install -g yo generator-code
npm WARN deprecated cross-spawn-async@2.2.5: cross-spawn no longer requires a build toolchain, use it instead
/Users/sho/.nodenv/versions/10.13.0/bin/yo-complete -> /Users/sho/.nodenv/versions/10.13.0/lib/node_modules/yo/lib/completion/index.js
/Users/sho/.nodenv/versions/10.13.0/bin/yo -> /Users/sho/.nodenv/versions/10.13.0/lib/node_modules/yo/lib/cli.js

> spawn-sync@1.0.15 postinstall /Users/sho/.nodenv/versions/10.13.0/lib/node_modules/yo/node_modules/spawn-sync
> node postinstall


> yo@2.0.5 postinstall /Users/sho/.nodenv/versions/10.13.0/lib/node_modules/yo
> yodoctor


Yeoman Doctor
Running sanity checks on your system

✔ Global configuration file is valid
✔ NODE_PATH matches the npm root
✔ Node.js version
✔ No .bowerrc file in home directory
✔ No .yo-rc.json file in home directory
✔ npm version
✔ yo version

Everything looks all right!
+ yo@2.0.5
+ generator-code@1.1.44
added 923 packages from 308 contributors in 50.674s
```

ベースのソースコードを準備します。

```bash
$ yo code

     _-----_     ╭──────────────────────────╮
    |       |    │   Welcome to the Visual  │
    |--(o)--|    │   Studio Code Extension  │
   `---------´   │        generator!        │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? kashiyuka
? What's the identifier of your extension? kashiyuka
? What's the description of your extension?
? Enable stricter TypeScript checking in 'tsconfig.json'? Yes
? Setup linting using 'tslint'? Yes
? Initialize a git repository? Yes
? Which package manager to use? npm
   create kashiyuka/.vscode/launch.json
   create kashiyuka/.vscode/settings.json
   create kashiyuka/.vscode/tasks.json
   create kashiyuka/src/test/extension.test.ts
   create kashiyuka/src/test/index.ts
   create kashiyuka/.vscodeignore
   create kashiyuka/.gitignore
   create kashiyuka/README.md
   create kashiyuka/CHANGELOG.md
   create kashiyuka/vsc-extension-quickstart.md
   create kashiyuka/tsconfig.json
   create kashiyuka/src/extension.ts
   create kashiyuka/package.json
   create kashiyuka/tslint.json
   create kashiyuka/.vscode/extensions.json


I'm all done. Running npm install for you to install the required dependencies. If this fails, try running the command yourself.



> kashiyuka@0.0.1 postinstall /Users/sho/working/nodejs/work/kashiyuka
> node ./node_modules/vscode/bin/install

Detected VS Code engine version: ^1.30.0
Found minimal version that qualifies engine range: 1.30.0
Fetching vscode.d.ts from: https://raw.githubusercontent.com/Microsoft/vscode/c6e592b2b5770e40a98cb9c2715a8ef89aec3d74/src/vs/vscode.d.ts
vscode.d.ts successfully installed!

npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN kashiyuka@0.0.1 No repository field.
npm WARN kashiyuka@0.0.1 No license field.

added 238 packages from 496 contributors and audited 960 packages in 8.84s
found 0 vulnerabilities


Your extension kashiyuka has been created!

To start editing with Visual Studio Code, use the following commands:

     cd kashiyuka
     code .

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.
```

Javascriptしかわからないのに、TypeScript選択してしまう程度には初心者です。

# src/extension.ts を書き換える

12/23 と同じ日付のときだけ処理をしたいので、楽をしようと `moment`モジュールを追加しています。 `npm install moment --save` が必要です。

```typescript:src/extension.ts
import * as vscode from 'vscode';
import * as Moment from 'moment';

export function activate(context: vscode.ExtensionContext) {
	let disposable = vscode.commands.registerCommand('extension.kashiyuka', () => {
		const today = Moment().format("MM-DD");
		const kashi = new Date("1988/12/23");

		if (today === Moment(kashi).format("MM-DD")) {
			vscode.window.showInformationMessage('Happy birthday Kashiyuka!');
		}
	});

	context.subscriptions.push(disposable);
}

// this method is called when your extension is deactivated
export function deactivate() { }
```

プログラム自体は、もうほんとに大したことをしていません。

# Azure DevOps のアカウントを準備

なんか名前が変わったのか統一されたのか、結果的には`Azure DevOps`のアカウントを取得しました。
[Quickstart: Create an organization](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/create-organization?view=vsts)

ここで作成した `Organization` が、そのまま publisher-name になります。Personal Access Token を取得してから、ローカルで `vsce`を使って、`.vsix`ファイルを作成します。

# VSCEでパッケージング

まずは、`vsce`をインストールしておきます。

```bash
$ npm install -g vsce
/Users/sho/.nodenv/versions/10.13.0/bin/vsce -> /Users/sho/.nodenv/versions/10.13.0/lib/node_modules/vsce/out/vsce
+ vsce@1.54.0
added 60 packages from 67 contributors in 6.14s
```

`package.json` と `README.md`に修正が必要です。

## package.json

`package.json` には `"publisher":` を追記します。内容は、先程 Azure DevOps で作成した `Organization` です。

## README.md

初期状態のままだとだめなので、適当に修正します。おまかせします。

## パッケージング

公開はしないので、手元にファイルができるところまでで進めていきます。<***>の部分は予測してどうぞ。

```bash
$ vsce create-publisher <publisher-name>
Publisher human-friendly name: (<publisher-name>) sho-san
E-mail: <e-mail address>
Personal Access Token: ****************************************************

Successfully created publisher '<publisher-name>'.
```

次に `vsce package` です。これで、ローカルに `.vsix` ファイルができあがります。
自宅のマシンのディレクトリを晒すくらいはどうってことないので、ディレクトリはそのままです。

```bash
$ vsce package
Executing prepublish script 'npm run vscode:prepublish'...

> kashiyuka@0.0.1 vscode:prepublish /Users/sho/working/nodejs/work/kashiyuka
> npm run compile


> kashiyuka@0.0.1 compile /Users/sho/working/nodejs/work/kashiyuka
> tsc -p ./

A 'repository' field is missing from the 'package.json' manifest file.
Do you want to continue? [y/N] y
Created: /Users/sho/working/nodejs/work/kashiyuka/kashiyuka-0.0.1.vsix (372 files, 733.52KB)
```

`kashiyuka@0.0.1` っていいっすね。

ということで、このできあがった`.vsix`ファイルを、VSCode の拡張機能で読み込めば、自分だけの拡張機能が登録できます。

やったぜ。ありがとう、かしゆか。