はじめてのServerless ✕ Webpack ✕ TypeScript

<img src="https://qiita-image-store.s3.amazonaws.com/0/8292/ef5f6cbc-0702-1c98-580f-786429f835e5.gif">
このエントリーは[aratana Advent Calendar 2017](https://qiita.com/advent-calendar/2017/aratana)12日目のエントリーです。

こんばんは！最近[Google Home Mini](https://store.google.com/product/google_home_mini?hl=ja)と[Amazon echo dot](https://www.amazon.co.jp/Amazon-Echo-Dot-New%E3%83%A2%E3%83%87%E3%83%AB-%E3%80%81%E3%83%96%E3%83%A9%E3%83%83%E3%82%AF/dp/B072B5BTLK)を購入したはいいが置き場所に困っている蔭山です。
みなさんはどのような場所に置かれているのでしょうか。。。

前日は~~新卒エンジニアには決して見えない~~安定感をお持ちの猿渡くんの[「NoSQLについて何か。」](http://sarup.hateblo.jp/entry/2017/12/11/000000)という記事でした！
*NoSQL？あぁ、聞いたことはある。*
みたいな僕でもわかりやすい記事でした！
最近AWSに興味が出始めたところでしたので、ぜひDynamoDBを使って軽い画像投稿サービスでも作ってみます！


さて今回はServerless ✕ Webpack ✕ TypeScriptの組み合わせで使えるように手順をまとめてみたいと思います！

##動作環境
今回の動作環境は以下になります！

```shell-session
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.12.6
BuildVersion:	16G1114

$ node -v
v8.2.1

$ serverless -v
1.24.0

$ webpack -v
3.5.6
```
##環境準備
nodeやserverlessのインストールについては下記記事を参考に。。。

- [Macにnode.jsをインストールする手順。](https://qiita.com/akakuro43/items/600e7e4695588ab2958d)
- [Serverless Frameworkのインストールと初期設定](https://qiita.com/keita-nishimoto/items/879bb8c075db802906df)

##とりあえずやってみる
まずはServerlessのプロジェクトを作ってみましょう

```shell-session
$ serverless create -t aws-nodejs -p hogehoge
Serverless: Generating boilerplate...
Serverless: Generating boilerplate in "/Users/fugafuga/hogehoge"
 _______                             __
|   _   .-----.----.--.--.-----.----|  .-----.-----.-----.
|   |___|  -__|   _|  |  |  -__|   _|  |  -__|__ --|__ --|
|____   |_____|__|  \___/|_____|__| |__|_____|_____|_____|
|   |   |             The Serverless Application Framework
|       |                           serverless.com, v1.24.0
 -------'

Serverless: Successfully generated boilerplate for template: "aws-nodejs"
$ cd ./hogehoge
```
JSer御用達npmを使って必要なパッケージをダウンロードしましょう。

```shell-session
$ npm init
$ npm install --save-dev serverless-webpack serverless-offline ts-loader typescript webpack
```
インストールが終わり次第、各種設定を行います。
今回はTypescript -> ES2015へのコンパイルを目的に設定させていただきます。
細かい設定内容に関しては割愛します。

```yaml:./serverless.yml
service: hogehoge

provider:
  name: aws
  runtime: nodejs6.10
  stage: dev
  region: ap-northeast-1

plugins:
- serverless-webpack
- serverless-offline

functions:
  hello:
    handler: handler.hello
    events:
     - http:
         path: hello
         method: get
```

```javascript:./webpack.config.js
module.exports = {
  entry: './handler.ts',
  target: 'node',
  module: {
    loaders: [{
      test: /\.ts$/,
      loader: 'ts-loader'
    }]
  },
  resolve: {
    extensions: ['.ts']
  },
  output: {
    libraryTarget: 'commonjs',
    path: __dirname + '/.webpack',
    filename: 'handler.js'
  }
};
```

```json:./tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs"
  },
  "exclude": [
    "node_modules"
  ]
}
```

準備はできたので、次はTypeScriptでコーディングしてみましょう!

```typescript:./handler.ts
export * from './src/ts/functions/hello';
```

```typescript:./src/ts/functions/hello.ts
export function hello(event, context, callback): void {
  const response = {
    statusCode: 200,

    headers: {
    },

    body: JSON.stringify({
      "message": "Hello Serverless x Webpack x TypeScript!!"
    })
  };

  callback(null, response);
};
```
コードが書けたらローカル環境で動作確認

``` shell-session
$ sls offline
・・・・・・・・・・・・・・・・
途中は割愛。m(__)m
・・・・・・・・・・・・・・・・
Serverless: Routes for hello:
Serverless: GET /hello

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

きちんと動作するか確認。

```shell-session
$ curl -X GET http://localhost:3000/hello
{"message":"Hello Serverless x Webpack x TypeScript!!"}
```

動作が問題なければ、早速デプロイしてみましょう！

```shell-session
$ sls deploy
・・・・・・・・・・・・・・・・
途中は割愛。m(__)m
・・・・・・・・・・・・・・・・
api keys:
  None
endpoints:
  GET - https://hogehoge.execute-api.ap-northeast-1.amazonaws.com/dev/hello
functions:
  hello: hogehoge-dev-hello
```

デプロイが完了したようです。
では早速動作確認。

```shell-session
$ curl -X GET https://hogehoge.execute-api.ap-northeast-1.amazonaws.com/dev/hello
{"message":"Hello Serverless x Webpack x TypeScript!!"}
```

ちゃんと動きましたね！

##最後に
無理やりTypeScriptを使った感が凄まじいですね。。。申し訳ありません＞＜
~~僕個人がTypeScriptを使ったことがなかったため使ってみたかったんです~~

明日は新卒田村くんの「Ctagsで自由な翼を得たVimについて」です！
お楽しみに！

##参考
主にこちらの記事を参考にさせて頂きました！ありがとうございますm(__)m

- [Serverless + Webpack + TypeScript + tslint メモ](https://qiita.com/y13i/items/3ab22f8f8f1c41c5402f)