デザイン部でフロントエンドエンジニアをしているkitoです。React.jsとVue.jsの登場で、JS界隈は一時期の混沌とした時代から落ち着いてきましたが、今や両者それぞれのエコシステムが豊かになるフェーズに移行しています。jQueryがデファクトスタンダードになり、盛んにプラグインが開発されていた頃を彷彿とさせます。
Vue.jsのエコシステムのなかでもNuxt.jsは、完成度の高さからVue.jsのサーバーサイドレンダリングのフレームワークとして広く利用されようとしています。
今回は、そんなNuxt.jsを実際のサービスで使うさいに欠かせないライフサイクルの知識について書きたいと思います。といっても、私自身、最近までNuxt.jsのライフサイクルついて十分に理解していたかというと、心もとないところがありました。公式サイトのライフサイクルダイアグラムをみてわかったようなわからないような気になっていたのです。
そのひとつの原因としては、Nxut.jsは、Vue.jsのサーバーサイドレンダリング用のラッパーのようなものなので、それぞれのライフサイクルを頭に入れ「どこからこどまでがサーバーサイドのライフサイクルなのか?」「どこからがクライアントサイドなのか?」を把握しなければならないからでしょう。
今回、曖昧だった疑問を整理し、Vue.jsとNuxt.jsをひとつにつなげたライフサイクルとして図を作成しました。
Nuxt.jsとVue.jsのライフサイクル
早速ですが、下記がライフサイクルの図になります。
nuxtServerInit
nuxtServerInitは、Nuxt.jsのライフサイクルの最初にくるメソッドで、サーバーサイドから直接データをstoreにセットしたいときなどに使います。ログイン認証でセッションIDをstoreに保存したいときはこのメソッドで行います。まだブラウザのwindowオブジェクトにアクセスできないので、localStorageにデータを直接保存することはできません。
middleware
次に、nuxt.config.jsに記述されているmoduleやmiddleware、pluginが呼び出されます。もし、severMiddlewareとしてexpress.jsを使っている場合もここで呼ばれます。 図では省略していますが、クライアントサイドでnuxt-linkをクリックして遷移したときは、ここまで戻って実行されます。
validate
validateは、動的ルーティングしているcomponentsのパラメータをバリデーションします。
asyncData or fetch
asyncDataでは、外部APIからのデータをサーバーサイドレンダリングしたい場合は、ここでaxiosなどを使って取得します。 fetchは、asyncDataとよく似ています。異なるのはfetchは、値をstoreにセットできますがcomponentsに値をセットできない点です。
render
renderでcomponentsがレンダリングされるわけですが、ここはサーバーサイドとクライアントサイドの境界にあり、beforeCreateやcreatedは両方から利用できるメソッドになっています。
クライアントサイド
これから下はクライアントサイドのみの領域になり、Vue.jsのみのライフサイクルに入っていきます。beforeMonuntはVueインスタンスがマウントされる前に呼ばれ、mountedはマウント直後に呼ばれます。DOMにアクセスしたいならここで。
ライフサイクルの重要性
ライフサイクルへの意識が特に必要になるのは、ログイン機能をつけるときでしょう。ユーザー認証のためにtokenを一定期間保持しなければなりませんが、asynDataではまだブラウザのcookieやlocalStrageにはアクセスできません。最初のリクエスト時、nuxtServerInitでtokenをStoreにセットしておくことが必要になるでしょう。 また、DOMを直接触ろうとするなら、クライアントサイドのライフサイクルに入ってからでないと不可能です。
まとめ
Nuxt.jsなら、モダンなフロンエンド開発に欠かせない設定が隠蔽されているので、容易にサーバーサイドレンダリングされたWebアプリが作成できます。 しかし、ログイン機能のような少し複雑な機能を追加しようとすると、途端にライフサイクルやVuexの状態管理の知識が必要になります。 今後、Nuxt.jsが選択されることが増えていくと思われます。Nuxt.jsへの技術的投資は、さらに重要になっていくのではないでしょうか。
アスタミューゼでは、エンジニア・デザイナーを募集中です。ご興味のある方は遠慮なく採用サイトからご応募ください。お待ちしています。