Nuxt.js + TypeScript + GraphQL(apollo)の導入

## 前提
- prisma等でGraphQLサーバが立ち上がっていること
- Nuxt.jsアプリのセットアップも完了していること

## 事前準備
- 必要なライブラリのインストール

```bash
yarn add @nuxt/typescript-build
yarn add vue-property-decorator
yarn add @nuxtjs/apollo
```

- apolloクライアントの設定

```js:nuxt.config.js
  modules: [
    '@nuxtjs/apollo'
  ],
  apollo: {
    clientConfigs: {
      default: '~/plugins/apollo-auth.js'
    }
  },
```

```js:plugins/apollo-auth.js
export default function (context) {
  return {
    httpEndpoint: '--- GraphQLサーバのエンドポイントURL ---'
  }
}
```

## 実装
### クエリ定義

```graphql:apollo/queries/getUsers.gql
query GetUsers {
    users {
        id
        name
        description
    }
}
```

### 呼び出し

```html:pages/index.vue
<template>
  <div>
    <h3>Users</h3>
    <ul>
      <li v-for="user in users" :key="user.id">
        <nuxt-link :to="`user/${user.id}`">
          {{ user.name }} : {{ user.description }}
        </nuxt-link>
      </li>
    </ul>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import getUsersGql from '~/apollo/queries/getUsers.gql';

@Component({})
export default class IndexPage extends Vue {
    users: {
            id: number;
            name: string;
            description: string;
    }[];

    get apollo () {
        return {
            users: {
                query: getUsersGql,
                prefetch: true
            }
        }
    }
}
</script>
```
※ TypeScriptでapolloを呼び出す場合は、算出プロパティのように「getter付きのメソッド」で呼び出す必要がある

<details><summary>ちなみに、JavaScriptで同じこと書くとこのようになる (クリック)</summary><div>

```html
<script>
import getUsersGql from '~/apollo/queries/getUsers.gql'

export default {
  data() {
    return {
      users: []
    }
  },

  apollo: {
    users: {
      query: getUsersGql
    }
  }
}
</script>
```
</div></details>

## IntelliJ(WebStorm、PhpStorm等)がCannot find moduleエラーを吐く場合

ビルド時に上記のようなエラーを吐く場合

```
ERROR  Failed to compile with 1 errors                                                                                                                                friendly-errors 19:02:49

This dependency was not found:                                                                                                                                         friendly-errors 19:02:49
                                                                                                                                                                       friendly-errors 19:02:49
* ~/apollo/queries/getUsers.gql in ./node_modules/babel-loader/lib??ref--12-0!./node_modules/ts-loader??ref--12-1!./node_modules/vue-loader/lib??vue-loader-options!./pages/area.vue?vue&type=script&lang=ts& 
```

### 対処法
```
yarn add graphql
```

```ts:shims-gql.d.ts
declare module '*.gql' {
  import Graphql from 'graphql'
  export default Graphql
}
```

```diff:tsconfig.json
+  "files": [
+    "shims-gql.d.ts"
+  ],
+  "include": [
+    "apollo/queries/*.gql",
+    "apollo/queries/**/*.gql"
+  ],
```


## 参考サイト
- [Vue.js to TypeScriptの書き方一覧 - Qiita](https://qiita.com/ryo2132/items/4d43209ea89ad1297426)
- [OniVe/vue-apollo-typescript-example: A simple vue-apollo typescript example app](https://github.com/OniVe/vue-apollo-typescript-example)
- [Nuxt 2.8の生成するtsconfig.jsonを使うとIntelliJ(WebStorm、PhpStorm等)がCannot find moduleエラーを吐く - Qiita](https://qiita.com/ryo511/items/0408d3763af797a16a7a)