Vue3とTypeScriptの相性の良さの理由!フルスタックエンジニアがVue3で堅牢・大規模開発を解説します😎

Vue3とTypeScriptの相性の良さの理由!フルスタックエンジニアがVue3で堅牢・大規模開発を解説します😎

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!

WEB のフロントエンド開発(JS フレームワークで開発)をする際、TypeScript を導入することは最近では当たり前になりつつあります。

React × TypeScript の相性が良いことは様々な記事で解説されておりますが、
Vue2 × TypeScript では以下の点から相性が悪いと言われておりました。

  • Options API での型定義が複雑で開発効率が良くない → Vue2.4 以下の場合は this の型推論がされない
  • Vuex の型推論問題(mapState や mapGetters などのヘルパー関数は正しく推論されない)

特に Vuex × TypeScript 周りでは any 型を使わざるを得ない場面が出てきて妥協することも出てくると思います。

今回は Vue2 からアップデートされた Vue3 と TypeScript の相性についてや 大規模開発で使われる Nuxt3 について解説したいと思います!

対象とする読者

  • Vue2 で開発しており、Vue3 を使おうと検討しているヒト
  • Vue3 で大規模開発を検討しているヒト

はじめに

本記事では TypeScript の詳細な解説しておらず、概要レベルでの説明となっております。
また、本記事では Nuxt3 について触れていますが、リリース前の情報になるためリリース後と異なる場合があります。

Vue2 からの Vue3 へのアップデート対応について

Vue2 で TypeScript を使用する際のハードルの1つは、 技術的には可能であるものの、Vuex などの型推論が思うように機能しない等々による導入コストの高さです。

例えば、Vuex 全体で型を簡単に検出できる機能が不足しており、エラーなく動作させるためには様々な妥協をしなければなりませんでした。


Vue2 自体が TypeScript で書かれていないのに対し、 Vue3 は完全に TypeScript で書き直されており、開発者は TypeScript のサポートの向上を期待する事ができます。

VSCode での Vue の拡張機能である Vetur などの開発者ツールや Vue Router、Vuex などのライブラリにおいても TypeScript の使用がより簡単になりました。

その結果 Vue2 よりも Vue3 の方が TypeScript の導入コストは低くなったと言えます。

Vue2 で途中から TypeScript を入れることは可能ですがリプレースなどのコストがかかるのに対し、
Vue3 の場合ははじめから TypeScript がサポートされているためそのような心配は必要ありません。

具体的なアップグレード方法についてはこちら

※ Vue3 は IE11 をサポートしていないため IE11 をサポートする場合は Vue2 のままにしておくことを推奨します

なぜ TypeScript を使う?

私たちの考えるフロントエンドの開発に TypeScript を導入することで得られるメリットは以下です。

  1. API レスポンスへの型付によるタイプセーフなオブジェクト参照
  2. amplify codegen による Graphql レスポンスへの強力な型付
  3. amplify codegen による Mutation, Query リクエストへの強力な型付
  4. Store(Vuex)への安全でタイプセーフなアクセス
  5. オープンソースモジュール(npm)への型付
  6. NuxtJS/VueJS コンパイル時の型エラー検出
  7. エディタの自動補完(変数参照、関数参照等々)

通常の JS でフロントエンドを実装した場合、エラーを検出しにくくデバッグが困難なシーンが度々発生しますが、TypeScript を導入すればある程度のエラーが明確に拾えるようになります。(常に完全なエラー詳細を取得できるとは限りません)

特に TypeScript は複数人での開発でその真価を発揮します。特にスタートアップの開発中は API 定義がよく変更されるため、TypeScript による型付けは大変有用です。

また余談ですが Vue2 の場合でも、 vue-class-component や vue-property-decorator などの外部モジュール(デコレータ)をインストールすることで TypeScript の導入が可能です。(NuxtJS の場合は nuxt-property-decorator )後述で Vue3 とTypeScript の相性の良さを解説しますが、プロジェクトの事情で仕方なく Vue2 を導入される場合でも TypeScript の利用をぜひ検討してみてください。

静的型付けによるコードの品質や可読性の向上

動的型付けな JavaScript は実際にインスタンス化されるまで変数や関数の引数などの型がわかりません。TypeScript は開発時に型を付与するため、変数や関数の引数などの型を推測してくれます。(型推論)

型推論によりコードを書いてる時点でエラーに気づいて修正することができます。
これはランタイム(実行時)でエラーに気づいて修正するよりもはるかに効率的です。

例えば、JavaScript で開発していると以下のような Null/undefined のエラーに遭遇する場面があると思います。

cannot read property 'x' of undefined

TypeScript の場合は定義されていない変数を使うことはできないためこのようなエラーは事前に防ぐことができます。

JavaScript でも関数などの doc でコメントをつけることができますが、TypeScript はコードの情報がそのまま型推論されるため信用性は高いと思います。

また、VSCode の Intellisense などの補完機能を使うことで、JavaScript に比べ開発効率は間違いなく上がると思います。

様々な JS 環境でも最新の構文が使用可能

TypeScript はコンパイル後の JavaScript バージョンを指定する事ができます。

プロジェクトの要件によっては ES5 などの古い要件での開発があると思いますが、TypeScript で ES6 などの構文をES5 へコンパイルすることも可能です。

また、TypeScript は ECMAScript への準拠を原則としており、便利な新機能を使う事ができるため、TypeScript は最新の JavaScript の構文を使いながら古い環境の JavaScript バージョンへも対応する事ができます。


その他のメリットについてはこちらをご覧いただければと思います。

TypeScript の基本構文こそは学習する必要がありますが、JavaScript の知識があれば TypeScript を使い始めることができます。

Vue に関してですが、後述する Composition API は関数型でコンポーネントを記述でき、 TypeScript を使うメリットは大きくなると思います!

Vue3 と Typescript の相性について

先ほども述べましたが、 Vue2 から Vue3 にアップデートされ、より TypeScript での開発がしやすく、アプリケーションへ TypeScript を導入するコストも低くなりました。

その中で注目すべき機能は Composition API と Vuex4 だと思います。

Composition API

Vue3 から Composition API という機能が追加されました。

主なメリットは以下となります。

  • TypeScript のサポート
  • コードの構造化(ロジックの再利用)

これまでの Vue2 では主に Options API や ClassComponent で書く事が多かったのではないかと思います。

Options API においては options(data や methods、mounted など)や VueJS のライフサイクルについて基礎を把握していれば、誰が書いてもある程度秩序のあるコードを書くことができます。

import Vue from "vue";
 
export default Vue.extend({
  data() {
    return {
      name: 'John',
    };
  },
  methods: {
    doIt(): void {
      console.log(`Hello ${this.name}`);
    },
  },
  mounted() {
    this.doIt();
  },
});

対して Vue3 で新たにリリースされた Composition API では
ロジックごとに切り出す事が可能な関数ベースの API となっております。

import { defineComponent, ref } from 'vue'
 
export default defineComponent({
  setup() {
    // data
    const name = ref('John');
    
    // methods
	  const doIt = () => console.log(`Hello ${name.value}`);
    
    // mounted
	  onMounted(() => {
	    doIt();
	  });

    return { name };
  }
});

実装上での大きな変更点は以下になります。

  • data, computed, method 等の Vue 機能は全て setup 関数に定義
  • ライフサイクルのフックは setup 関数に定義
  • リアクティブ(変更検知)したい値は全て ref で指定必須
  • 暗黙的に動作していた部分を全て明示的に実装する必要有

また、 setup() 内では this を使ってのアクティブなインスタンスへの参照はできません。

setup() 内では、this は現在のアクティブなインスタンスへの参照にはなりません。 setup() は他のコンポーネントオプションが解決される前に呼び出されるので、setup() 内の this は他のオプション内の this とは全く異なる振る舞いをします。 これは、setup() を他のオプション API と一緒に使った場合に混乱を引き起こす可能性があります。

https://v3.ja.vuejs.org/guide/composition-api-setup.html#this-の使用

Options API では暗黙的で別途記述が必要だった部分が、 Composition API を使用することで型推論が効き開発効率が上がります。

Vuex4

Vuex4 は2021年2月3日にリリースされました。

今回のアップデートで TypeScript をサポートしており、前述の Composition API と組み合わせることで
正しく型付けされたアプリケーションの開発ができるようになりました。

TypeScript を使用する際には以下のような型宣言ファイルを作成する必要があります。

// vuex-shim.d.ts

import { ComponentCustomProperties } from 'vue'
import { Store } from 'vuex'

declare module '@vue/runtime-core' {
  // ストアのステートを宣言する
  interface State {
    count: number
  }

  interface ComponentCustomProperties {
    $store: Store<State>
  }
}

Composition API で使用する場合ですが、 setup 関数内ではこれまでのような this.$store でのストアの取得はできません。

useStore という Composition API でストアを操作するための新たな合成関数が登場しました。
setup 関数内で useStore を使うことでストアを取得する事ができます。

import { useStore } from 'vuex'

export default {
	setup () {
		const store = useStore()
	}
}

Nuxt3 で堅牢な大規模開発

React や Vue での大規模開発には NextJS や NuxtJS の導入を検討すると思います。

NuxtJS で Composition API を使う場合などは別途 [@nuxtjs/composition-api](<https://composition-api.nuxtjs.org>) のライブラリを入れて対応する必要がありました。

2021年10月12日に公開される Nuxt3 では Composition API をはじめとする Vue3 の機能をカバーしており、
Nuxt2 よりも堅牢な大規模開発ができると思います。

他にも Nuxt3 には以下の機能が発表されています。

  • Nuxt2 よりも20%軽量なファイルサイズ
  • 開発環境の高速化
  • ISR のサポート
  • Composition API の標準搭載
  • Webpack 5
  • Vue3 フルサポート
  • TypeScript フルサポート
  • Netlify などのホスティングサービスで SSR サポート
    (Nitroと呼ばれる新たなサーバーエンジンとサーバーレス機能の組み合わせ)

また、既存の Nuxt2 プロジェクトに Nuxt3 の機能を導入できるものも紹介されており、
Nuxt2 でより簡単に Composition API が使用できるようになったり Nuxt3 へ段階的なアップグレードがサポートされる予定です。

まとめ

今回は Vue3 × TypeScript の相性について Nuxt3 での大規模開発について紹介しました。

Nuxt3 についてはまだリリースされていないということで不明点はあると思いますが、
特徴として Composition API や TypeScript の完全サポートがあげられております。

より TypeScript で開発しやすくなりましたので、React/NextJS で開発していた方も Vue3/Nuxt3 での開発を検討してみてはいかがでしょうか?

Vue3/Nuxt3でのフロントエンドの開発は、ぜひお気軽にお問い合わせください!