TypeScriptなNuxt.jsをVSCodeで開発

作成したテンプレートは以下にあります。
[c8112002/nuxt-ts-template](https://github.com/c8112002/nuxt-ts-template)

## 1. プロジェクト作成

今回作成するプロジェクトはSPAモードでフォーマッタにPrettierを使用します。

```bash
$ yarn create nuxt-app nuxt-ts-template

? Project name nuxt-ts-template
? Project description My dazzling Nuxt.js project
? Use a custom server framework none
? Choose features to install Linter / Formatter, Prettier, Axios
? Use a custom UI framework none
? Use a custom test framework none
? Choose rendering mode Single Page App
? Author name c8112002
? Choose a package manager yarn
```
## 2. VSCodeの設定

### 2-1. Extensionの追加
以下のExtensionを追加。

- [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur)
  - Vueのシンタックスハイライトや補完ができるようになる
- [Vue Peek](https://marketplace.visualstudio.com/items?itemName=dariofuzinato.vue-peek)
  - template内からコンポーネントへのジャンプやPeek Definitionができるようになる
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
  - ワークスペース（なければグローバル）のESLintを使って警告やファイル保存時にauto fixができるようになる
- [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig)
  - workspace設定の内容を `.editorconfig` で上書きしてくれる

### 2-2. workspace設定

`.js` `.ts` `.vue` ファイルの保存時にESLintを走らせます。

`.vscode/settings.json` を追加し、以下を追記。

```json
{
  "eslint.validate": [
    {
      "language": "javascript",
      "autoFix": true
    },
    "javascriptreact",
    {
      "language": "typescript",
      "autoFix": true
    },
    {
      "language": "vue",
      "autoFix": true
    }
  ],
  "eslint.autoFixOnSave": true,
  "vetur.format.defaultFormatter.html": "prettier"
}
```

## 3. TypeScript化

### 3-1. 必要なモジュールをインストール

```bash
$ yarn add -D @nuxt/typescript
$ yarn add ts-node
```

### 3-2. tsconfig.jsonの作成

[Nuxt TypeScript サポート](https://ja.nuxtjs.org/guide/typescript)によると、
> 情報: tsconfig.json は nuxt コマンドを初回実行時に自動的にデフォルト値で更新されます。

とのことなので、

```bash
$ touch tsconfig.json
$ yarn run nuxt
```

これで `tsconfig.json` に適当な設定がされる。

次作業で修正する `nuxt.config.ts` 内で `package.json` をimportする部分があるので、 `tsconfig.json` に以下を追記。

```json
"resolveJsonModule": true,
```

参照: [TypeScript --resolveJsonModule](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html#new---resolvejsonmodule)

### 3-3. nuxt.config.jsをTypescript化

`nuxt.config.js` を `nuxt.config.ts` にリネームし以下のように修正。

```typescript
import NuxtConfiguration from '@nuxt/config'
import pkg from './package.json' // <--拡張子を追加

const config: NuxtConfiguration = {

  //・・・

  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {
      // Run ESLint on save
      if (ctx.isDev && ctx.isClient) {
        if (!config.module) return // <--追記
        config.module.rules.push({
          enforce: 'pre',
          test: //.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }
}

export default config
```

### 3-4 ESLintの設定

```bash
$ yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser
```

`package.json` のlintを修正。

```json
・・・
  "scripts": {
    ・・・  
    "lint": "eslint --ext .ts,.js,.vue --ignore-path .gitignore .", // <- .tsを追加
    ・・・
  },
・・・
```

`.eslintrc` を修正。

```javascript
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parser: 'vue-eslint-parser',
  parserOptions: {
    'parser': '@typescript-eslint/parser',
  },
  extends: [
    '@nuxtjs',
    'plugin:nuxt/recommended',
    'prettier',
    'prettier/vue',
    'prettier/@typescript-eslint',
  ],
  plugins: [
    'prettier',
    '@typescript-eslint'
  ],
  // add your custom rules here
  rules: {
    "prettier/prettier": "error",
    "no-unused-vars": "off",
    "@typescript-eslint/no-unused-vars": "error"
  }
}
```

__※eslint-plugin-prettierの設定について__

`eslint-plugin-prettier` の [README](https://github.com/prettier/eslint-plugin-prettier#recommended-configuration)に書かれているよように

```javascript
{
  "extends": ["plugin:prettier/recommended"]
}
```
と設定すれば、下記の設定は省略できるはずですが、

```javascript
extends: [
    'prettier',
  ],
  ・・・
  plugins: [
    'prettier',
  ],
  ・・・
  rules: {
    "prettier/prettier": "error",
  }
```
この設定だとVSCodeが `.prettierrc` の変更を検知してくれませんでした。

今回は[こちら](https://github.com/prettier/eslint-plugin-prettier/issues/103#issuecomment-425670176)を参考に `"extends": ["plugin:prettier/recommended"]` を使わないで対応しました。

同じisssue上で[指摘](https://github.com/prettier/eslint-plugin-prettier/issues/103#issuecomment-481563862)されていますが、terminal上から `yarn run lint --fix` のようにeslintを実行するとちゃんと `.prettierrc` が読み込まれているので、VSCodeのESLintエクステンションのバグでしょうか？

### 3-5 vue-property-decorator導入

```bash
$ yarn add vue-class-component vue-property-decorator
```

`components/Logo.vue` と `pages/index.vue` をクラス形式に変更。

components/Logo.vue

```vuejs
<template>
・・・
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'

@Component
export default class Logo extends Vue {}
</script>
・・・
```

pages/index.vue

```vuejs
<template>
・・・
</template>

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

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

## 4. 動作確認

開発サーバ起動。

```bash
$ yarn run dev
```

`http://localhost:3000` にアクセスして以下の画面が表示されれば完了。

![スクリーンショット 2019-05-17 13.38.59のコピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18185/f09e78db-26e3-3713-44e7-8e115d808457.jpeg)



## 参考
- [Nuxt.js TypeScript サポート](https://ja.nuxtjs.org/guide/typescript)
- [Nuxt.js v2.6でTypeScriptが書ける環境を構築する](https://qiita.com/dora1998/items/932506fa995962d4dc63)
- [TypeScript --resolveJsonModule](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html#new---resolvejsonmodule)