初めてのVSCode Extension公開

# 初めてのエクステンション開発

VSCodeのエクステンションを作成して公開するまでの手順。
大まかには下記だけでとりあえず作れるっぽいことがわかった。

1. yo codeで雛形作成
2. package.jsonの修正
    3. contributes.commandsにコマンドパレット表示名とコマンドIDを登録
    4. activationEventに onCommand:コマンドID を登録 (今回はコマンドパレットから実行したいため)
    5. publisherの設定
5. extension.tsの修正
    6. vscode.commands.registerCommandにコマンドIDと処理を記述
7. Personal Access Tokenの取得 
    8. [Azure DevOps](https://go.microsoft.com/fwlink/?LinkId=307137)にサインインして「Security」>「Personal Access Tokens」で新規トークン作成[^2]　<br>　*Azure DevOpsのOrganizationがない場合は先にそちらの作成が必要[^1]
10. vsce publish で公開


# ネタ元

ググってみたらGetting Startedっぽいページを見つけたので下記を読みながら試行錯誤。

|Title|Content|
|---|---|
|[Your First Extension](https://code.visualstudio.com/api/get-started/your-first-extension)|[Yeoman](https://yeoman.io/)の[VSCode Generator](https://www.npmjs.com/package/generator-code)でのプロジェクトの雛形作成、雛形に少し手を入れてデバッグ実行する方法を教えてくれる。|
|[Extension Anatomy](https://code.visualstudio.com/api/get-started/extension-anatomy)|Your First Extensionで作った雛形の内容を少し細かく解説してくれている。<br>下記について記載されている。 <br> - ファイル構造<br> - Extension Manifest(package.json)<br> - エントリーファイル(extension.ts)|
|[Publishing Extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) |vsceコマンドを使用して作成したエクステンションをマーケットプレースに公開する方法を教えてくれる。<br> 公開するためのPersonal Access Token作成方法も載っている。|
|[vscode-extension-samples](https://github.com/Microsoft/vscode-extension-samples/tree/master/helloworld-sample)|エクステンションの色々な実装サンプルコード|
|[VS Code API](https://code.visualstudio.com/api/references/vscode-api)|エクステンションが使用できるAPIが載っている。|


[^1]: Organization作成の手順は[本家サイト](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/create-organization?view=vsts#create-an-organization)に載っているが正直迷いながら進んだ。

[^2]: 具体的な手順は[本家サイト](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#get-a-personal-access-token)参照。

# 1.プログラム作成

## 雛形作成

yoを使用して雛形を作成する。

```terminal
$#yoのインストール (初回のみ)
$npm install -g yo generator-code

$#vscode extensionの雛形作成 (対話でエクステンション名を入力する)
$yo code

$#VSCodeで開く(VSCodeである必要はない。)
code ./extension名(フォルダ名)
```

## Extension Manifest (package.json)の修正

エクステンションのマーケットプレイスへの登録内容やコマンドIDの定義を行う。
詳細は[本家](https://code.visualstudio.com/api/get-started/extension-anatomy#extension-manifest)参照

![Screen Shot 2019-01-04 at 14.51.48.png](https://qiita-image-store.s3.amazonaws.com/0/215058/22228bdf-6cd9-00a0-22cb-5b0261218d10.png)

* activationEvent (onCommand):
    * extensionをアクティブにするイベントを定義する
    * 後述のcontributes.commandsで定義したコマンドがユーザーにより実行された時に
エクステンションがアクティブになる <br>*onLanguageのように開いたファイルの言語が指定されたものの場合に、エクステンションをアクティブにするものもある

* contributes.commands:
    * コマンドパレットへの表示名とコマンドパレットで選択された時に実行するコマンドIDを定義する
        * title: コマンドパレットに表示される名称 (上記画像だと"Hello World")
        * command: コマンドパレットで選択された時に実行するコマンドID

## Entry File(extension.ts)の修正

エクステンションのエントリーファイルの修正を行う。
*package.jsonのmainからエントリーファイルを変更することもできる。

![Screen Shot 2019-01-04 at 14.50.20.png](https://qiita-image-store.s3.amazonaws.com/0/215058/b071a5e9-7644-b1f7-568c-fafa9af2d35c.png)

* activate: activationEvent発生時に実行される。一旦は気にしなくていい。

* deactivate: エクステンション終了時に実行される。一旦は気にしなくていい。

* **vscode.commands.registerCommand**:<br>package.jsonのcommandで定義したコマンドIDと実装の紐付けを行う。<br>定義した処理は context.subscriptions に登録する。
    * 第1引数: package.jsonに定義したコマンドIDを設定
    * 第2引数: 実行する処理をコールバックに記述。
    
# 2.デバッグ

F5などでデバッグ実行をすると [Extension Development Host] という名前でVSCodeが立ち上がる。このVSCode上では開発中のエクステンションを実行できるようになっている。

![Screen Shot 2019-01-04 at 16.02.41.png](https://qiita-image-store.s3.amazonaws.com/0/215058/d009eb43-3738-6b68-f636-730d459553a4.png)

![Screen Shot 2019-01-04 at 16.02.48.png](https://qiita-image-store.s3.amazonaws.com/0/215058/3778b984-f71f-4cf7-4f96-2ce98012326d.png)

# 3.公開

## vsceコマンドのインストール

```terminal
$ npm install -g vsce
```

## Personal Access Token取得

[Azure DevOps](https://go.microsoft.com/fwlink/?LinkId=307137)でPsersona Access Tokenを取得する。

## Publisherの作成

```terminal
$ vsce create-publisher (Publisher名)
```
Personal Access Token (PTA)について確認されたら入力する。

## Publish

エクステンションのルートフォルダ(package.jsonのあるフォルダ)に移動して下記コマンドを実行する。

```terminal
$ vsce publish
```