TypeScript 実行環境（CLI環境）をWindowsのUbuntuに作る方法

# 内容
自分がTypeScriptの実行環境（CLI環境）を作成した時の手順をまとめてみました。
自分の環境情報は下記の通り

```bash
user@pc:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.7 LTS
Release:        16.04
Codename:       xenial
```

# nvm のインストール
nvmとは「Node.js」のバージョン管理ツールで数多あるNode.jsの中から使用するバージョンを選択し気軽に使用できる状態にすることができるものです。コマンドは下記の通り

```bash
user@pc:~$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
```

**※[nvmのgitページ](https://github.com/nvm-sh/nvm)の[installing-and-updating](https://github.com/nvm-sh/nvm#installing-and-updating)を参照して最新のものを使用するようにしましょう。**

インストールが完了するとホームディレクトリにある ~/.bashrc の末尾に以下が追記される。

```
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion        
```

上記が確認できたらこれを有効化するため下記コマンドで ~/.bashrc を再度読み込む。
読み込んだあと nvm のバージョンを確認して正しく出るかどうかを見る。出ればインストール完了

```bash
user@pc:~$ source ~/.bashrc
user@pc:~$ nvm --version
0.37.2
```

## 注意点

- nvm本体は `~/.nvm` ディレクトリ配下に存在するため、当該ユーザ以外でログインした場合は使用できない。
- `$ source ~/.bashrc` はインストール直後でのみ実施すれば良い。次回以降当該ユーザでUbuntuにログインするたびに勝手に読み込まれる。


# Node.js のインストール

nvm コマンドを使って指定バージョンのNode.jsをインストールします。
まずはインストール可能なバージョン一覧を `mvn ls-remote` にて参照します。

```bash
user@pc:~$ nvm ls-remote
        v0.1.14
        v0.1.15
        v0.1.16
        ：
        ：
        ：
```

このような感じでインストールできるバージョンがリストとして表示されるのでインストールしたい物を選び `mvn install` コマンドを実行してインストールする。

```bash
user@pc:~$ nvm install v14.15.1
Downloading and installing node v14.15.1...
Local cache found: ${NVM_DIR}/.cache/bin/node-v14.15.1-linux-x64/node-v14.15.1-linux-x64.tar.xz
Checksums match! Using existing downloaded archive ${NVM_DIR}/.cache/bin/node-v14.15.1-linux-x64/node-v14.15.1-linux-x64.tar.xz
Now using node v14.15.1 (npm v6.14.8)
```

※上記は `v14.15.1` をインストールとした時に出力された内容

実際に使用したい Node.js のバージョンを指定するために `nvm use` を使って設定します。

```bash
user@pc:~$ nvm use v14.15.1
Now using node v14.15.1 (npm v6.14.8)
user@pc:~$ node -v
v14.15.1
```

`nvm ls` は現在インストール済みの Node.js のバージョン情報と現在使用設定されている内容を出力します。

```bash
user@pc:~$ nvm ls
d_takahashi@PC-D-TAKAHASHI4:~/.nvm/versions/node$ nvm ls
       v12.20.0
->     v14.15.1
default -> v12.20.0
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v14.15.1) (default)
stable -> 14.15 (-> v14.15.1) (default)
lts/* -> lts/fermium (-> v14.15.1)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.23.0 (-> N/A)
lts/erbium -> v12.20.0
lts/fermium -> v14.15.1
```

## 注意点

- Node.js本体は `~/.nvm/version/node` ディレクトリ配下に存在するため、当該ユーザ以外でログインした場合は使用できない。


# tsc, ts-node をインストールする

## tsc 
TypeScriptで記載されたコードをJavascriptコードに変換するコマンド。
[トランスコンパイラ](https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B9%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9)と呼ばれているものでTypeScriptで書かれたコードを tsc コマンドに食わせるとJavascriptで出力、保存してくれる。

## ts-node 
TypeScriptで記載されたコードを直接実行して結果を参照できるコマンド。 tsc とは違いJavascriptのコードが生成されない。

今回は両方とも「ローカルインストール」の方法を記載します

```bash
user@pc:~$ mkdir ~/tmp/typescript/
user@pc:~$ cd ~/tmp/typescript/
user@pc:~$ npm install --save-dev typescript ts-node
user@pc:~$ ls -lF
node_modules/
package-lock.json
```

ローカルインストールなのでインストールコマンドを実行した場所に `node_modules` `package-lock.json` が追加されます。
※すでに存在した場合は当該ファイル、ディレクトリ内に上書きされるイメージ
※グローバルインストールは `$ npm install -g typescript ts-node` という形になる


# tsc, ts-node を使ってみる

上記でインストールした場所にて使ってみます。
まずは定番「HelloWorld.ts」というファイルを作ります。内容は下記のような感じ

```file
// helloworld.ts
const hello = (text: string) => {
    console.log(`Hello ${text} !`);
}

hello('World');
```

設置場所はこんな感じ。

```bash
user@pc:~$ cd ~/tmp/typescript/
user@pc:~$ ls -lF
helloworld.ts
node_modules/
package-lock.json
```

まずは tsc を使ってみます。
ローカルインストールなので tsc は　`./node_modules/.bin/tsc` と記載して呼び出します。
実行すると自動的に `helloworld.js` を生成します。これがJavascriptに「トランスコンパイル」されたファイルとなります。
生成されたjsファイルと、元のtsファイルをそれぞれ node で実行してみるとjsファイルは正しく実行され、tsファイルはエラーとなって実行できない感じになります。

```bash
/* tscコマンド実行 */
user@pc:~$ ./node_modules/.bin/tsc helloworld.ts

/* helloworld.jsが生成されている */
user@pc:~$ ls -1F
helloworld.js
helloworld.ts
node_modules/

/* helloworld.jsをnodeで実行 --> 成功 */
user@pc:~$ node helloworld.js

Hello World !

/* helloworld.tsをnodeで実行 --> エラーになる*/
user@pc:~$ node helloworld.ts
/xxxx/yyyy/tmp/typescript/helloworld.ts:2
const hello = (text: string) => {
                   ^

SyntaxError: Unexpected token ':'
　　：
　　：
```

次は ts-node を使ってみます。
ローカルインストールなので ts-nodeは　`./node_modules/.bin/ts-node` と記載して呼び出します。
tsc では一度jsファイルにしないと動作チェックができないが ts-nodeであればTypeScriptを直接実行して動作確認をすることができます。

```bash
/* tscコマンド実行 */
user@pc:~$ ./node_modules/.bin/ts-node helloworld.ts
Hello World !
```


# 完成

TypeScriptを試すベース環境がこれでできました。あとはトライ＆エラーで学習あるのみ。がんばります…


# 補足

ここまでの手順にて「TypeScript環境を作る」に直接関係はないが、躓いた点がいくつかありますので紹介＆対処方法をメモっておきます。

## WindowsのUbuntuにて `root` になれない。

この場では記載していませんが、これらインストール作業をする前 `# apt update` 等のrootで実行するべきコマンドを実行しインストール済みのパッケージの更新を実施したのですが、そもそも root になれなくてハマった。
下記コマンドを実行することで root ユーザでUbuntuに入ることができる。
rootでは入れてしまえばそこからパスワード変更するなり、そのまま必要なコマンドを叩いていくなりが実施できる

```powershell
/* PowerShellで実行*/
PS C:\Users\xxx> wsl -u root

/* rootでログインしている状態になる */
root@pc:/mnt/c/Users/xxx# 
```

## インターネット経由でのファイル更新ができない

`# apt update` や上記の「nvm のインストール」で使っている `curl` がローカルPCから外に通信が出ていかずエラーになってしまう事態になる。これは `/etc/resolv.conf` の中に記載されている `nameserver` の値を `8.8.8.8` にすると解消できる。ただここの値はターミナルに入り直す等をするともとに戻るみたいで、自分は何回か修正することで対応した。
※Googleさんに聞くと永続的に変更することも可能みたいだが、自分は実施しなかった。
※ここでもrootのパスワードが…

```bash
user@pc:~$ sudo vi /etc/resolv.conf 

/* nameserverを 8.8.8.8 に修正して保存する */
nameserver 8.8.8.8
```