Nuxt v2.xでVuexからPiniaに移行してみた
今回はNuxt v2.xを用いたプロダクトで利用していたVuexをPiniaに移行したので、その際に得られた知見を記事にします。
この記事では、
・Piniaってなんなの?
・Vuexと比べてどうなの?
・実際に変えてみて良かったこと、大変だったこと
についてまとめていきます。
主にVuexを利用している or していた人向けに書くため、Vuex自体についての説明は割愛します。
Piniaとは?
Vueの状態管理のためのライブラリです。
Vue3からは、VuexではなくPiniaが状態管理のライブラリとして公式に推奨されています。
また、Vuex5の目的だったことがほぼPiniaで実現されていることから実質Vuex5であり、Vuex3,4は引き続きメンテナンスされていくが、追加機能の実装はないことが公式からアナウンスされています。
https://github.com/vuejs/vuex
なお、既存のVue2のプロダクトに導入することも可能です。
Piniaのざっくり説明
State,Getter,Actionの3つの要素によって構成されています。
状態を格納するState、Stateを加工して算出するGetter、Stateを更新するActionの3つです。
Vuexを使っていた人向けにざっくりと説明するなら、Vuexのactionとmutationを合わせたのがPiniaのActionです。
State,Getterは役割としてはVuexと同じという理解で問題ありません。
また、Vue.js devtoolsのサポートがあり、Vuexのように開発中にstoreの中身を参照することが可能です。
Vuexと何が違うの?
mutationの廃止
まず、前述の通り、mutationがなくなっています。
コードを書く際にmutationを書くのが個人的に面倒と感じることも多く、書きやすさやコードの可読性という点においてかなり嬉しいポイントです。
一方で、mutationの存在意義でもあった、stateの更新に制約を加えるという要素がなくなっているのも事実です。piniaではコンポーネント内からstore.count = 2のようにstoreを更新することができてしまいます。
実際、Vuexのstrictモードでは、そういったstateの更新を禁じるためにmutation以外でのstoreの更新はエラーになるようになっていました。
このことからも、状態の変更はmutationに集約すべきという思想があったことが窺い知れます。
これについては、piniaのissuesでも議論されており、component内でstoreの直接的な更新を禁じるようなoptionを追加するPRが作成されていることも確認できました。
https://github.com/vuejs/pinia/issues/58
https://github.com/vuejs/pinia/pull/493
自分がissueを読んだ感じだと、以下のような理由が挙げられていました。
・stateの更新に対する制約はlinterがやることで、ライブラリがやることじゃない
・Vuexでは単純なstateの更新をするだけのmutationがたくさんできてしまっていたこと
・mutationはdevtoolのためという側面が大きかったが、piniaはmutationがなくとも状態の追跡が可能になった
これらのことからmutationは不要と判断しているようです。
納得感あるし、何よりコードがスッキリするので良いと思いましたが、少し注意が必要だなと思いました。
Typescriptのサポートほか
次にtypescriptがデフォルトでサポートされています。これが本当に嬉しい…
Vuexをtypescriptに対応させるために、ライブラリを追加したり、独自のクラスを実装したり、かなり面倒だったので…
他にもモジュールの入れ子構造が無くなったことや、名前空間が無くなったことなどが挙げられますが、詳しくは公式の以下の箇所を参照してください。
https://pinia.vuejs.org/introduction.html#comparison-with-vuex-3-x-4-x
実際に移行を担当されたメンバーによかった点、苦労した点について聞いてみました。
よかった点
・型推論が強い
Vuexの場合、型推論を効かせるために、独自で型のための情報をNuxtに渡す必要があり、actionなどの推論はうまくいっていなかった。PiniaはデフォルトでTypeScriptに対応しているので、複雑なことをする必要がなく、型推論が効く。
・mutationがなくなるため、コードがスッキリする。
Vuexの場合はstate更新時に必ずmutationを経由する必要があったが、Piniaにはmutationがないので、actionから直接更新することができ、コード量が減り見通しが良くなった。
・ビルドが早くなった
ビルド時間が10%ほど短縮された。
・Devtoolのサポートがある
Vuexを使うメリットの一つとして、Vue Devtoolsのサポートが受けられるというものがあったが、piniaもサポートされているため、便利!
・Vuexからの移行が簡単
storeの中はmutationsを消して、actionsでstoreを書き換えるように修正し、
コンポーネント側では、storeの参照をPiniaで作ったstoreに向けるだけで済んだので、時間がそこまでかからなかった。
移行時に躓いたポイント
・store内で、nuxtのコンテキストがthisから直接参照できなくなる。
Nuxt v2ではthis.$nuxt.に変更することで参照可能になる。
Nuxt v3ではuseNuxtApp()で代用可能。
・nuxtServerInitが自動実行されなくなる。
middlewareなどで呼び出すように修正してあげる必要がある。
まとめ
・PiniaはVueの状態管理ライブラリのスタンダードにこれからなっていきそう
・全体的に書きやすくなっており、開発体験がVuexより向上しているが、mutationが無くなっていることに関しては注意
・Vuexからの移行も比較的容易
今回の移行では発生しませんでしたが、storeのモジュールを多重にネストしていた場合などは移行に少し苦戦するかもしれません。
また、mutationがなくなることで、state更新の制約がなくなることは事実なので、レビューやlinterなどで制約を設ける必要があることは留意が必要だなと感じました。
しかしながら移行したことで、Vuexより開発体験が向上し、より効率良くコードを書けるようになったことは間違いありません!
引き続き、Vue,Nuxt周りで得られた知見を共有していければと思います。
SHOWROOM株式会社では、エンジニア職を絶賛募集中です。
・ライブ配信サービス「SHOWROOM」
・バーティカルシアターアプリ「smash.」
以下の求人内容をご確認の上、ご興味あればご応募ください。
心よりご応募お待ちしております。
■求人は以下になります
SHOWROOM株式会社採用情報
■その他SHOWROOM株式会社の情報
・ note(代表前田取材記事です!)
・ 社員インタビュー記事
・ SHOWROOM
・ smash.
・ SHOWROOM最新記事一覧(PRTimes)
この記事が気に入ったらサポートをしてみませんか?