Nuxt.js v2.6.1 + TypeScriptで型の恩恵を受ける

はじめに

もともとUnityエンジニア兼CSharperではあったのですが、業務都合でWebアプリケーションを作る機会があったので、何事もやってみないとわからないしどうせなら流行りに乗ってみよう!ということでここ半年近くNuxt.jsとTypeScriptでWeb開発をしていました。

自分がNuxt.jsを触り始めたころはv2.0がリリースされるちょっと前で、その頃には公式にTypeScriptはサポートされていませんでした。とはいえ静的型付けに慣れている身としてはJavaScriptよりもTypeScriptを使いたいという思いが強かったので、四苦八苦しながらもなんとか開発できる環境を整えました。

そんなNuxt.jsもv2.4.0からTypeScriptが公式にサポートされたので、TypeScriptによる開発がだいぶ容易になってきました。2019年4月5日現在はv2.6.1がリリースされており、v2.4.0で必要であったnuxt-tsモジュールが早速廃止されるなど変化は激しいですが、どんどん使いやすくなっており好印象を持っています。

今回はcreate-nuxt-appを使って、イチからNuxt.jsプロジェクトを作る方法をまとめます。

Nuxt.jsのインストール

2019年4月5日現在、create-nuxt-appでプロジェクトを作成するだけで、Nuxt.js v2.6.1がインストールされます。今回は以下の内容でプロジェクトを作成しました。

  • Server framework - none
  • Additional features - none
  • UI framework - vuetify
  • test framework - none

プロジェクト作成が完了したら、npm run devにてサーバが立ち上がることを確認します。

TypeScript対応

Nuxt.jsではv2.4.0よりTypeScriptサポート機能が大幅に強化されました。v2.4.0以前はwebpackの設定をカスタマイズする必要がありましたが、サポート強化後はいくつかパッケージを追加するだけでTypeScriptでコードを書ける環境が整います。

パッケージのインストール

必要となるパッケージは以下の通りです。

typescript
TypeScriptモジュール。トランスパイラなどが含まれます。

ts-node
TypeScriptをトランスパイルすることなく動かすためのランタイム。ビルド時に使用しているようです。@nuxt/cliや@nuxt/builderあたりのコードを読めば動作が把握できそうです。

@nuxt/typescript
ビルド時にtsconfig.jsonをロードしてくれるモジュール。プロジェクトにtsconfig.jsonが存在しない場合は自動で生成する機能も有している。

nuxt-property-decorator
必須ではありませんが、Vueコンポーネントをクラススタイルで書けるようにするためのデコレータセットです。一部のIDEだと型定義ファイルによるコード補完が少し弱くなりますが、コンポーネントの定義内容がわかりやすくなるのでよく使います。公式ではvue-property-decoratorを使うようになっていますが、私が試した時にはpageコンポーネントのメソッド(asyncDataやfetch)が動かなかったので使っていません

tsconfig.jsonの追加

tsconfig.jsonはTypeScriptのコードをコンパイルするときに使用する設定ファイルです。前述の通りtsconfig.jsonは初回起動時に自動で生成されますが、今回は公式のサンプルを参考にtsconfig.jsonを追加しています。

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "lib": [
      "esnext",
      "esnext.asynciterable",
      "dom"
    ],
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "allowJs": true,
    "sourceMap": true,
    "strict": true,
    "noImplicitAny": false,
    "noEmit": true,
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "./*"
      ],
      "@/*": [
        "./*"
      ]
    },
    "typeRoots": [
      "./node_modules/@nuxt/vue-app/",
      "./node_modules/@types"
    ]
  }
}

TypeScriptでコードを書く

create-nuxt-appvuetifyで作成したプロジェクトに最初から含まれているコンポーネントをTypeScriptで書き直します。

default.vue

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

@Component
export default class extends Vue {
  clipped = false;
  drawer = false;
  fixed = false;
  items = [
    {
      icon: "apps",
      title: "Welcome",
      to: "/"
    },
    {
      icon: "bubble_chart",
      title: "Inspire",
      to: "/inspire"
    }
  ];
  miniVariant = false;
  right = true;
  rightDrawer = false;
  title = "nuVuetify.js";
}
</script>

scriptタグにlang=“ts”を指定するだけでTypeScriptによって書かれたVueコンポーネントと認識されます。

続いてindex.vue

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

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

デコレータを使うスタイルの場合、外部のコンポーネントを使用する場合は@Componentデコレータの中に使用するコンポーネントを列挙します。そのほかにもミドルウェアを使用するときなどもデコレータ内にて定義する必要があります。

Nuxt.js関連のオブジェクトの型定義を使う

型定義ファイルは@nuxt/vue-appに入っています。Nuxt.jsのpageコンポーネントを使うにあたって利用頻度が高いであろうContextの型定義もこの中に入っています。

index.vue(追加)

<script lang="ts">
import { Context } from "@nuxt/vue-app";

import Vue from "vue";
import { Component } from "nuxt-property-decorator";
import Logo from "~/components/Logo.vue";
import VuetifyLogo from "~/components/VuetifyLogo.vue";

@Component({
  components: {
    Logo,
    VuetifyLogo
  }
})
export default class extends Vue {
  asyncData(ctx: Context) {
    // Contextオブジェクトにアクセスするときプロパティの候補がIDEから提示される
  }
}
</script>

備忘

@nuxt/vue-appの中のvue.d.tsにはNuxt.jsのpageコンポーネントにあわせたVueクラスの型定義拡張が用意されています。しかしデコレータを使ったクラススタイルでコンポーネントを書く場合にどのように利用すればいいのかわからないので困っています…

まとめ

Nuxt.js v2.6.1とTypeScriptで開発するための第一歩をまとめました。 Nuxt.jsを利用する機会が増えてきたので、そろそろNuxt.js自体の実装も把握しておこうかなと思います。まずはビルドまわりから。

Profile
d_yama
元Microsoft MVP for Windows Development(2018-2020)
Sub-category : Windows Mixed Reality
Search