Nuxt.js【プロジェクト設定編】

## 概要

2020/09/25　※随時更新

Nuxt.jsをTypeScriptで開発する時の設定メモです。  
可能な限りTypeScriptの型システムや補完が活かせるようにします。

- **[nuxt.js](https://ja.nuxtjs.org/guide/)**
- **[typescript](https://www.typescriptlang.org/)**

## プロジェクトの作成

```bash
$ npx create-nuxt-app <project-name>
```

```bash
create-nuxt-app v3.3.0
✨  Generating Nuxt.js project in <project-name>
? Project name: nuxt-ts-starter
? Programming language: TypeScript
? Package manager: Npm　# お好みで
? UI framework: None　# お好みで
? Nuxt.js modules: Axios
? Linting tools: ESLint, Prettier, StyleLint # 最低この３つ
? Testing framework: Jest
? Rendering mode: Universal (SSR / SSG) # お好みで
? Deployment target: Server (Node.js hosting)　# お好みで
? Development tools: # js.configは不要
? Version control system: None
```

### Typescript化

```@types/vue-shim.d.ts
declare module "*.vue" {
  import Vue from 'vue'
  export default Vue
}
```

nuxt.config.js -> nuxt.config.ts

```nuxt.config.ts
import { NuxtConfig } from '@nuxt/types'

const config: NuxtConfig = {
  ...
};

export default config;
```

`$ npm run dev` 実行時に以下のようなエラーが出た場合は、`@nuxt/typescript-runtime`をアップデートする。
[https://github.com/nuxt/nuxt.js/issues/8015](https://github.com/nuxt/nuxt.js/issues/8015)

```bash
ERROR  Failed to compile with 1 errors  
This relative module was not found:   
* ./index.vue?vue&type=script&lang=ts& in ./pages/index.vue
```

```bash
$ yarn add @nuxt/typescript-runtime --dev
```

**フォーマッターのスクリプトを設定**

```json:package.json
{
    "format:ts": "prettier --quiet --write **/*.{vue,ts}",
}
```

## 使用ライブラリー

### [@vue/composition-api](https://github.com/vuejs/composition-api)

> 関数ベースでコンポーネントを実装しTypeScriptとの相性を高める。  
> 今後は[`@nuxtjs/composition-api`](https://composition-api.nuxtjs.org/)も検討する。

- [参考](https://qiita.com/Aruneko/items/552fcd3ae5da4eb1b218)

**インストール**

```bash
$ npm i @vue/composition-api
```

**設定**

```plugins/composition-api.ts
import Vue from 'vue'
import VueCompositionApi from '@vue/composition-api'

Vue.use(VueCompositionApi)
```
```nuxt.config.ts
const config: NuxtConfig = {
  // ...
  plugins: ['@/plugins/composition-api'],
  // ...
}
```

**Vue.extend -> defineComponentへ変更**

```pages/index.vue
<template>
    ...
</template>

<script lang="ts">
import { defineComponent } from '@vue/composition-api'

export default defineComponent({})
</script>
```

### [nuxt-typed-vuex](https://github.com/danielroe/nuxt-typed-vuex)
> Vuexに型情報を付与する。

- [参考](https://qiita.com/shindex/items/a90217b9e4c03c5b5215)

**インストール**

```bash
$ npm i nuxt-typed-vuex
```

**設定**

```nuxt.config.ts
const config: NuxtConfig = {
  ...
  buildModules: ['nuxt-typed-vuex'],
  ...
  build: {
    transpile: [/typed-vuex/,]
  },
  ...
}
```

```store/index.ts
import { getAccessorType } from 'typed-vuex'

export const state = () => ({})

export const getters = {}

export const mutations = {}

export const actions = {}

export const accessorType = getAccessorType({
  state,
  getters,
  mutations,
  actions,
  modules: {},
})
```

```@types/vuex.d.ts
import { accessorType } from '~/store'

declare module 'vue/types/vue' {
  interface Vue {
    $accessor: typeof accessorType
  }
}

declare module '@nuxt/types' {
  interface NuxtAppOptions {
    $accessor: typeof accessorType
  }
}
```

## 備考
どんどん更新して行こうと思いますので、良いライブラリーや設定などありましたら是非教えてください！