Vue CLI 3でAWS Amplify + TypeScriptでビルド時のエラー解消

# 概要

- Vue CLI 3でプロジェクト作成時のオプション指定で、TypeScriptを組み込みました
- このVueプロジェクトに、AWS Amplifyを組み込み、ビルドを実行したところエラーになりました
- エラーの再現手順と解消方法を記述します

# 注意

2019年1月27日時点で確認しているものです。

この時点のaws-apmlifyのバージョンは、"1.1.19"です。

バージョンアップに伴い、修正されているかもしれないので、ご注意ください。

# 検証環境

## ツールバージョン

    $node -v
    v8.15.0
    
    $npm -v
    6.4.1
    
    $yarn -v
    1.13.0

## モジュールバージョン

    "dependencies": {
      "@types/graphql": "^14.0.5",
      "@vue/cli-service-global": "^3.3.0",
      "aws-amplify": "^1.1.19",
      "aws-amplify-vue": "^0.2.5",
      "pug": "^2.0.3",
      "pug-plain-loader": "^1.0.0",
      "register-service-worker": "^1.5.2",
      "vue": "^2.5.21",
      "vue-class-component": "^6.0.0",
      "vue-property-decorator": "^7.0.0",
      "vue-router": "^3.0.1",
      "vuex": "^3.0.1"
    },
    "devDependencies": {
      "@types/jest": "^23.1.4",
      "@vue/cli-plugin-babel": "^3.3.0",
      "@vue/cli-plugin-e2e-nightwatch": "^3.3.0",
      "@vue/cli-plugin-eslint": "^3.3.0",
      "@vue/cli-plugin-pwa": "^3.3.0",
      "@vue/cli-plugin-typescript": "^3.3.0",
      "@vue/cli-plugin-unit-jest": "^3.3.0",
      "@vue/cli-service": "^3.3.0",
      "@vue/eslint-config-prettier": "^4.0.1",
      "@vue/eslint-config-typescript": "^3.2.0",
      "@vue/test-utils": "^1.0.0-beta.20",
      "babel-core": "7.0.0-bridge.0",
      "babel-eslint": "^10.0.1",
      "eslint": "^5.8.0",
      "eslint-plugin-vue": "^5.0.0",
      "lint-staged": "^8.1.0",
      "stylus": "^0.54.5",
      "stylus-loader": "^3.0.2",
      "ts-jest": "^23.0.0",
      "typescript": "~3.1.1",
      "vue-template-compiler": "^2.5.21"
    },

# 再現手順

## Vue CLIでプロジェクト作成

    vue create ts-project

presetは以下にしています。（全部入り）

    {
      "useConfigFiles": true,
      "plugins": {
        "@vue/cli-plugin-babel": {},
        "@vue/cli-plugin-typescript": {
          "classComponent": true,
          "useTsWithBabel": true
        },
        "@vue/cli-plugin-pwa": {},
        "@vue/cli-plugin-eslint": {
          "config": "prettier",
          "lintOn": [
            "save",
            "commit"
          ]
        },
        "@vue/cli-plugin-unit-jest": {},
        "@vue/cli-plugin-e2e-nightwatch": {}
      },
      "router": true,
      "routerHistoryMode": true,
      "vuex": true,
      "cssPreprocessor": "stylus"
    }

## AWS Amplifyインストール

    cd ts-project
    yarn add aws-amplify aws-amplify-vue

## AWSa Amplifyでバックエンドの構築

vue側のmain.tsで、Amplifyクライアントの初期化(configure)が必要ですが、この際 aws-exports.js
 を読み込む必要があります。

aws-exports.jsは、amplify-cliでバックエンド環境を初期化(amplify init)し、環境を構築(amplify push)する際に生成されます。

エラー再現のため、最小限のバックエンド構築を行います。

amplify-cliのインストールやconfigureは予め必要となります。

今回はエラーの再現手順なので、amplify によるバックエンド構築の詳細は割愛します。

まず、バックエンド初期化を行います。

    amplify init

対話型で以下のような内容を設定しました。

この時点で、プロジェクトのルートに、amplifyディレクトリが作成されます。

    ? Choose your default editor: IDEA 14 CE
    ? Choose the type of app that you're building javascript
    Please tell us about your project
    ? What javascript framework are you using vue
    ? Source Directory Path:  src
    ? Distribution Directory Path: dist
    ? Build Command:  npm run-script build
    ? Start Command: npm run-script serve
    Using default provider awscloudformation

次に、バックエンド環境をAWS上に構築します。

この時点で、aws-exports.jsが生成されます。

    amplify push

aws-exports.js

    // WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.
    
    const awsmobile = {
        "aws_project_region": "ap-northeast-1"
    };
    
    
    export default awsmobile;

## main.tsへamplify configの記述
生成されたaws-exports.jsonを読み込んで、amplifyクライアントの設定を記述します。



```typescript:main.ts
import Amplify, * as AmplifyModules from 'aws-amplify'
// @ts-ignore
import { AmplifyPlugin } from 'aws-amplify-vue'
// @ts-ignore
import aws_exports from './aws-exports'
Amplify.configure(aws_exports)

Vue.use(AmplifyPlugin, AmplifyModules)
```

## tsconfig.jsonへ追記

Typescriptのコンパイルオプションのtypesに"node"を追加します。

この設定がないと、node_modules/aws-sdk内のコードに対して、大量にエラーが出力されます。

    {
      "compilerOptions": {
        ...snip
        "types": [
          "webpack-env",
          "jest",
          "node" <-追加
        ],
        ...snip

**疑問**

tsconfig.jsonには、excludeにnode_modulesが指定されているはずなのに、なぜnode_modules/aws-sdk配下のコードが除外されていないのは、なぜだろう。

    "exclude": [
      "node_modules"
    ]

## ビルドを実行

    yarn build

## エラー内容

2つのエラーが出力されます。

## エラーその１

    ERROR in /Users/yoshinori/WebstormProjects/amplify-twitter-auth/node_modules/@aws-amplify/api/lib/types/index.d.ts
    1:30 Could not find a declaration file for module 'graphql/language/ast'. '/Users/yoshinori/WebstormProjects/amplify-twitter-auth/node_modules/graphql/language/ast.js' implicitly has an 'any' type.
      Try `npm install @types/graphql` if it exists or add a new declaration (.d.ts) file containing `declare module 'graphql/language/ast';`
      > 1 | import { DocumentNode } from 'graphql/language/ast';
          |                              ^
        2 | /**
        3 | * RestClient instance options
        4 | */
    
     error  in /Users/yoshinori/WebstormProjects/amplify-twitter-auth/node_modules/aws-amplify/lib/index.d.ts

「モジュールが見つけられないから、@types/graphqlをインストールしろ」という内容です。

これは、指示の通りに@types/graphql モジュールを追加すると解消されました。

    yarn add @types/graphql

## エラーその２

    ERROR in /Users/yoshinori/WebstormProjects/amplify-twitter-auth/node_modules/aws-amplify/lib/index.d.ts
    8:16 Could not find a declaration file for module '@aws-amplify/ui'. '/Users/yoshinori/WebstormProjects/amplify-twitter-auth/node_modules/@aws-amplify/ui/dist/aws-amplify-ui.js' implicitly has an 'any' type.
      Try `npm install @types/aws-amplify__ui` if it exists or add a new declaration (.d.ts) file containing `declare module '@aws-amplify/ui';`
         6 | import Cache from '@aws-amplify/cache';
         7 | import Interactions, { InteractionsClass } from '@aws-amplify/interactions';
      >  8 | import UI from '@aws-amplify/ui';
           |                ^
         9 | import XR, { XRClass } from '@aws-amplify/xr';
        10 | import Amplify, { ConsoleLogger as Logger, Hub, JS, ClientDevice, Signer, I18n, ServiceWorker } from '@aws-amplify/core';
        11 | export default Amplify;
    
     ERROR  Build failed with errors.
    error Command failed with exit code 1.
    info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

こちらもモジュールが見つけられないというエラーですが、@types/aws-amplify__uiというモジュールが存在していませんでした。

    i$ yarn add @types/aws-amplify__ui
    yarn add v1.13.0
    [1/4] 🔍  Resolving packages...
    error An unexpected error occurred: "https://registry.yarnpkg.com/@types%2faws-amplify__ui: Not found".

## aws-amplifyのバージョンを調整する

色々模索したところ、aws-amplifyのバージョンを調整することで、エラーが解消しました。

package.json の "aws-amplify"のバージョンを"1.1.10"固定にします。（^も外します）

    "aws-amplify": "1.1.10", // ^1.1.19 -> 1.1.10

## ビルドを再度実行

モジュール更新とビルドを実行します。

    yarn && yarn build

エラーが解消されて、ビルド成功します。