2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Nuxt.jsの基本2(Nuxt.jsについて)

Last updated at Posted at 2022-05-05

入る前に、

1であるこちらを先に確認して、CSR,SSRについて理解した上で読むことをおすすめします。

Nuxt.jsとは?

vue.jsのフレームワークベースの開発環境の構築に役立つフレームワークである。

フレームワークのためのフレームワークと言うのは難しいかもしれませんが、解いてみると、Vue.jsプロジェクトで使用されるいくつかの有用なライブラリを基本的に搭載しているフレームワークと見ればよい。

Nuxt.jsに含まれる機能は以下の通りになる。

  • Vue 2 (2022/05時点→3は秋ぐらい予定)
  • Vue Router
  • Vuex
  • Vue Server Render
  • vue-meta
  • vue-loader
  • babel-loader
  • webpack

Nuxt.jsの特徴

Vue.js + ライブラリ構造なので、Nuxt.jsは次のような特徴を持ってます。

  • Vue ファイルが使える
  • コード分割の自動化
  • サーバーサイドレンダリング
  • 非同期データ基盤、強いRoutingシステム
  • 静的ファイルの転送
  • ES2015+ サポート
  • js & css コードバンドリング及び圧縮
  • エレメント管理(title, metaなど)
  • 開発時のHot Module管理
  • CSS pre-processor 提供(SASS, LESS, Stylusなど)
  • Pre-Rendering
  • pages ディレクトリを使ったて安いRouting
  • webpackなどを使った簡単な設定

Nuxt.jsはいつ使うのか?

決定的にSEOを改善したいと思う時、

ディレクトリ構成

image.png

  • assets
    • css, image, fontなどのリソースを含まれてる
    • scriptで動作するロジックとは別部分であり、デザイン的に見せるファイルなどが入っている
  • components
    • アプリケーションで使われるコンポネントが入ってる
    • 該当パスで配置あれてるコンポネントはNuxt.jsの非同期関数であるasyncDataまたはfetchは使えない
  • layouts
    • アプリケーション全体に対するレイアウトを含まれてる。
    • 基本的にはdefault.vueが準備されてる。
    • ディレクトリ名変更不可
  • middleware
    • アプリケーションで使うmiddlewareを配置
    • middlewareはページまたは、レイアウトがレンダリングされる前に実行される。
    • middlewareをページや、レイアウトにバインディングしたら、該当ページや、レイアウトが実行されるたびに実行される。
  • node_modules
    • Nuxtフレームワークのメイン機能を拡張、統合、追加できる。
    • ユーザーが直接モジュールを作成できる。
  • pages
    • 実際アプリケーションのページ構成を含まれてる。
    • このディレクトリの構造によって、Routerが自動的に作られる。
    • index.vueとして指定されたファイル名は省略できる。
  • plugins
    • アプリケーションにバインディングされる外部または、内部のプラグインを配置
    • アプリケーションがインスタンス化される前に実行され、Global的な構成要素を登録し、関数または、常数を入れることが可能
  • store
    • アプリケーションで使うvuex storeのファイルを配置
    • 基本的には非活性化状態
    • store ディレクトリにindex.jsフィアルを作成することで、store機能が活性化状態になる。
    • 構成によってモジュール形式のstoreが作成できる
  • content
    • オプション、
    • @nuxt/contet モジュールを使ってアプリケーションを拡張可能
    • markdown, json, yaml, xml, csv などのファイルをInputしたり、管理できる。

Nuxt.jsと、Vue.jsのディレクトリ比較

// Vue.js
npm i -g @vue/cli
vue create <project name>
cd <project name>
vue add vuex
vue add router

// Nuxt.js
npm init nuxt-app <project-name>

image.png

上記のコマンドで作られて2つのPJのディレクトリを比較してみよう。
基本的にVue.jsのPJにはVuexと、Vue Routerを追加した状態で,NuxtではUIFW以外は特に入れたものはない状態である。
Vue.jsではsrcフォルダ配下に入ってる内容が、Nuxt.jsでは全般的にRootレベルとして上がっている。

Vue.jsと、Nuxt.jsが両方とも持ってるディレクトリを線を利用して表示してみた。
Vue.jsのPJではRouter関連ディレクトリがrouter, view があるが、Nuxt.jsでは pages ディレクトリ一つが全部まとめて処理する。
Vue.jsのPJではRouterを設定するにはrouter/index.js で直接Routerの登録が必要だが、Nuxt.jsでは pagesフォルダの構造通りにRouterが自動作成される。

Vue.jsでは見えないmiddleware, layouts, plugins が確認できる。

Nuxt.jsのレンダリングモード

image.png

Nuxt.jsはSingle Page Application (SPA)、Universal Application, Static Applicationをサポートしている。
これは、nuxt.config.jsで、mode Perpertyを使って設定可能である。(mode:'spa', 'universal')

上記のスクショ(公式ドキュメント)上だと、universalについて、Isomorphic application (server-side rendering + client-side navigation)のように説明している。これはどんな意味でしょう

SSRをmodeとして指定する方法はdeprecatedになった。 build : { ssr: true/false} の方法に変えた。

server-side rendering + client-side navigation

これはどんな意味でしょう
これはこの前の記事で話した新しい方法のSSR、要するにUniversal Appの動作方法を意味してる。
過去に、ぺーじを移動するたびに、リフレッシュすることを保管するために新しく登場したレンダリング方法として言える。

最初の画面だけ、過去のサーバーレンダリングように完成されたHTMLを表示され(SSR),今後は、Ajaxを利用して、動的Routingを使って必要なデータのみ持ってこれたらどうだろう(CSN)というアイディアから登場したレンダリング方法である。

test3.png

Universal Appの動作方法は上記のイメージのようになる。
最初のRequestが届いたらサーバーサイドではnuxtServerInit, middleware Validate(), asyncData(), fetch() などのプロセスが動いた後、レンダリングしたイメージをResponseする(各プロセス内容は下で再度説明する。)

  • ここかでが、SSR(Server side Rendering)の部分である。
  • このアツ、nuxt-link タグとしてNavigateがおこなわれるけど、これをCSN(Client−Side Navigation)だという。

CSNについて

CSNは大きく、Pre-fetch + Hydration家庭として動作してる。
Nuxt.jsはUniversalモードで基本的にRequestしたURLを使って、ロードするべきのページだけサーバーでレンダリングしClient側にResponseする。
Requestが行われるたびに、サーバーでレンダリングするのであれば当然リフレッシュが発生し、既存のSSRと同じ状態になる。しかし、Nuxt.jsのUniversalモードではリフレッシュが発生しないのは、Pre-fetchのおかげである。

Pre-fetchはCSN(Client-Side Navigation)の流れの一つである。要するに、Universal Appだけ使える方法ではなく、Vue-CLIのようなSPAでもサポートできる機能で有ること。

Pre-fetch

先にデータを準備する意味。
言葉通りに、レンダリングが必要になる次のページを先に準備しておきこと、
Nuxt.jsはこれをどうわかって準備できるのだろう。

これはNuxt.jsの機能の一つである nuxt-linkを介して行われます。 (Vue Routerの route-linkと同じだと見ることができます。

Nuxt.jsは、最初のサーバーでデータと一緒にHTMLをレンダリングし、それから viewport(画面に表示されるページ)の nuxt-linkから次のページを予測してバックグラウンドでジャンクファイルをダウンロードします。 。

このとき、あらかじめ持ってくるデータの形式は js である。

Nuxt.jsは自動的に code splitting(ファイル容量を減らすためにコードを難難にすること)を適用するので、新しいページをレンダリングしたい時はサーバーに毎回レンダリングしたHTMLを要求する代わりに、ブラウザがレンダリングできるように助けるjsファイルを要求する。

要約すると、ユニバーサルアプリが瞬時にページをロードできる理由は、次のページのデータ .js を事前に取得する(Pre-fetch)ためです。

Hydration

レンダリング過程を終え、ブラウザに渡されたHTMLファイルの上に残ったJavaScriptコードを実行する動作である。

ハイドレーションにより、SSRアプリは既存のSPAと同じ動作と反応性を保証できるようになる。用語そのまま不完全なHTMLファイルという「乾いた土地」にJavaScriptという「水」を振りかけること。

  • Universal Appは、Server Side RenderingとClient Side Navigationプロセスを介して動作する。
  • Server Side Renderingは、私たちが知っているサーバーでHTMLをレンダリングする方法である。
  • Server Side Rendering後、view portのnuxt-linkタグを介して次のページを事前にダウンロードしてくる(Pre-fetch)
  • あらかじめダウンロードしてきたため、リロードせずにページ移動が可能だ。
  • ページ移動後の動作はハイドレーションと呼ばれる。
  • ハイドレーションにより、Universal AppはSPAと同じ動作と反応性を保証できる。

Isomorphic Application

Isomorphicは直訳すると、「同じ構造の」という意味。

通常Isomorphic Javascriptという言葉でよく使われますが、一般的には同型JavaScriptに翻訳します。サーバーとクライアントに同じ言語が使われるという意味で考えればよい。

nuxtServerInit, middleware, validate(), asyncData(), fetch() などの過程を最初の要求では、サーバーサイドで処理するロジックが同じ javascript で作成されたことを意味する。

ここで話すサーバーサイドの サーバー は API を意味するバックエンドサーバーではなく、 Nuxt.js に組み込まれた Express(Node.js) サーバーを言う。 Nuxt.jsはSSRを実装するためのExpressサーバーを内蔵している。

Express(Node.js)サーバーとクライアントが同じようにJavascriptで構成されているため、Isomorphic Javascript / Universal SSRという。

実際にコーディングするときは、そのコードをサーバー/クライアントの両方で実行できることを常に念頭に置いて作業する必要がある。

Static App

Nuxt.jsはUniversal App、SPAに加えてStatic Appをサポートしている。

Static App はすべての page が pre-rendering (プリランダリング) されたビルドを生成し、 server は含まない。つまり、完成した静的HTMLを生成して配布する方式だ。

フリーランダリング
サーバーの介入なしに事前にレンダリングされたすべてのページのHTMLファイルをクライアントに提供する。

Static Appを実装するには、 nuxt.config.jstarget:'static'を追加するだけ

デプロイ時に npm run generate を行うと dist (default) にすべてのページがレンダリングされたビルドが生成される。

しかし、idのようなパラメータを渡してルーティングするページは、パラメータが決まった値ではないため、プリレンダリングされず、urlアクセスが不可能な問題が発生する。

これを解決するためには nuxt.config.jsgenerate property オプションを利用することができる。

たとえば posts というリストページがあり、posts/[id] が詳細ページとする場合

generate: {
    routes: function () {
      return [
        '/posts/id値'
      ]
    }
  },

その id 値を入れて generate してくれれば id 値のフォルダと一緒に index.html が別々に生成されることが分かる。

しかし、すべてのid値をconfigファイルに入れて管理するには無理があり、これはサーバーから値を受け取って設定することができる。

const axios = require('axios'); 

generate: {
    routes: function () {
      return axios.get('http://test.com/posts')
        .then(res => {
            const routes = []
            for (const key in res.data) {
               routes.push('/posts/' + key)
            }
            return routes
        })
    }
  },

Nuxt.jsのLife Cyle

lifecycle.jpeg

何かすごく複雑に見えるイメージだが、上記内容を全て読んできたら理解しやすい。

まず、真ん中に描かれた線を見てみましょう。
中線を基準に、上側はVueコンポーネントができる前、下はその後になる。
もっと簡単に言えば、上はServer Side、下はClient Sideです。

Vue Componentが発生する前に、Server Sideでページがレンダリングされる前にすべきことを行います。
当然のことですが、サーバーサイドではVue Componentがまだ生成される前であるため、thisを使用することはできません。

前述のmiddlewarevalidate()asyncData() を実行します。

まとめ

今回は、Nuxt.jsと、Vue.jsのディレクトリの比較、各ディレクトリの役割、レンダリング、LifeCycleについて書いてみました。
最近、Nuxtのバージョンは2.15以上、Vueは3バージョンが、Currentになりましたので、内容が少し古いかもしれませんが、そこまで大きい差分は発生してないし、バージョンによって大きいな動作の異なりはないと思います。
そしてこのような背景を身についているのであれば、今後の新しいバージョンにも早速対応できると思います。

次の記事では、簡単な使い方として、Routingと、Vuexの動作方法、非同期データ扱い方法などについて整理してみようと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?