VSCode覚書


# 概要

VSCodeについての覚書

# HelloWorld(TypeScript)

## 対象のディレクトリを作る
``` shell
$ mkdir typescript
```

## フォルダを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/c4a0e997-591b-3b50-c2b1-999fb5a79ee6.png)

## tsconfig.jsonを作る

[ファイル] -> [新規ファイル]

``` json
{
    "compilerOptions": {
        "target": "ES5",
        "sourceMap": true,
        "module": "commonjs"
    }
}
```

## HelloWorld.tsを作る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/1b4b95dd-412e-aea9-da76-63d0965628dd.png)

[ファイル] -> [新規ファイル]

``` typescript
function main()
{
    console.log("Hello, World.");
}

main();
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/1ccd474f-8299-eb09-edb1-072909dbecf2.png)

## ビルド

HelloWorld.tsを選択している状態で以下を実行すると.vscode以下にtask.jsonが作成される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/ba2769c0-6366-09c3-e973-9a428f309955.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/80c3d3de-eec1-3099-b025-a1b778e9b0df.png)

HelloWorld.tsを選択している状態でビルドタスクの実行をするとjsやjs.mapファイルができる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/ee81b950-2612-e640-b68f-92fde8e53d9a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/8b86193a-7222-6570-a374-39c7c9db367d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/2a3eca10-c9c1-bf09-012b-364fb32e4726.png)

## 実行

Node.jsを実行する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/4ee8e8d7-a1bc-39de-e7e2-1fb761d66058.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/b623d464-bc50-1962-52a2-ccc3c2f03ec5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/0ccfcf1e-8b10-0b4c-ed08-a4d45cfcece9.png)


<!--
HelloWorld.tsを選択している状態でF1キー or [表示] -> [コマンドパレット]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/9b473cb8-de08-4a27-0b4b-bbf70ab5fbec.png)
-->

* プログラムを変更した場合は「ビルドタスクの実行」からやる
    * でないと変更前のプログラムが実行される
* ショートカット
    * 「Ctrl + Shift + b」でビルドが終わってから「Ctrl + F5」

# NEM/Symbol開発設定

[GettingAccountInformation.ts](https://github.com/nemtech/symbol-docs/blob/master/source/resources/examples/typescript/account/GettingAccountInformation.ts)を実行する設定

``` typescript
// GettingAccountInformation.ts
import {Address, RepositoryFactoryHttp} from 'symbol-sdk';

/* start block 01 */
// replace with recipient address
const rawAddress = 'TAD4HT-CTLXDH-BZWRGJ-73LQYV-OI6SD4-BCD4W5-7AZ7';
const address = Address.createFromRawAddress(rawAddress);
// replace with node endpoint
const nodeUrl = 'http://127.0.0.1:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const accountHttp = repositoryFactory.createAccountRepository();

accountHttp
    .getAccountInfo(address)
    .subscribe((accountInfo) => console.log(accountInfo),
        (err) => console.error(err));
/* end block 01 */
```

## モジュールのインストール

``` shell
$ npm install symbol-sdk@0.19.2 rxjs
```

## tsconfig.json作成

``` json
{
    "compilerOptions": {
        "target": "ES5",
        "module": "commonjs",
        "sourceMap": true,
        "strict": true,
        "esModuleInterop": true,
        "skipDefaultLibCheck": true,
        "forceConsistentCasingInFileNames": true,
        "watch": true
    },
    "compileOnSave": true
}
```

* strict
    * [様々なオプション](https://qiita.com/ryokkkke/items/390647a7c26933940470#strict)をtrueにする
        * 厳密なチェックが行われエラーが出やすくなるオプションなど
* esModuleInterop
    * モジュールを読み込むときの振る舞いをBabelに近づけるようなイメージ
        * [esModuleInterop オプションの必要性について](https://qiita.com/karak/items/29ff148788f5abb15331)
    * skipDefaultLibCheck
        * デフォルトのライブラリの宣言ファイルの型のチェックをスキップ
    * forceConsistentCasingInFileNames
        * 同じファイルへの一貫性のない参照を禁止


タスクの構成
ビルドタスクの実行
実行



# tsconfig.json

## tsconfig.jsonとは

アプリのビルド時にJavaScriptへコンパイルする対象となるTypeScriptファイルと、それらをJavaScriptコードへコンパイルする際のコンパイルオプションなどを指定するファイル。通常プロジェクトのルートディレクトリに配置する

## コンパイル

``` shell
### プロジェクトファイルの中で実行
$ tsc

### ファイルを指定する場合
$ tsc -p tsconfig.json
```

## 構成

### 最小構成

``` json
{
}
```
プロジェクトのルートディレクトリ以下にある全ての.tsファイルがコンパイル対象となる

### 例1

``` json
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es3",
    "noImplicitAny": false,
    "outDir": "built",
    "rootDir": ".",
    "sourceMap": false
  },
  "exclude": [
    "node_modules"
  ]
}
```

* compilerOptionsプロパティ
    * tscコマンド実行時のコマンドライン引数を指定(デフォルト値)
        * `"module": "commonjs"` はコマンドラインでは `--module commonjs`
        * 実際にコマンドラインで実行する場合に同じ引数を指定した場合そちらが優先される
    * オプションについて
        * module
            * 生成するJavaScriptモジュールの形式
        * target
            * 生成するJavaScriptコードのバージョン
        * noImplicitAny
            * trueに設定すると、TypeScriptの型推測でAny型となった式／宣言があったときにはエラーメッセージが生成されるようになる
        * outDir
            *  出力先のディレクトリ
        *  rootDir
            *  プロジェクトのルートディレクトリ（tscコマンドに渡すTypeScriptコードを含んだルートディレクトリ）
        *  sourceMap
            * trueに設定すると、対応するソースマップファイル（.js.mapファイル）が生成されるようになる 
            * ソースファイルはTypeScriptコードとそこから生成されたJavaScriptコードとの対応関係を記述
* excludeプロパティ
    * tscコマンドによるコンパイルの対象外となるファイルまたはディレクトリを指定
* filesプロパティ
    * コンパイル対象のファイルを列挙する
    * ただしfilesプロパティに指定したファイル内で「filesプロパティには指定されていないファイル」を参照していた場合には、そのファイルもコンパイルの対象となる
        * Bar.tsファイルではFoo.tsファイルが公開する関数を利用しているとき、Bar.tsのみ指定していてもFoo.tsもコンパイルされる

### 手動コンパイル不要設定

デフォルトではプログラム変更する毎にコンパイルをやり直す必要があるが
以下の設定でコンパイルのやり直し不要になる。

``` json
// tsconfig.json
{
  "compilerOptions": {
      "target":"ES5",
      "sourceMap": true,
      "module": "commonjs",
      "watch": true         <- 追加
  },
  "compileOnSave": true     <- 追加
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/5c7c02ab-b373-d38e-e6c9-5113136f8bdc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/ec2037d6-d6a6-9207-0074-aca6f4bd8edd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/9775fe5d-9790-cefb-1139-f8d575dcbb6d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/8b1f9f2c-21fe-83ee-a033-e40eaf587820.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/13f4addf-7967-c845-ed1b-632d78941662.png)

この状態になるとプログラム変更後にコンパイルせずプログラムを実行するだけで良くなる。

## リンク

* [tsconfig.jsonの全オプションを理解する（随時追加中）](https://qiita.com/ryokkkke/items/390647a7c26933940470)
* [tsconfig.json（TypeScript構成ファイル）](https://www.atmarkit.co.jp/ait/articles/1603/08/news029.html)
* [コンパイラ・オプション](http://js.studio-kingdom.com/typescript/project_configuration/compiler_options)

# launch.json

実行するときのオプションなど指定

## symbol-cli開発時の例

``` json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program": "${workspaceFolder}/build/src/cli.js",
            "args": ["block", "header", "--height", "1"]
            //"args": ["account", "info"]
        }
    ]
```

* program
    * nodeコマンドを実行するときのjsファイルを指定
* args
    * コンパイル時につけるオプション

# task.json

TypeScript向けBuild/Watchタスクを定義する。

## 1ファイルをコンパイルする場合

``` json
{
    "version": "2.0.0",
    "tasks": [
        {
            "command": "tsc",
            "args": ["${workspaceFolder}/account/CreatingAnAccount.ts"],
            "problemMatcher": [
                "$tsc"
            ],
            "label": "tsc: compile tsfile"
        }
    ]
}
```

* problemMatcher
    * 設定するとエラーカ所をハイライトしてくれるっぽい？

## リンク

* [tasks.json](https://gist.github.com/bonprosoft/fd414f1c7d6f12bd1d6f)
* [Visual Studio Codeの使い勝手をよくするツール](https://www.atmarkit.co.jp/ait/articles/1509/08/news019_2.html)


# .js.mapファイル

元の.jsファイルとの行単位での関係を示し、このファイルを元にデバッグできる

## 例

``` shell
### HelloWorld.js
### 末尾に.js.mapファイルへのパスのコメントが追加される
================================================
function main() {
    console.log("Hello, World.");
}
main();
//# sourceMappingURL=HelloWorld.js.map
================================================

### HelloWorld.js.map
================================================
{"version":3,"file":"HelloWorld.js","sourceRoot":"","sources":["HelloWorld.ts"],"names":[],"mappings":"AAAA,SAAS,IAAI;IAET,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AACjC,CAAC;AAED,IAAI,EAAE,CAAC"}
================================================
```

<!--
## リンク
[VisualStudioCodeデバッグ技術](https://books.google.co.jp/books?id=sPd7DwAAQBAJ&pg=PT57&lpg=PT57&dq=vscode+js.map%E3%81%A8%E3%81%AF&source=bl&ots=8z2af00o1g&sig=ACfU3U3qQUqXls_JA86YbKfGATVNlvg_Cw&hl=ja&sa=X&ved=2ahUKEwilk76s7qzqAhUIy4sBHcp-CiIQ6AEwBXoECAoQAQ#v=onepage&q=vscode%20js.map%E3%81%A8%E3%81%AF&f=false)
-->

# エラー対応

## 対応するJavaScriptが見つからないため、プログラム～を起動できません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/de2040d4-67fe-ccd1-cca0-d3182f80992b.png)

### 状況

``` shell
### /home/vagrant/symbol-cli
tsconfig.json
.vscode/launch.json
.vscode/task.json

### /home/vagrant/symbol-cli/src
GettingAccountInformation.ts
```

### 解消方法
「ビルドタスクの実行」でjsファイルを作成してから実行する

## デバッグ実行してもブレークポイントで止まらない

### 状況
タイトル通り

### 解消方法

launch.jsonのPATHを正しく設定する

``` json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "skipFiles": [
                "<node_internals>/**"
            ],
            "program": "${workspaceFolder}/src/GettingAccountInformation.ts",
            "outFiles": [
                "${workspaceFolder}/src/**/*.js"
                //"${workspaceFolder}/**/*.js"   <- PATHが間違っており動かなかった
            ]
        }
    ]
}
```

※ 再び動かなくなった時はVSCodeを再起動すると動く場合もある

## ProcessingERR The CLI cannot reach the node.
ソースからビルドしたsymbol-cliでコマンドを実行してもnodeに実行されない

### 状況
タイトル通り

### 解消方法

ユーザーの作成については以下実行できた

`symbol-cli profile list` が実行できればGeneration HashとNetwork Currencyを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20474/0a526630-ae9f-3d7c-33a6-786f10d559c1.png)

これをオプションで指定すれば実行できた

``` shell
$ ./bin/symbol-cli profile create --generation-hash A956C113AEB76FEC72A19A6EECDB83CBA7C98647B8A63773E --namespace-id cat.harvest --divisibility 6
? Select the network type: ? TEST_NET
? Enter the Symbol node URL. (Example: http://localhost:3000): … http://localhost:3000
? Enter a profile name: … hoge
? Enter your wallet password: … ********
? Do you want to set the account as the default profile? … no
? Select an import type: ? PrivateKey

Account
...
```

`symbol-cli profile list` が実行できない場合はcurlで調べる

``` shell
### 「networkGenerationHashSeed」を--generation-hash で指定
$ curl http://localhost:3000/node/info
{"version":0,"publicKey":"3FBC1B9D6229EC86BD7032FA6EDB35A9C0F9817BCBF10118DA3C9F1A27AF6C8E","networkGenerationHashSeed":"A956C113AEB76FEC72A19A6EECDB83CBA7C98647B8A63773EB51A3174626F91F","roles":2,"port":7900,"networkIdentifier":152,"host":"api-node-0","friendlyName":"api-node-0"}
```


## Chromeのデバッグモードで [WDS] Disconnected!

Chromeのデバッグモードで題のエラーが発生していてHMR（Hot Module Reload : ソースを変更すると動的にページも変わる機能）が機能していない。

### 状況

オプションをつけずに `npm run serve` が実行される事により、VMのIPを自動的に取得してNetworkのIPが`10.0.2.15` になってしまっていた。しかし、実際にホスト側からVMにアクセスする際のIPはVagrantfileの設定により `192.168.56.12` となっている

### 解消方法

以下のようにtasks.jsonを設定し、npmコマンドに引数を渡してタスクを実行した。

``` json
{
    "version": "2.0.0",
    "tasks": [
        {
            "command": "npm",
            "args": ["run", "serve", "--", "--host", "192.168.56.12"],
            "label": "npm run serve"
        },
    ]
}
```


# リンク

* [Visual Studio CodeではじめるTypeScript入門](https://www.casleyconsulting.co.jp/blog/engineer/255/)
* [Visual Studio CodeでTypeScript開発のノウハウ (ブラウザ編)](https://qiita.com/takao_mofumofu/items/4f8d365846e2f770bd6e)