Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
141
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

実際Nuxt.jsとExpressでどうやってSSRやるか理解してましたか?自分はよくわかってなかったです【解説】

最近は、

  • Firebase Cloud Functions(Node v8):バックエンド処理
  • Nuxt.js:JSフレームワーク
  • Firebase Hosting:css, jsファイルなど静的ファイル
  • Cloudinary:画像等メディアファイル

が爆速でWebアプリケーションを開発する最適解だと考えているのですがどうでしょう?

自分が最初Firebase x Nuxt.jsで開発を始めた際、なかなか理解できなかったのが、
Nuxt.jsとExpressがどう繋がっているのかということでした。
Express(Firebase Cloud Functions)で受けて、どうやってNuxt.jsと連携するの? という疑問がなかなか晴れず。

そこで今回は、自分で作ったFirebase x Firebase用vueテンプレートを混ぜ込みつつ解説したいと思います。

ExpressとNuxt.jsの連携

ポイント1. Nuxt.jsはExpressの中でミドルウェア的に使う

Nuxt.jsはExpressの中で、1つのmoduleとして使用します。  
例)https://github.com/taishikato/nuxt-express-firebase-template/blob/master/template/functions/index.js#L2

いままでVue.jsなどでSPAを作るのに慣れていると、フレームワークをモジュールとして使うという発想はなかったかなと思います(自分はなかった)。
この考え方の切替が結構大事かなと思います。

ポイント2. nuxt.renderRoute()でパス毎に処理を分ける

このように書くことでパス毎に、Nuxt.jsのどのPage Componentを出力するか、決定できます。  
ポイントはnuxt.renderRoute()メソッドを使うことです。
nuxt.renderRoute()について、公式ドキュメントには以下のように書いています。

特定のルートをレンダリングします。その際にコンテキストを渡すことができます。

仮に、アプリケーションのURLをhttps://example.com とすると、
例えば以下のように書いた場合、https://example.com にアクセスしたら、Nuxt.jsのpages/top.vueが使用されます。簡単ですね。

app.get('/', (req, res) => {
  nuxt.renderRoute('/top', { req })
  .then(result => {
    res.send(result.html);
  })
  .catch(e => {
    res.send(e);
  });
});

また、第二引数にコンテキストを渡すことができます。

オプション, オブジェクト, 付与するコンテキスト, 利用できるキー: req 及び res

上記の例で、仮にExpressでAPIを実行し、得た情報をNuxt.jsで描画したい場合、以下のように、reqオブジェクトに入れてあげると、

app.get('/', (req, res) => {
  (async () => {
    // axiosでAPIを実行します
    const { data } = await axios.get('https://api.com');
    req.data = data;
    const result = await nuxt.renderRoute('/top', { req });
    res.send(result.html);
  })();
});

Nuxt.jsのasyncDataメソッドで参照することができます

<template>
  <div>
    {{ apiResult }}
  </div>
</template>

<script>
export default {
  asyncData(context) {
    return { apiResult: context.req.data };
  }
}
</script>

図で説明

  1. Firebase Cloud Functionsへリクエスト、Expressが受け取ります
  2. Expressの該当Router内でnuxt.renderRoute()を実行
  3. Nuxt.jsがHTMLを生成して、Expressへ返却
  4. Nuxt.jsから返されたHTMLをExpressがクライアントへsend

Nuxt x Express.png

宣伝

vueテンプレート
:fire: taishikato/nuxt-express-firebase-template
ぜひぜひ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
141
Help us understand the problem. What are the problem?