Vueの振り返り

これは記事の日本語版。

The English version of this article is here.

二年前Vue 2を批判している記事を書いた。それ以来、Vue 3といくつかの新しいツールを通してほとんどの問題が解決できた。現時点ではVueでアーキテクチャ的な問題が残っていないと思う。

自分の口からそんな褒め言葉が出るとは。

前の記事の問題を次のように解決した。

テンプレートの型安全

二年前、Vue 2のテンプレート内で型安全が一切なかった。そのせいで無意味なバグが非常に書きやすかった。Storybookとステージング環境で常に細かい不具合を発見していた。

初めには部分的な解決策しか見つからなかった。我々はVSCode派で、唯一の本番向けの拡張機能としてVeturを使っていた。Vue自体は型安全機能が付いていないため、その提供はVeturに任せられた。Veturは確かに、実験的な型安全を提供しはじめたが、あまりにも不完全だった。特に別ファイルで定義された型を拾わないところが致命的だった。

そしてついに数ヵ月前、Volarという新たな拡張を偶然に見つけた。この拡張は本格的な型安全がある。ライブラリーも、別のファイルの型も拾われている。おかげで今はVueファイルで完全な型安全で開発できている。

グローバルな変数

Vueのテンプレートでグローバルな変数を参照するため、改めてコンポーネントの中でその変数を定義しなければならない。

正確にいうと、この問題を直さなかった。Composition APIで問題がなくなったからだ。

同じコンポーネントでたくさんの変数、関数などを定義するのは、普段テンプレートで何かを計算しているから必要となる。でもVue 3のComposition APIを活かせば、その処理を再使用可能なフックに抽象化するの方が自然だ。テンプレートに限らず、コンポーネント全体がそのフックの計算に必要な関数をインポートする必要もなくなった。

Vuexが複雑すぎる

Vuexの使用を完全に止めた。その決定は簡単だった。

Vuexの代わりを決めることは時間がかかった。今の実装は「動的なストア」と似ていて、injectprovideで動く。例えば、ユーザのステートが共有したいとする。共通ステートを立てる、そして取得するフックを作る。

実践でコードは次のように書く。

import { inject, InjectionKey, provide, readonly, Ref, ref } from 'vue-demi';

const USER_INJECTION_KEY: InjectionKey<UserContext> = Symbol('user');

export function useUser(user: Ref<User | null>) {
  const context = {
    user: readonly(user),
  };
  
  provide(USER_INJECTION_KEY, context);
  return context;
}

export function useCurrentUser() {
  return inject(USER_INJECTION_KEY, {
    user: readonly(ref(null)),
  });
}

export type UserContext = ReturnType<typeof useUser>;

(型は循環的に見えるが、コンパイルも型チェックもちゃんと効く。)

他の共通データもInjectionKeyで共有する。上記のパターンは利点がいくつかある。

  1. 型安全がある。Vuexのストアと違って、何が入っていると何ができるのが明確で、コンポーネントで使う時は再宣言も不要。
  2. Storybookにとって楽。ユーザに依存するコンポーネントはuseUserを呼べば済む。よくあるユーザ状態も共通化できる。例えば、useMockUseruseMockAdminUserをよく使う。レゴのように複雑なデータを築いていく。
  3. たまに非現実的な機能が意外と現実的になる。例えば、アドミンがなりすましログインをして別のユーザの視点から画面が見たいとする。上記の書き方だと、どこかでuseUserを呼んでおいて、それ以降のコンポーネントは全部そのユーザを使うことになる。アプリの一部が動いている文脈を変えるのは直感的にできる。

型のある簡単なTypeScriptで「ストア」が書けるから、Vuexに戻る未来を想定していない。

結論

ここ二年Vueが成長してきたことは間違いない。確かに、今はレガシーなVue 2プロジェクトを数個持っている。いつVue 3になるのも不明。でも新規に開発されるプロジェクトはしっかりしたベースができていると思う。

最新のVueは過去最強のVueである。あなたの組織がフロントエンドのフレームワークを調べているなら、真面目にVueも検討すべきだと思う。