TypeScriptでLambdaを書く準備

# やりたかったこと
AWSのLambdaの話を聞いて、Serverlessに興味を持ってもう3年（もっと？）経った。
その頃から触ってみたいなーと思いつつ、なかなかちゃんと触る機会なかったので触ってみました❗

# なぜTypeScript？
もともとJavaを触ってきて今はKotlinなのですが・・・
どちらも**Lambda**で書くにはあんまり向かないんですよね(；´∀｀)

巷ではnodeやPythonあたりが主流なのかな？
re:InventでRubyも追加されたからこっちも少し増えてくるかなと。

ただ、僕自身PythonもRubyもあまり触ったこと無く、自分のリソース的には**TypeScript**かなと。
というわけでTypeScriptで書いてみようと思いました！

AWS-CLIは入ってるものとして、credentialsも設定済みとします。

# yarnを入れてみた
最近は**npm**ではなく、**yarn**の記事をちょくちょく見るので今回はこっちを入れてみた。
MacなのでhomebrewでInstall

```terminal
brew install yarn
```

インストール先は/usr/local/Cellar/yarn/1.15.2/bin/yarnでした。
とりあえずはsampleプロジェクトのディレクトリ切って、その中でyarnの初期化

```terminal
$ mkdir serverless-typescript-sample
$ cd serverless-typescript-sample
$ yarn init
yarn init v1.15.2
question name (serverless-typescript-sample): 
question version (1.0.0): 
question description: 
question entry point (index.js): 
question repository url: 
question author: 
question license (MIT): 
question private: 
success Saved package.json
✨  Done in 13.12s.
```

package.jsonが出来上がります。

```package.json
{
  "name": "serverless-typescript-sample",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT"
}
```

# 環境構築
|パッケージ  |バージョン |
|---|---|
|yarn  |v1.15.2|
|nodejs|v11.12.0|
|typescript|v3.2.4|
|Serverless |v1.40.0|
|serverless-offline|v4.9.3|

## Git
Gitの初期化とリモートリポジトリ追加。
リモートリポジトリはGithubなので、その他の場合は適宜変更で。

```terminal
git init
git remote add origin git@github.com:*************************************.git
```
## Serverless Freamwork
今回はグローバル領域にインストールしないで、**node_module**内にしておきます。
先程入れた**yarn**でインストール。

```terminal
yarn add serverless
yarn add v1.15.2
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
success Saved 281 new dependencies.
info Direct dependencies
└─ serverless@1.40.0
info All dependencies
~~~~
✨  Done in 6.61s.
```

インストールが終わったらプロジェクトも作ってしまいます。

**aws-nodejs-typescriptの場合はpackage.jsonに変更が加わるので、すでにあるとエラーになります。
とりあえずひとつ下の階層にパス指定して同じ名前のディレクトリつくります。**


```terminal
yarn sls create -t aws-nodejs-typescript -p serverless-typescript-sample
```

こんな感じになるので、serverless-typescript-sampleディレクトリの中身を全部上のディレクトリに移動します。
**package.jsonだけは丸コピするとserverlessが消えちゃうので手動でやります。**

移動前ディレクトリ構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/0548e9a9-d53f-e877-7c4c-050b6cab2853.png)

移動後ディレクトリ構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33165/34af7ca3-d852-95b6-89fe-b0f82f4cf327.png)


手動で直した後のpackage.json

```package.json
{
  "name": "serverless-typescript-sample",
  "version": "1.0.0",
  "description": "Serverless webpack example using Typescript",
  "main": "handler.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    "serverless": "^1.40.0",
    "source-map-support": "^0.5.10"
  },
  "devDependencies": {
    "@types/aws-lambda": "^8.10.17",
    "@types/node": "^10.12.18",
    "serverless-webpack": "^5.2.0",
    "ts-loader": "^5.3.3",
    "typescript": "^3.2.4",
    "webpack": "^4.29.0"
  },
  "author": "The serverless webpack authors (https://github.com/elastic-coders/serverless-webpack)",
  "license": "MIT"
}
```

**package.json**を変更したので、`yarn install`で依存関係の更新します。

# ローカル開発環境の構築
## serverless-offline
ローカルでLambdaを実行できるようにするために、`serverless-offline`をyarnでインストールします。

```terminal
$ yarn add -D serverless-offline
yarn add v1.15.2
[1/4] 🔍  Resolving packages...
warning serverless-offline > h2o2 > joi@10.6.0: This version is no longer maintained. Please upgrade to the latest version.
warning serverless-offline > hapi > catbox > joi@10.6.0: This version is no longer maintained. Please upgrade to the latest version.
warning serverless-offline > hapi > heavy > joi@10.6.0: This version is no longer maintained. Please upgrade to the latest version.
warning serverless-offline > hapi > podium > joi@10.6.0: This version is no longer maintained. Please upgrade to the latest version.
warning serverless-offline > hapi > shot > joi@10.6.0: This version is no longer maintained. Please upgrade to the latest version.
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
success Saved 37 new dependencies.
```

インストールしたら`serverless.yml`のpluginに以下の追記

```serverless.yml
plugins:
  - serverless-offline
```

追記出来たら`yarn sls offline start`でローカルサーバーの起動をします。

```terminal
yarn sls offline start
yarn run v1.15.2
$ /Users/hisayuki/vscode/serverless-typescript-sample/node_modules/.bin/sls offline start
Serverless: Bundling with Webpack...
Time: 1348ms
Built at: 2019/03/30 22:01:55
         Asset     Size   Chunks             Chunk Names
    handler.js  129 KiB  handler  [emitted]  handler
handler.js.map  146 KiB  handler  [emitted]  handler
Entrypoint handler = handler.js handler.js.map
[./handler.ts] 307 bytes {handler} [built]
[./node_modules/buffer-from/index.js] 1.56 KiB {handler} [built]
[./node_modules/source-map-support/register.js] 25 bytes {handler} [built]
[./node_modules/source-map-support/source-map-support.js] 17.6 KiB {handler} [built]
[./node_modules/source-map/lib/array-set.js] 3.12 KiB {handler} [built]
[./node_modules/source-map/lib/base64-vlq.js] 4.6 KiB {handler} [built]
[./node_modules/source-map/lib/binary-search.js] 4.15 KiB {handler} [built]
[./node_modules/source-map/lib/mapping-list.js] 2.28 KiB {handler} [built]
[./node_modules/source-map/lib/source-map-consumer.js] 39.6 KiB {handler} [built]
[./node_modules/source-map/lib/source-map-generator.js] 14 KiB {handler} [built]
[./node_modules/source-map/lib/source-node.js] 13.5 KiB {handler} [built]
[./node_modules/source-map/source-map.js] 405 bytes {handler} [built]
[fs] external "fs" 42 bytes {handler} [optional] [built]
[module] external "module" 42 bytes {handler} [optional] [built]
[path] external "path" 42 bytes {handler} [built]
    + 3 hidden modules
Serverless: Watching for changes...
Serverless: Starting Offline: dev/us-east-1.

Serverless: Routes for hello:
Serverless: GET /hello

Serverless: Offline listening on http://localhost:3000
```

これでcurlや直接ブラウザでLambdaを実行することが出来ます！

```
$ curl http://localhost:3000/hello
{"message":"Go Serverless Webpack (Typescript) v1.0! Your function executed successfully!",....
```

# まとめ
テンプレートの**aws-nodejs-typescript**が**package.json**があることでうまくいかないところについては面倒なのですが、**グローバル領域にserverlessをインストールすれば特に問題ないです。**
今回はプロジェクト内で収めておきたいというこだわりがあったので手間をかけました。

その点以外については、割とスムーズに環境構築ができたので難しくはないと思います。
ローカル実行環境やテスト環境なども以前やったときより簡単になったきがしますね。