トップ «前の日記(2018-05-02) 最新 次の日記(2018-05-06)» 編集

2018-05-03 [長年日記]

_ Vue.js x SSRメモ

これ読め。

Introduction · GitBook

Nuxt をちょっと使った程度で気になったところだけを抜粋。

まず prerender を検討せよ

SSR は考えることが増えるので prerender をお勧めされる。

vue-server-renderer

vue-server-renderer が String を生成してくれる。

express などサーバサイドのフレームワーク上で Vue component を利用してページ生成することができる。

VM Life Cycle が異なる

Server Side では data reactivity は不要であり、VM life cycle は以下の 2つしかない。

  • beforeCreate
  • created

だから created() で store の registerModule を route に応じて行う Nuxtでrouteに応じてVuex Storeをmodule分割する方法 - あーありがち(2018-04-19) コードを試した時に訳の分からない動きをしたのか。

custom directive は要注意

  • 多くは生DOMに依存するので動かない
  • <no-ssr> で回避できる

Nuxtegoist/vue-no-ssr: Vue component to wrap non SSR friendly components (428 bytes) で利用できる。

自分で実装する際には custom directive ではなく component にして VirtualDOM にする方法を選択すべし。

stateful な singleton を排除

サーバサイドの Node.js プロセスは長寿命であり、Vue のレベルで singleton を作ってしまうと複数のリクエストで状態が share されてしまう。

routing を vue-router に

サーバサイドフレームワークの routing を素通しにして vue-router で routing を行うことで client-side と同じ動きにできる。

サーバサイドでの dynamic component の lazy loading は危険

const Page = () => import('Page.vue')

みたいなやつ。

以前試したのだが、2つ問題があった。

一つはサーバサイドで実現するには描画開始前に非同期コンポーネントを先に解決する必要があり、これが Nuxtでrouteに応じてVuex Storeをmodule分割する方法 - あーありがち(2018-04-19) の registerModule と矛盾していた。

もう一つは route レベルでない場合は単純に難しいということ。

cf. ルーティングとコード分割 &#183; GitBook

Nuxt で route が解決されたあとに Page component レベルで dynamic component を使って route を偽装しようとするのは可能だが、問題が複雑すぎた。

Nuxt に頼らず自前で router を直接記述しつつ Vue + SSR を実現できるならイケたかもしれないが、Page component を利用しつつ routing を差し替えるには、実は routes を直接書き換えてしまえばよいことが分かっているので、今さらわざわざこの方法を採用する必要もないだろう。

JavaScriptでRubyのArray#replaceのようなことをしたい - あーありがち(2018-04-26)

nuxt.config.js の

router: {
  extendRoutes(routes, resolve) { // <- この routes ね

store と asyncData

サーバサイドでも生かすには root component の asyncData を使う。 こうすることで route から特定の処理を挟んで store に落としてこれをクライアントサイドで利用することができる。

root component の asyncData 内で store.registerModule する方法もあるが、その場合は destroyed で解放しておかないとクライアントサイドで二重に register しようとして壊れる。

ただそもそも data reactivity を component をまたいで実現しつつ persisted にしたい(要は store を localStorage などに保存したい)とかいう場合はサーバサイドで動く意味がなく、asyncData の利用は検討外と言ってよいだろう。

個人的まとめ

今回最後の store 辺りで散々苦しんだが、理屈は分かっていなかったが、動作から逆に導いて結果として正しい選択をすることはできたみたいだ。

Vue.js の SSR について理解しないままなんかできるっぽいよという理由で Nuxt で書き始めてハマって分かったことは、SSR 固有のエラーかどうかはログを見ても知識がないとさっぱり分からないということ。

ということで自分でゼロから書かなくても公式の SSR のドキュメントは読んでおこう、という当たり前の話に戻ってきました。おしまい。