Nuxt.jsについて

今回の目的

Nuxt.jsとはどんなもので、何が出来るかを理解していただき、 今後使用するきっかけ作りになればいいかと思います。

Nuxt.jsとは

Vue.jsアプリケーションを作成するフレームワークです。 アプリケーションを作るための最低限の機能やそれを実現するためのモジュール群を予め用意してくれるため、環境構築に手間をかけずに開発を始められます。

例えば、ルーティング機能をVue.jsで使用するにはVue-Routerを使用します。 通常なら、設定用のjsファイルを手動で用意するのですが、Nuxt.jsの場合は既に設定されており、 該当のディレクト(pageディレクトリ。詳しくは後述します)にファイルを作るだけで勝手にルーティングの設定が行われます。

Nuxt.jsで出来ること

サーバーサイドレンダリング(SSR)

個人的に一番の使用理由だと思います。 通常javascriptでAPIでデータを取得してVue.jsでレンダリングすると、クライアントサイドでのレンダリングになります。 その場合、問題になってくるのでSEOやSNSのOGP関連です。(クローラーやsns側がAPIのデータを取得出来ず、うまく表示されない)

Nuxt.jsではVue Server Rendererの機能を使い、SSRを実現できるようにしています。 初期描画はサーバーサイドで行います。(PHPなどで作られる通常のwebサイトと同じ) その後のサイト内遷移に関してはSPAと同じようにVue-Routerを使ってページを切り替えます(高速!!)

また、サーバーサイドとクライアントサイドの実装を同じコードで実現できるのも一つの特徴です。

ルーティング機能

前途しましたが、Nuxt.jsではVue-Routerを使ったルーティング機能がデフォルトで用意されています。 Pageという特殊なディレクトリが用意されていて、その中に任意のvueファイルを作成するとそのページが自動で出来上がり、ルーティング設定も行われます。

ビルド機能

Nuxt.jsでは基本的なビルド機能が備わっています。ES6/ES7のトランスパイルやミニファイなど、webpackの設定を手動で行わなくても出来るようになっています。(webpackはNuxt.jsのフレームワーク内部で使用されている)

また、sass-loaderなどのローダーは必要に応じてインストールするだけで自動で使えるようになり、さらにオプションの拡張もconfigファイル(nuxt.config.js)から行えるようになっていて、柔軟な構造になっています。

開発サーバー

開発時のローカルサーバーも組み込まれています。 ホットリローディングにも対応しているため、コードを変更したらすぐにブラウザに反映されます。

静的化

SSRでなく、予めHTMLを生成することも可能です。 そのため、動的なHTMLの生成が必要としない場合でも、静的サイトとして作ることができます。

その他

その他にも便利な機能が備わっているので詳しくはこちらを確認してください。 主な機能

Nuxt.jsの使い所

Vue.jsを使った中・大規模開発

Vue.jsを使った中・大規模は開発を行う際は、おすすめです。前途したようにWebアプリケーションに必要な機能は予め用意されています。 また、フレームワークであるため、どのディレクトリにどのファイルを入れるかなどある程度ルールが決まっているため、それに沿って作ることで ファイル構成の一貫性が保ちやすくなります。

SEOが重視されるサイト

APIでデータを取得しVue.jsでレンダリングを行うサイトで、SEO対策も必要となるサイトはNuxt.jsのSSR機能を使って開発することをおすすめします。 SEOだけでなくOGPの内容も事前にサーバーサイドで用意すること出来るので、SNS側も正しい情報を取得できます。

逆にいうと、SEOやOGPの対応が必要ない場合(管理画面など)は無理に入れずにvue-cliを使って開発しても良いと思います。(もしくはNuxt.jsのSPAモード)

Nuxt.jsを使う上で気をつけること

SSRでのサーバー負荷

SSRは、サーバーに負荷がかかりやすい処理と言われています。トラフィックが多く見込まれる場合はサーバーでのキャッシュ対策などの対応が必要になります。

実行環境にNode.jsが必要

Nuxt.jsでSSRを行うには、サーバーにNode.jsの環境が必要になります。AWSやGCPなどのクラウドサーバーにはNode.jsの環境が整っていますが、レンタルサーバーなど安価なサーバーには備わってないことがあります。 実際にアプリケーションを動かす環境を事前に確認して使用する必要があります。(Nuxt.jsを使って静的にHTMLを生成する場合は、こちらに当てはまりません。)

インストール

今回は公式サイトに掲載されているcreate-nuxt-appを使ったインストールを行います。

Nuxt.js クイックインストール


$ npx create-nuxt-app <project-name>

<project-name>は任意の名前を指定します。

インストールが始まると対話式でいくつか聞かれます。


? Project name (project-name) #プロジェクト名
? Project description (My great Nuxt.js project) #プロジェクト詳細
? Use a custom server framework (Use arrow keys) #サーバーサイドのフレームワーク 今回は none
? Choose features to install # 必要なモジュールをインストールします 今回は何も選ばない
? Use a custom UI framework # UI フレームワークを選びます 今回は none
? Use a custom test framework # unitテストのツールを選びます 今回は none
? Choose rendering mode # レンダリングモードを選びます 今回は Universal
? Author name # ユーザー名
? Choose a package manager # パッケージマネージャーを選択します 今回は npm

上記を選択していくとインストールが開始されます。 npm installも同時に行ってくれます。

下記コマンドで、アプリを起動できます。


$ cd <project-name>

$ npm run dev

http://localhost:3000でアプリケーションにアクセスできます。

※ スクラッチでインストール、環境設定を行うこともできます。 スクラッチでインストール

ファイル・ディレクトリ構造

create-nuxt-appを使ってインストールするとデフォルトでファイルやディレクトリが用意されています。 それぞれ役割が分かれているので、幾つかのファイル・ディレクトリについて説明します。

nuxt.config.js

Nuxt.jsの設定ファイルになります。Nuxt.jsが予め用意している設定を変更・拡張したい場合にこちらのファイルを変更します。 configファイルの中身はオブジェクトが書かれたjsファイルで、各種プロパティに対して設定を行っていきます。

nuxt.config.jsプロパティ一覧

例えば、webpackの設定を拡張したい場合には、buildプロパティ設定を追加します。
同じように、独自の環境変数を追加したい場合は、envプロパティに変数を追加します。

このように、アプリケーションに関数設定は、nuxt.config.jsファイルに集約します。

pagesディレクトリ

各ページとなる*.vueファイルを入れるディレクトリです。
(HTMLでいうと、index.htmlとかlist.htmlとかdetail.htmlなど、実際のページとなるファイルです)

このディレクトリに入れたファイルは自動的にVue-Routerによってルーティング設定されます。 そのため、開発者が手動でルーティング設定を行う必要がありません。

静的なルーティングだけでなく、動的なルーティング(記事ページでpost/[id]みたいにidが動的に変わるページなど)の生成も行えます。

componentsディレクトリ

Vue.jsのコンポーネントファイルを入れます。
pagesディレクトリに入れたファイルから呼ばれるVueコンポーネント全てをこのディレクトリに集約します。

layoutsディレクトリ

アプリケーション全体のレイアウトを構成する*.vueファイルを入れます。

レイアウトファイルに、アプリケーション全体で使われるヘッターやフッターなどを書いておくことでアプリケーション全体で統一したデザインを作れます。

また、レイアウトファイルは複数作れるので、ページごとにレイアウトの変更も可能です。

assets ディレクトリ

scss、js、画像などビルド前のファイルを格納します。 グローバルなcssやjsはこちらのディレクトリに入れると良いです。

その他

Nuxt.jsディレクトリ構造

ページを追加してみよう

ページを追加するには、pagesディレクトリに*.vueファイルを追加します。

pages/index.vueファイルをコピーして、名前をdetail.vueとしましょう。

そして、detail.vueのh1タグのテキストを変換します。

<h1 class="title">
    project-name
</h1>

<!-- 下に変更↓↓↓↓ -->

<h1 class="title">
    detail
</h1>

出来たら、http://localhost:3000/detailにアクセスします。

pages/*.vueファイルで使えるメソッド

pagesディレクトリ内の*.vueファイルでは、通常のVueメソッド以外にも使えるメソッドあります。 SSRを行う上で必要になってくるメソッドが幾つかあるので紹介します。

asyncDataメソッド

サーバーサイドでAPIからデータを取得して、コンポーネントのdataとしてセットしたい場合に使います。 asyncDataメソッド内でデータを取得することができるので、SEOやOGPの設定に有効です。

また、サーバーサイドでの実行は初回描画のみで、Vue-Routerを使ってページを遷移した場合はクライアントサイドで実行されます。
(サーバー・クライアントサイド、両方同じコードで実行できる)

ログを出してみよう

pages/detail.vueファイルのasyncDataメソッドを使ってログを出してみましょう。


export default {
  asyncData() {
    console.log('called asyncData')
  },
}

asyncDataメソッド内でconsole.logでログをだす単純なプログラムを用意します。

一度、devサーバーを停止し、再度起動します。

http://localhost:3000/detailにアクセスすると、 ターミナルにcalled asyncDataと表示されます。

このことから、ブラウザ側で実行されたのでなく、サーバー側で実行されたのがわかります。

次に、クライアントサイドでログを出してみましょう。
Vue-Routerを使ってhttp://localhost:3000/detailにアクセスすることで、 ブラウザでログを確認できます。

まず、pages/index.vueファイルにdetailページへのリンクを設置します。

<!-- 22行目に追加 -->
<nuxt-link to="detail" class="button--grey">detail</nuxt-link>

nuxt-linkタグは、Vue-Routerを使ったリンクの書き方です。to属性にはページの名前を指定します。(今回はdeital)

http://localhost:3000/にアクセスします。そして、先ほど追加したボタンをクリックします。 そうするとページが遷移し、ブラウザのconsoleにcalled asyncDataが表示されます。

これにより、asyncDataメソッドの処理は初期アクセスはサーバーサイド、それ以降のページ内遷移はクライアントサイドで実行されていることがわかると思います。

データを設定する

asyncDataメソッドでは、APIなどで取得したデータをVueコンポーネントのデータに設定することができます。

一旦APIは使わずに、静的なデータを設定してみましょう。

コンポーネントにデータをセットする場合は、asyncDataメソッドの戻り値にオブジェクトを指定します。

オブジェクトのkeyが各データ名、valueがデータ値になります。

実際に設定してみましょう。

<template>
  <div>
    {{newData}}
  </div>
</template>

<script>
export default {
  asyncData() {
    return {
      newData: 'set data from asyncData'
    }
  },
}
<script>

今回は、newDataというデータを用意するため、戻り値のオブジェクトにkeyにnewDataを用意して、値をset data from asyncDataにしています。 そして、テンプレート側に{{newData}}と記述することで、ブラウザ上でset data from asyncDataが表示されます。

これは次のコードに置き換えることができます。

<template>
  <div>
    {{newData}}
  </div>
</template>

<script>
export default {
  data() {
    return {
      newData: 'set data from asyncData'
    }
  }
}
<script>

違うのは、asyncDataの場合はサーバーサイドであらかじめデータをセット出来るということです。 これはSEOやOGPの設定に有効に働きます。

APIからデータを取得してみる

今度はAPI経由でJSONを取得し、コンポーネントのデータに反映しましょう。

API通信するHTTPクライアントはaxiosを使います。(create-nuxt-appの設定で、既にインストール済みです)

APIは以前使用したjson-serverを使いましょう。

リポジトリ: https://github.com/du-masa/json-server
json-server使い方: https://study-frontend.netlify.com/jsonServer

リポジトリが用意できたら、APIサーバーを立てましょう。

$ npm i 
$ npm run api-server

立ち上がったら、今回はhttp://localhost:3030/postsというエンドポイントを使ってJSONを取得しましょう。

pages/detail.vueの中身を下記のにします。

<template>
  <div>
    {{posts}}
  </div>
</template>

<script>
import axios from 'axios' 
export default {
  asyncData() {
    return axios.get('http://localhost:3030/posts')
    .then((res) => {
      return {
        posts: res.data
      }
    })
  }
}
<script>

APIで取得したデータを、postsというデータ名で用意してコンポーネントで使用できるようにしてます。 ブラウザでアクセスして、http://localhost:3030/postsのJSONの中身が表示されればOKです。

headメソッド

headメソッドは、htmlのheadタグの記述を設定できます。 通常のSPAだとheadタグの中身をjsで切り替えただけでは、クローラーなどにうまく認識されません。 headメソッド使ってheadタグの中身を設定することで、事前にサーバーサイドでレンダリングしてくれます。

例えば、titleタグの内容を設定するには下記のようにします。

<script>
import axios from 'axios' 
export default {
  head() {
    return {
      title: '詳細ページです',
    }
  }
}
<script>

headメソッドの戻り値をオブジェクトにして、keyにtitle、valueに実際に表示するタイトルのテキストを指定します。

metaタグは複数存在するので、配列を指定して、metaタグごとの属性情報を指定したオブジェクトを格納します。

<script>
import axios from 'axios' 
export default {
  head() {
    return {
      title: '詳細ページです',
      meta: [
        { name: 'description', content: 'ディスクリプションディスクリプションディスクリプション' },
      ]
    }
  }
}
<script>

上記は、metaタグのdescriptionを指定してます。

APIから取得したデータをheadタグの中身に埋め込む

asyncDataメソッドを使ってAPIから取得したデータはheadメソッド内で使用できます。

http://localhost:3030/posts/1にアクセスすると、一つの記事情報が取得できます。 これを使って記事のタイトルをtitleタグの中身に設定してみましょう。

<script>
import axios from 'axios' 
export default {
  asyncData() {
    return axios.get('http://localhost:3030/posts/1')
    .then((res) => {
      return {
        post: res.data
      }
    })
  },
  head() {
    return {
      title: this.post,
      meta: [
        { name: 'description', content: 'ディスクリプションディスクリプションディスクリプション' },
      ]
    }
  }
}
<script>

その他

headメソッドはvue-headというモジュールを内部で利用しています。
titlemetaタグ以外にもheadタグ内で使用するタグの指定方法が載っていますので、参考にしてみてください。

参考文献

results matching ""

    No results matching ""