Nuxt.jsをはじめよう - TypeScriptでコードを書く

Nuxt.jsをはじめよう - TypeScriptでコードを書く
目次

前回の記事 では Vuex を使った状態管理の仕方を書きました。 今回はNuxt.jsのコードをTypeScriptで書くための設定や書き方などを紹介します。

なお、ここでは Nuxt 2.8.x を想定しています。

Nuxt.jsのTypeScriptサポート

Nuxt.js ではTypeScriptをサポートしています。JavaScriptを使った開発において、TypeScriptは静的な型付けをしてくれる言語であるため潜在的なエラーをコーディング段階で排除できることから人気があります。

公式でもTypeScriptのサポートを謳って おり、今回はそれを参考にしつつTypeScriptへの書き換えを行っていきましょう。

なお、2019/08現在では npx create-nuxt-app コマンドを通じてTypeScriptプロジェクトを生成することはできないので、手動で設定を追加していく必要があります。

TypeScriptのモジュールインストール

まずはTypeScriptをトランスパイルするためにモジュールをインストールします。

1npm i -D @nuxt/typescript
2npm i ts-node
3npm i -S vue-property-decorator

vue-property-decorator は公式から提供されたモジュールではないのですが、Nuxt.jsの公式が使うことを推奨しているモジュールのためインストールしておきます。このモジュールにより、.vue ファイルの <script> ブロックをよりClassっぽく書くことができます。

Configファイルの書き換え

次に、プロジェクトルートに tsconfig.json ファイルを作成します。 既にファイルが存在する場合は省略して構いません。

1touch tsconfig.json

次にプロジェクトルートにある nuxt.config.jsnuxt.config.ts にリネームを行います。

1mv nuxt.config.js nuxt.config.ts

その後、nuxt.config.ts の内で NuxtConfiguration 型の定数をexportしてあげます。この config の中に nuxt.config.js の中身をそのままコピーしてあげれば良いです。

1import NuxtConfiguration from '@nuxt/config'
2
3const config: NuxtConfiguration = {
4// ここに中身を引っ越す
5}
6export default config;

Vueコンポーネントの書き換え

次にVueコンポーネントを書き換えます。まずは <script> ブロックに lang="ts" を追加してTypeScriptであることを教えてあげます。

1<script lang="ts">

次にClassを実装してexportします。ざっくりサンプルを記載します。 以下のコードではTypeScript化にしたことでスッキリした点を記載します。

  • @Component(components:〜) によって依存するVueコンポーネントを完結に記載できる
  • <template> ブロック内で呼び出す関数はClass内の関数として定義できる
  • 依存する Vuex ストアも明示的にimportするので理解しやすい
  • TypeSafeな実装にすることができる
 1<template>
 2  <div class="container">
 3    <div class="columns">
 4      <Monitor />
 5      <Menu />
 6    </div>
 7    <Msg :message="initMsg" />
 8    <div class="buttons are-medium">
 9      <a class="button is-primary is-outlined" @click="regist('A')" >A</a>
10      <a class="button is-link is-outlined" @click="regist('B')">B</a>
11      <a class="button is-info is-outlined" @click="regist('C')">C</a>
12    </div>
13  </div>
14</template>
15
16<script lang="ts">
17import { Vue, Component } from 'vue-property-decorator'
18import { userModule } from '@/store/modules/user'
19
20@Component({
21  components: {
22    Monitor: () => import('../components/Monitor.vue'),
23    Menu: () => import('../components/Menu.vue'),
24    Msg: () => import('../components/Msg.vue')
25  }
26})
27export default class Next extends Vue {
28  initMsg: string = 'Welcome to netx page!!'
29
30  public async regist(value) {
31    await userModule.save()
32    this.$router.push('/users/')
33  }
34}
35</script>

注意点としては、@Component アノテーションの中では computedmethods といったパラメータも受け付けられるので、アノテーション中に処理をモリモリ書いていくとTypeScriptにした旨味が減るように思います。

若干学習コストを払いますが vue-property-decoratorのdoc を読みながらClassで書く方法を模索すると良いです。

最後にStoreのコードもTypeScript化してみます。ここでは vuex-module-decorators を使って書いていますが、このモジュールはvue-property-decorator と違ってNuxt.jsの公式から推奨されているわけではないので、利用するかどうかはおまかせします。

 1import { VuexModule, Module, Action, Mutation, getModule,} from 'vuex-module-decorators';
 2import store from "@/store/store"
 3import axios from 'axios';
 4
 5export interface User {
 6  name: string
 7}
 8
 9interface UserState {
10  users: Array<User>;
11}
12
13@Module({ dynamic: true, store, namespaced: true, name: 'user'})
14class UserModule extends VuexModule implements UserState {
15
16  users: Array<User> = [];
17
18  get all(): Array<User> {
19    return this.users;
20  }
21
22  @Mutation
23  updateUser(users: Array<User>): void {
24    this.users = users
25  }
26
27  @Action({})
28  async save() {
29    const users = await axios.get<Array<User>>(process.env.apiBaseUrl + '/users')
30    this.updateUser(users.data)
31  }
32}
33export const userModule = getModule(UserModule)

参考にさせていただいたサイト