【メモ】Vue.jsでサーバサイドレンダリングを最小限に行う

公式のVue.jsサイトのデモにあるHackerNewsクローンをコードリーディングする前段階として、公式のVue SSR ガイドに掲載されている最小限のSSRを試したのでメモ。

const Vue = require('vue')
const server = require('express')()
const renderer = require('vue-server-renderer').createRenderer()

server.get('*', (req, res) => {
  const app = new Vue({
    data: {
      url: req.url
    },
    template: `<div>The visited URL is: {{ url }}</div>`
  })

  renderer.renderToString(app, (err, html) => {{
    if (err) {
      res.status(500).end('internal server error')
    }
    res.end(`
      <!DOCTYPE html>
      <html lang="ja">
      <head>
        <title>hello</title>
      </head>
      <body>
        ${html}
      </body>
    `)
  }})
})

server.listen(8080)

server.get()

第1引数に、URLのパターンマッチングを渡し、マッチするURLでHTTPリクエストを受け取ると第2引数のコールバックが実行されます。今回はアスタリスクなので、全てのURLでマッチします。
第2引数のコールバックにはRequest、Responseオブジェクトが渡されます。

RequestオブジェクトはHTTPリクエスト関連の情報を取得できますが、中にはNodeのhttp module等から引き継いでいるプロパティ等もあるそうです。 Responseオブジェクトも同様です。

APIリファレンスを見ると、Requestは読み取り系のプロパティが豊富ですが、Responseはこれからクライアントへ送信する情報を決定するため、HTTPレスポンスを編集するメソッドが豊富なイメージです。

renderer.renderToString()

第一引数に渡したVueのインスタンスを内部でレンダリングし、静的な文字列を生成しています。 このメソッドによって初期表示のHTMLが生成されているようです。
生成された文字列は第二引数のコールバックに渡されます。

このdemoではVueのインスタンスを文字列に変換していましたが、ストリームでの対応もしているようです。 HTMLをチャンク単位で破片毎に生成するということだと思いますが、個人的には今は出番は無さそうです。

res.end()

レスポンスの処理が終了した際に呼び出します。 HTTPレスポンスのボディになるデータを引数で渡します。

server.listen()

HTTPサーバーの待ち受けを開始します。 引数には使用するポートを指定します。