[Symbol]TypeScriptの環境を雑に構築してプライベートテストネットに繋いでみる

前回、前々回とSymbolSDKを使うべく
ローカル環境にプライベートテストネットを作成し、その後Symbolテスト通貨の取得をしてみたのですが、
開発するにはTypeScriptが動いて、テストネットのアカウントに接続できないと話になりません。

本来はプライベートテストネットとTypeScriptの開発環境を別に分けて
DockerComposeのシェアネットで接続するべきだとおもうのですが、今回は雑にテストネットが乗っているDokcerComposeに相乗りさせてもらい、雑に接続を確認したいというものです。

そもそも、TypeScript触るのも初めてな上、Symbolのドキュメントにも環境構築の記載があまりなく、他に記事もなさそうなのでこれを皮切りにどなたかDokcerHubに作ってもらえると嬉しいです（丸投げかよっ！


# プライベートテストネットのdocker-composeの場所
まだプライベートテストネットを作ってない方は[こちらの記事](https://qiita.com/raharu0425/items/83f7e75f381049c2e7cc)をご覧ください

```
$ cd ~/work/symbol
$ ls -la
total 0
drwxr-xr-x   4 raharu  staff   128  9  7 09:46 .
drwxr-xr-x  36 raharu  staff  1152  9  3 13:14 ..
drwxr-xr-x  14 raharu  staff   448  9  3 13:14 catapult-service-bootstrap
```

ここの下にテストネット用のリポジトリフォルダがあるはずです。

```
$ cd catapult-service-bootstrap/cmds/bootstrap/
$ ls -la
total 96
drwxr-xr-x  15 raharu  staff   480  9  7 14:02 .
drwxr-xr-x  26 raharu  staff   832  9  3 13:14 ..
-rw-r--r--   1 raharu  staff  1181  9  3 13:14 api-db.yml
-rw-r--r--   1 raharu  staff  1168  9  3 13:14 catapult-api-broker.yml
-rw-r--r--   1 raharu  staff  2060  9  3 13:14 catapult-api-node.yml
-rw-r--r--   1 raharu  staff  1664  9  3 13:14 catapult-api.yml
-rw-r--r--   1 raharu  staff  1442  9  3 13:14 catapult-peers.yml
-rw-r--r--   1 raharu  staff  6046  9  3 13:14 dev-base.yml
-rw-r--r--   1 raharu  staff  1190  9  3 13:14 docker-compose-setup-network.yml
-rw-r--r--   1 raharu  staff  4616  9  7 14:01 docker-compose.yml
drwxr-xr-x   7 raharu  staff   224  9  3 13:14 dockerfiles
-rw-r--r--   1 raharu  staff   511  9  3 13:14 rest-dev.yml
-rw-r--r--   1 raharu  staff  3301  9  3 13:14 setup-network.yml
```

さらにcmds/bootstrap/の下に行くと見つかるdocker-compose.yml
これがテストネットをローカルに構築するための元のymlになります。
なのでこのdocker-compose.ymlにnginxとnodeを追記する形で作成してしまいます。

# docker-compose.ymlに追記

```yaml:docker-compose.yml

//下に追記
  app:
    build:
      context: ./
      dockerfile: ./nginx/Dockerfile
    ports:
      - "8080:80"
    volumes:
      - ./src/html:/app
    depends_on:
    - rest-gateway
    - setup-network

  node:
    image: node:12.18.3
    container_name: "node"
    tty: true
    working_dir: /usr/src/app
    volumes:
      - ./src:/usr/src/app
    depends_on:
    - rest-gateway
    - setup-network
```

Node.Jsは12.xを使います

# フォルダの作成
現在いるディレクトリにnginxとsrcを作成します

```
$ mkdit nginx
$ mkdir src 
$ mkdir -p src/html/js/ts
$ mkdir -p src/html/js/dist
```

# 初期化
```
$ docker-compose run --rm node npm init
```

そうすると、src/package.jsonが作成されているはずです一旦それはおいておきます

#ライブラリの追加

```
$ docker-compose run --rm node npm install -D typescript @types/node
$ docker-compose run --rm node npm install -D ts-node ts-node-dev rimraf npm-run-all
$ docker-compose run --rm node npm install --save-dev webpack webpack-cli ts-loader
$ docker-compose run --rm node npm install symbol-sdk rxjs
```

もろもろはいりました。


# webpack.config.jsの作成

symbol/catapult-service-bootstrap/cmds/bootstrap/src/の下に
webpack.config.js作成します

```js:webpack.config.js
const path = require('path');

module.exports = {
// モード値を production に設定すると最適化された状態で、
// development に設定するとソースマップ有効でJSファイルが出力される
mode: 'development', // "production" | "development" | "none"

// メインとなるJavaScriptファイル（エントリーポイント）
entry: './html/js/ts/index.ts',

output: {
    path: path.join(__dirname, "html/js/dist"),
    filename: "index.js"
},

module: {
    rules: [{
    // 拡張子 .ts の場合
    test: /\.ts$/,
    // TypeScript をコンパイルする
    use: 'ts-loader'
    }]
},
// import 文で .ts ファイルを解決するため
resolve: {
    modules: [
    "node_modules", // node_modules 内も対象とする
    ],
    extensions: [
    '.ts',
    '.js' // node_modulesのライブラリ読み込みに必要
    ]
}
};

```

# package.jsonの修正
symbol/catapult-service-bootstrap/cmds/bootstrap/src/package.json

を修正します

```json:package.json
~skip
  "scripts": {
    "tsc": "tsc",                          // 追加
    "build": "webpack --mode=development"  // 追加
  },
~skip
```

# TypeScriptの初期化

```
$ docker-compose run --rm node npx tsc --init
```

# tsconfig.jsonの修正

作成された、symbol/catapult-service-bootstrap/cmds/bootstrap/src/tsconfig.jsonを修正します

```json:tsconfig.json
{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
     "sourceMap": true,
     "outDir": "./html/js/dist",
    "strict": true,
    "typeRoots": [
        "node_modules/@types"
    ],
    /* Experimental Options */
    "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
    "strictPropertyInitialization": false,

    /* Advanced Options */
    "skipLibCheck": true,                     /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
  },
  "include": [
    "html/js/ts/**/*"
  ],
  "exclude": [
    "node_modules"
  ]
```

ここは[github](https://github.com/nemtech/symbol-docs/blob/main/source/resources/examples/typescript/tsconfig.json) を参考にしています

# サンプルコード

symbol/catapult-service-bootstrap/cmds/bootstrap/src/html/js/ts/にindex.tsを作成

```typescript:index.ts
import {Address, RepositoryFactoryHttp} from 'symbol-sdk';
// アドレスは自分用に変更してください
const rawAddress = 'TDKVJI-IPTWYD-N7FONG-FWM2BF-AYJGBA-ILYDJU-M2I';
const address = Address.createFromRawAddress(rawAddress);
// replace with node endpoint
const nodeUrl = 'http://localhost:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const accountHttp = repositoryFactory.createAccountRepository();

accountHttp
    .getAccountInfo(address)
    .subscribe((accountInfo) => console.log(accountInfo),
        (err) => console.error(err));
```

symbol/catapult-service-bootstrap/cmds/bootstrap/src/html/にindex.htmlを作成

```html:index.html
<!DOCTYPE html>
<html lang='ja'>
  <head>
    <meta charset="utf-8">
    <title>Hello typescript</title>
  </head>
  <body>
    <div id="output"></div>
    <script src="./js/dist/index.js"></script>
  </body>
</html>
```

# コンパイル

```
$ docker-compose run --rm node npm run build
Starting bootstrap_db_1 ... done
Starting bootstrap_setup-network_1 ... done
Starting bootstrap_init-db_1       ... done
Starting bootstrap_rest-gateway_1  ... done

> app@1.0.0 build /usr/src/app
> webpack --mode=development

Hash: 19d75630d595642fcee4
Version: webpack 4.44.1
Time: 40011ms
Built at: 09/07/2020 6:01:25 AM
   Asset     Size  Chunks             Chunk Names
index.js  5.3 MiB    main  [emitted]  main
Entrypoint main = index.js
 [0] crypto (ignored) 15 bytes {main} [built]
 [1] util (ignored) 15 bytes {main} [built]
 [2] util (ignored) 15 bytes {main} [built]
 [5] buffer (ignored) 15 bytes {main} [optional] [built]
 [6] buffer (ignored) 15 bytes {main} [optional] [built]
 [7] crypto (ignored) 15 bytes {main} [optional] [built]
 [8] buffer (ignored) 15 bytes {main} [optional] [built]
 [9] buffer (ignored) 15 bytes {main} [optional] [built]
[10] buffer (ignored) 15 bytes {main} [optional] [built]
[12] buffer (ignored) 15 bytes {main} [optional] [built]
[13] buffer (ignored) 15 bytes {main} [optional] [built]
 [./html/js/ts/index.ts] 767 bytes {main} [built]
 [./node_modules/webpack/buildin/amd-options.js] (webpack)/buildin/amd-options.js 80 bytes {main} [built]
 [./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
 [./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {main} [built]
    + 1068 hidden modules
```

sousurutosymbol/catapult-service-bootstrap/cmds/bootstrap/src/html/js/dist/に
index.jsが生成されると思います

# 起動

```
$ docker-compose up -d
```

# 確認する

http://localhost:8080/index.html

コンソール上に対象のアドレスの情報がテストネットから返却されていれば成功です。

![200907-0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42874/07383914-3d1e-3344-8bb5-0d01b336aa40.png)

# 所感
もともとは別docker-composeで作成してテストネットに繋ぐ予定だったのですが、
それがうまく行ってなくて雑な構築になりましが、接続が成功した際のレスポンスを確認できました。

今回は本当い接続確認という体になってしまったのでもう少しTypeScritと仲良くなったら再度試してみたい所存です

# 参考記事
https://qiita.com/reflet/items/538753d5dcf3560567a9
https://qiita.com/EBIHARA_kenji/items/31b7c1c62426bdabd263#webpack-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
https://github.com/nemtech/symbol-docs/tree/main/source/resources/examples/typescript