NuxtにTypeScriptを導入する備忘録（2020年3月）

NuxtでTypeScriptを導入するにあたって、まず公式のドキュメントを頼りにしてみたものの上手くいかない事があるので、備忘録的に手順をまとめてみました。ゴールは「Nuxt環境でTypeScriptによるクラスベースの開発が出来るようになる事」です。


1. 公式の手順を踏んでTypeScriptを導入
2. jsconfig.json の作成・編集
3. Lint設定
4. vue-property-decorator の導入



## 事前準備 : Nuxtインストール

参考までに今回インストールしたNuxtはこんな構成です。

```bash
$ npx create-nuxt-app

create-nuxt-app v2.14.0
Generating Nuxt.js project in .
? Project name nuxt-ts-demo
? Project description My terrific Nuxt.js project
? Author name mach3
? Choose the package manager Npm
? Choose UI framework None
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules Axios
? Choose linting tools ESLint
? Choose test framework None
? Choose rendering mode Single Page App
? Choose development tools jsconfig.json (Recommended for VS Code)
```

- 最後の `jsconfig.json` はあとでまるっと書き換えてしまうので要らないといえば要らないです
- `Prettier` はとにかく消耗させてくるので入れていません（個人の感想です）


## 1. 公式の手順を踏んでTypeScriptを導入

公式ドキュメント : <https://typescript.nuxtjs.org/ja/guide/setup.html>

### `@nuxt/typescript-build` のインストール

```bash
$ npm i @nuxt/typescript-build -D
```

### `nuxt.config.js` の編集

```js:nuxt.config.js
  ...
  buildModules: [
    '@nuxtjs/eslint-module',
    '@nuxt/typescript-build' // <- 追加
  ],
  ...
```

### `tsconfig.json` の追加と編集

ファイルの中身は公式の物をコピー＆ペーストする。

```bash
$ touch tsconfig.json
```

## 2. jsconfig.json の作成・編集

`jsconfig.json` は VS Code 向けの設定ファイルです。したがって他のエディタを使用している場合はスキップしても良さそうです。

`jsconfig.json` はNuxtインストール時に選択肢を選べば自動生成してくれますが、内容を `tsconfig.json` に合わせてやる必要があります。構成は両者とも同じなので、単純にまるっと転記してしまいます。

```bash
$ cat tsconfig.json > jsconfig.json
```

書き換えられた jsconfig.json をエディタで開くと分かりますが、いくつか許可されていないプロパティがあるので、そこは削除します。( `allowJS` と `types` )

```diff:jsconfig.json
{
  "compilerOptions": {
    "target": "es2018",
    "module": "esnext",
    "moduleResolution": "node",
    "lib": [
      "esnext",
      "esnext.asynciterable",
      "dom"
    ],
    "esModuleInterop": true,
    "experimentalDecorators": true,
-   "allowJs": true,
    "sourceMap": true,
    "strict": true,
    "noEmit": true,
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "./*"
      ],
      "@/*": [
        "./*"
      ]
    },
-   "types": [
-     "@types/node",
-     "@nuxt/types"
-   ]
  },
  "exclude": [
    "node_modules"
  ]
}
```

この2ファイルの内容を同期しておけば、 `Vetur` 等でエラーメッセージがおかしくなることも少なくなるかと。（ゼロになるとは言ってない）


## 3. Lint設定

ESからTSに変わるのでLint周りも変更しなければなりません。NuxtからEslint Configが提供されているのでそれを使います。 

### `@nuxtjs/eslint-config-typescript` を導入

```bash
$ npm i @nuxtjs/eslint-config-typescript -D
```

### `.eslintrc.js` の編集

```diff:.eslintrc.js
module.exports = {
  ...
  parserOptions: {
-   parser: 'babel-eslint'
  },
  extends: [
    '@nuxtjs',
+   '@nuxtjs/eslint-config-typescript',
    'plugin:nuxt/recommended'
  ],
  ...
}
```

Thanks) [Nuxt v2\.9 \+ Typescriptの環境構築 \- Qiita](https://qiita.com/yoh_zzzz/items/9e2611b7a994427474f6)


## 4. vue-property-decorator の導入

[vue-property-decorator](https://github.com/kaorun343/vue-property-decorator) は Vue + TypeScript でクラスベースでアプリを書いていく為のライブラリです。
別にこれを使わなくても TypeScript で書いていくことは出来ますが、入れたから使わなくてはならないわけではないのでとりあえず入れておきましょう。

### 導入する

```bash
$ npm i vue-property-decorator -D
```

使用する場合は、 `tsconfig.json` と `jsconfig.json` で `experimentalDecorators` オプションを設定してやらないとエラーになります。

```diff:(tsconfig|jsconfig).json
{
  "compilerOptions": {
    ...
+   "experimentalDecorators": true,
    ...
  }
}
```


### 使ってみる

`pages/index.vue` でテストしてみます。

#### Before

```vue
<script>
import Logo from '~/components/Logo.vue'

export default {
  components: {
    Logo
  }
}
</script>
```

#### After

```vue
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import Logo from '~/components/Logo.vue'

@Component({
  components: { Logo }
})
export default class IndexPage extends Vue {
}
</script>
```

## おまけ : 遭遇したエラーたち

### Experimental support for decorators is...

```
Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.
```

と言われる。この機能を利用するためには、`tsconfig.json` と `jsconfig.json` で `experimentalDecorators` オプションを設定する必要があるらしいので、その通りにする。 

- -> [4. vue-property-decorator の導入](#4-vue-property-decorator-の導入) 参照


### Please use `export @dec class` instead

```
error  Parsing error: Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead.
```

と怒られる。 `@nuxtjs/eslint-config-typescript` の導入が必要らしいのでそのようにする。

- -> [3. Lint設定](#3-lint設定) 参照