Denoを最大限使えるvscodeのsettings.jsonを作ってみた

# はじめに
今年ももう12月。アドベントカレンダーの時期ですねぇ。今年も自分なりにDenoにどっぷり浸かった一年でした。

僕が普段コードを書くときはVSCodeを使っており、もちろんDenoのコード書く時にも使っています。
DenoはランタイムだけでなくLSPも入っているので、VSCodeで補完などの恩恵を得ることができます！

# 設定ファイルをつくっていく

ということで、公式マニュアル [Using Visual Studio Code](https://deno.land/manual@v1.16.4/vscode_deno)に乗っ取りながら、少し便利な機能も追加して設定ファイルを作っていこうと思います。
章立ても公式マニュアルと同じようにしていきます。

## Installing

VSCode拡張機能をインストールしましょう。

https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno

VSCode拡張機能はDeno CLIを使うため、Deno本体がインストールも必要がです。

## Configuring the extension

VSCodeでDenoが使えるように設定していきましょう。

### Deno enabling a workspace

VSCode上で「Ctrl + Shift + P」または「F1」を押すと出てくるコマンドパレット。`deno`と打つと下の画像のようなリストが画面上部中央に出てくるかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/c6ec069b-5020-e820-72d7-68a376fa6d39.png)

そこで画像の一番上に出ている「Deno: Initialize Workspace Configration」を選択すると、以下の2つの質問が出てくるので適当に答えてください。

- Enable Deno linting?
- Enable Deno unstable APIs?

僕は`Yes`,`No`の順番で答えました。

すると、`.vscode/settings.json`が以下のように出来上がります。

```json:settings.json
{
  "deno.enable": true,
  "deno.lint": true,
  "deno.unstable": false
}
```

これで、VSCodeでDenoの補完が効くようになりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/62e629a7-a406-e583-e9b1-9bf204ff19d1.png)

### Using linting

上の初期設定で設定済みなので飛ばします。

### Using import maps

DenoはImportMapが使えます。settings.jsonに直接内容を書くこともできますが、VSCodeを使わない人もいるので、ファイルを参照しておきましょう。`import_map.json`には[Standard Library](https://deno.land/std@0.117.0)が楽に使えるように設定しておきましょう。

```json:import_map.json
{
  "imports": {
    "std/":"https://deno.land/std@0.117.0/"
  }
}
```
 
`settings.json`に以下を追記します。

```json
{
  "deno.importMap": "./import_map.json"
}
```

### Using a configuration file

Denoは(たしか)1.14からConfigファイルをサポートするようになりました。`deno.json`[^1]にいろいろ書いて、コマンド実行時に`--config <filepath>`とすればConfigを読み込んでくれます。

[^1]: 現在ファイル名に決まりはないものの、`deno.json`や`deno.jsonc`にしておくと将来のアプデでConfigファイルを自動読み込みしてくれるようになるかもしれません。

設定できる項目などは公式マニュアルの [Configuration file](https://deno.land/manual@v1.16.4/getting_started/configuration_file) をご覧ください。

今回は簡単なひな形だけ書いておきましょう。

```json:deno.json
{
  "compilerOptions": {
  },
  "lint": {
    "files": {
      "include": [],
      "exclude": []
    },
    "rules": {}
  },
  "fmt": {
    "files": {
      "include": [],
      "exclude": []
    },
    "options": {}
  }
}
```

:::note info
ここが公式マニュアルに明記されていないJSON Schema設定の部分。
:::

`deno.json`は設定できる項目が多い反面、どうやって書けばいいんだっけ？みたいなこともよくあります。公式でjson schemaが公開されているので、うろ覚えでも使えるように設定しておきましょう。（json schemaの設定はVSCode自体の機能です。）

ということで`settings.json`には以下を追記。

```json
{
  "deno.config": "./deno.json",
  "json.schemas": [{
    "fileMatch": ["/deno.json"],
    "url": "https://deno.land/x/deno/cli/schemas/config-file.v1.json"
  }],
}
```

### Using formatting

Deno CLIにはフォーマッタもついています。せっかくなのでフォーマットもDenoにしてもらいましょう。

`settings.json`に以下を追記。

```json
{
  "editor.defaultFormatter": "denoland.vscode-deno"
}
```

### Setting a path to the Deno CLI

Deno CLIにPATHが通ってないときとかに使うオプションです。`settings.json`に`deno.path: <path>`とすると設定できるみたいですが、今回は普通にインストールされていると仮定して追記はしません。

## Import suggestions

通常、`import { } from "~~~"`と書くときに、ローカルファイルだと自動でファイル名などを補完してくれますが、リモートモジュールの場合はうまく機能しません。
しかし、モジュールの提供先がこの機能に対応していた場合[^2]にはリモートモジュールでも補完してくれます。
今回は、`deno.land`の補完を有効にしておきましょう。

有効にしておくとこんな感じで補完が効きます。（個人的にこのバージョン補完は嬉しいかも）

{![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/7e579447-9143-8f21-72bf-4aa6198b3166.png)

[^2]: 対応しているかどうかは、実際にインポート文を書いているときに右下に「ここは補完に対応しているけどそれ有効にしとく？」てきな表示が出てくるので、そこで「Enable」を押せば`settings.json`に勝手に追記してくれます。

`settings.json`に以下を追記

```json
{
  "deno.suggest.imports.hosts": {
    "https://deno.land": true
  }
}
```

## Code lenses

コードレンズという機能もサポートしているようです。この関数・変数は何回使われてるよーなどのプチ情報をエディタ上で確認できます。参照先があるかの判別などにはとても便利です。

以下の例では、`lib.ts`でexportされている`hello`という関数は、`lib.ts`だけで見るとで使用されていないように見えるが、実際には`main.ts`で参照されている。そのときにコードレンズが有効だと参照されてるんだなぁというのが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255360/77b66bbb-08ee-cdbe-9be6-ae3c7bfbe056.png)

ということで、`settings.json`に以下を追記。

```json
{
  "deno.codeLens.implementations": true,
  "deno.codeLens.references": true,
  "deno.codeLens.referencesAllFunctions": true
}
```

# `settings.json`

以上でDenoを最大限使える`settings.json`が出来ました！
最終的なものはこちらです。

```json:settings.json
{
  "deno.enable": true,
  "deno.lint": true,
  "deno.unstable": false,
  "deno.importMap": "./import_map.json",
  "deno.config": "./deno.json",
  "json.schemas": [{
    "fileMatch": ["/deno.json"],
    "url": "https://deno.land/x/deno/cli/schemas/config-file.v1.json"
  }],
  "editor.defaultFormatter": "denoland.vscode-deno",
  "deno.suggest.imports.hosts": {
    "https://deno.land": true
  },
  "deno.codeLens.implementations": true,
  "deno.codeLens.references": true,
  "deno.codeLens.referencesAllFunctions": true
}
```

これだけの機能が初めから入っているDenoってやっぱいいですね🦕

# 実行時

ちなみにコマンドで`main.ts`を起動させたいとき、vscodeの設定環境と同じ環境にするには

```console
> deno run -A --config ./deno.json --import-map ./import_map.json main.ts
```
と実行する必要があります。fmtやlintも同じような感じです。

```console
> deno fmt --config ./deno.json main.ts
> deno lint --config ./deno.json main.ts
```

少し長いですね…。ここら辺は`deno.json`の自動認識などこれからのアップデートに期待していきたいところです。

[denon](https://deno.land/x/denon@2.4.10)や[Velociraptor](https://velociraptor.run/)などのDeno実行ツールもあるのでこれを活用するのも一つの手です。

# テンプレートリポジトリ

今回の記事で作成した設定ファイル一式をリポジトリにまとめました。
テンプレートリポジトリになっているのでよかったら使ってください！
PR、issueも大歓迎です（にほんごおっけーよ。）

https://github.com/kamekyame/deno-init-template

# さいごに

今年もアドベントカレンダー書きたいなーと思っていたらいつの間にか12月入ってました笑
あまり考えずに記事書いているので間違いとかあったら修正・コメントください。

ではちょっと早いですがよいクリスマスとよいお年を！！