Vue.jsでUniversalなSPAを開発できるフレームワークであるNuxt.jsのバージョン 1.0のリリースがいよいよ近づいてきました。
本稿では、シングルページアプリケーション(以下 SPA)開発によって生じた問題を解決するために生まれたサーバーサイドレンダリング (以下 SSR)を中心に、Vue.jsでの開発を強力にサポートするNuxtについて、その魅力と基本的な使い方をご紹介いたします。
Nuxt.jsとは?
Nuxt.js(ナクストと読みます)はReact.jsベースのSSR用フレームワークであるNext.jsに触発されて作成された、Vue.jsベースのフレームワークです。
特にUIの描画サポート に主眼をおき、SSRをはじめとした様々なサポートを行ってくれるものとなります。
Nuxt.jsでできること
それではそのNuxt.jsではどのようなことができるのでしょうか。
現在挙げられている主な機能一覧としては以下のようなものがあります。
(現在準備中のv1.0向け日本語訳プロジェクトから抜粋。私も一部関わっております)
- Vueファイルで記述できること
- コードを自動的に分割すること
- サーバーサイドレンダリング
- 非同期データをハンドリングするパワフルなルーティング
- 静的ファイルの配信
- ES6/ES7のトランスパイレーション
- JSとCSSのバンドル及びミニファイ
- Head要素の管理
- 開発モードにおけるホットリローディング
- SASS, LESS, Stylus などのプリプロセッサのサポート
- HTTP/2 push headers ready
- モジュール構造で拡張できること
こうして見てみると、Nuxt.jsが提供する機能は 「SSR 基盤の提供」と「コードを書きやすい環境を提供するもの」 、そして「拡張性の高い構造を提供するもの」 の3つと考えることができます。
SSR基盤としての優秀さ
Vue.jsの2系からはコアでSSRのシステムを内蔵しており、単体でもSSRを行うことは可能ですが、より円滑に、かつ柔軟なシステムをNuxt.jsでは提供しています。
単純なレンダリングだけの場合はVue.jsのものを利用しても簡単におこなうことができますが、Nuxt.jsではそれに加えルールに基づいた自動的なルーティングやプリコンパイル、 <meta>タグの編集などが可能となっており、より効率的なSSR基盤の構築が可能となっています。
モダンなVue.jsによる開発環境の提供
Nuxt.jsでは、vue-loaderベースでのVue.jsでの標準的なコーディング環境や、 画像などのアセットのパスの解決、そしてSassなどのCSSプリプロセッサの対応など、webpackなどのビルドツールの設定を必要とするものが一通りサポートされています。
その上で、それらの基本的な構成をまとめたボイラープレートをnuxt-community/starter-templateとしてNuxt.jsコミュニティが公式で提供しており、webpackなどのモジュールバンドラやbabelなどのビルドシステムに精通していない人でも簡単にモダンな環境を構築することが可能となっています。
また、これらのテンプレートはVue.jsコミュニティ公式のスキャフォールディングツールである vue-cliを利用してセットアップが可能となっており、すぐに開発をはじめることが可能です。
ミドルウェアやasyncDataなどの拡張システムの提供
また、Nuxt.jsでは、ミドルウェアやasyncDataという構造・システムを利用することで、SSR結果に非同期処理(例えばAPIからのデータフェッチ)の結果を出力・その後SPA側からデータストアとして参照できるシステムがあります。
これを利用することにより、記事データを取得した上でOGPとして出力を行うことや、i18n処理の結果をHTMLとして流すなど、様々なことができるようになります。
Nuxt.jsを利用すべきシーン
メディアやSNS 、求人サイトなどをSPAとして立ち上げる場合・運用している場合
SPAとして立ち上げるサイトやWebサービスの中では、SEOやOGP、Twitter Cardを重視すべきものというのは非常に多く存在します。
メディアサイトなどであれば、そもそもWordPressなどで運用するほうが筋が良い場合も多いでしょうが、SNSや求人サイトの場合は、SPAのほうが都合が良い場合も存在します。
SNSでの事例でいえば、今のTwitter Lite(モバイル版)ではReactが使われていたり、求人サービスであるSCOUTERなどはサービス全体をVue.jsのSPAとして構築されており、個々の投稿やアカウントなどの情報をSSRしたいであろうサービスが SPA 化されていることは多くなってきました。
そういった場合のSEO、OGP生成エンジンとして、比較的一般的なディレクトリ構成がなされているNuxt.jsを採用する、Nuxt.jsへと移行するというということは選択肢として十分現実的なものです。
技術系ドキュメントの運営
技術ドキュメントの運用にも有効活用が可能です。
Nuxt.jsには、独自の機能としてnuxt generate
が存在しており、このコマンドを利用すると、Nuxt.jsで作られたものを全て静的サイトとして、ルーティングをそのままに書き出すことが可能となります。
Markdownで原稿は管理を行い、Vue.jsの強力なコンポーネントシステムのもと、デザインを効率的に管理する。ということが可能です。Nuxt.jsの公式ドキュメントは、この手法にて管理されています。
いわゆる一般的なホームページ制作
驚くかもしれませんが、一般的なホームページ制作においてもNuxt.jsは大きく貢献してくれます。
Vue.jsのコンポーネントでは Scoped CSSを利用することが可能となっており、CSSの影響範囲についての考慮を最小限できるためコーディングのスピード化に貢献するほか、ライブリロードなどの効率的な開発基盤が既に整っているからです。
また、本稿では詳しくは紹介しませんが、Nuxt.jsはプログラムから呼び出すことも可能であるため、お問い合わせだけをExpress.jsで受けるということも実現可能です。
実際にPush7というサービスのWebサイトはi18n化をmiddlewareで、メール受け付けをExpressで実装しました。
Nuxt.jsをはじめる
それではいよいよNuxt.jsを利用して実際にアプリケーションを作成してみましょう。
まずはサンプルプロジェクトを作成した後、実際にAPIと連携するWebサイトを構築してみます。
プロジェクトのセットアップと実行
プロジェクトの初期化にはvue-cliを利用しましょう。ターミナル上で以下を実行してください。
1 2 |
$ npm install -g vue-cli # 既に vue-cli を導入されているかたについては不要です $ vue init nuxt-community/starter-template nuxt_sample |
これを行うことで実行したディレクトリに新たにnuxt_sampleという名前でプロジェクトが作成されます。
これで一通りのファイルはセットアップされていますので、そのまま依存関係をインストールしてサーバーを立ち上げてみます。
パッケージ管理については、Nuxt.js自体がYarnで管理されているため、個人的にはYarnを用いることを推奨します。
1 2 3 |
$ cd nuxt_sample $ yarn $ yarn dev |
実行した段階でプリコンパイルが実行され、完了次第 http://localhost:3000 にてアクセスが可能であることが確認できるようになっています。実際にアクセスしてみます。
このように表示された時点で成功です。
ページのソースコードを見ると、きちんとSSRされて結果が出力されていることがわかります。
APIからデータを取得してSSRするページを作成する
基本的なサーバーの起動はここまでで完了したので、ここからはルーティングの追加と非同期データの取得を行っていきます。
ここでは誰でも利用できるPublicなAPIとして、GitHubのユーザー情報を参照する API を利用し、ユーザー情報を表示してみます。要件としては、以下を満たすものの開発とします。
- https://developer.github.com/v3/ を利用したデータ取得を行う
- /users/:id 形式でそれぞれのユーザーにアクセスする
- ユーザー情報からIDと名前を取得し、アイコン画像と共に表示する
ルーティングを追加する
まずはルーティングを追加してみます。
Nuxt.jsにはファイルに応じたルーティングの自動生成機能がありますので、これを有効活用して作成します。
今作ったnuxt_sampleのプロジェクトルート内の pages/ディレクトリ内にusersディレクトリを作成し、さらにその中に _id.vueファイルを作成します。
内容については、index.vueの中身をコピーしておくと良いでしょう。
完成したディレクトリ構成はこのようになります。
このようにファイルを配置することで、Nuxt.jsがルーティングを解釈し、 /users/:idのリクエストについては全て_id.vue を参照するようになります。
さらに、アクセス時にURLパラメータのオブジェクト内にidというキー名で格納されます。
これを例えば_nickname.vueなどとした場合は、idの代わりにnicknameというキーで保存されます。
これでひとまずルーティングの作成は完了です。
ページ内でHTTPリクエストを行い、結果を取得する
次は_id.vueの中でGitHubからデータをフェッチしてみます。
まずはHTTPリクエストのためにaxiosをインストールします。
1 |
$ yarn add axios |
その上で、_id.vueを以下のように記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<template> <section class="container"> <img :src="`https://github.com/${user.login}.png`" :alt="user.name"> <h1>{{user.name}}</h1> </section> </template> <script> import axios from 'axios' export default { async asyncData ({ params }) { const { data: user } = await axios.get(`https://api.github.com/users/${params.id}`) return { user } } } </script> <style> .container { min-height: 100vh; display: flex; justify-content: center; align-items: center; text-align: center; flex-direction: column; } .container img{ margin-bottom: 20px; border-radius: 50%; overflow: hidden; } </style> |
ここでポイントとなるのはasyncDataの記述です。
通常のVue.jsでは、データの保持について、 data(){}形式で関数を定義し、その戻り値をデータとして利用しますが、これを asyncData(){}に置き換えることで、SSR時に非同期のデータを取得した上で、SSRに流し込むことが可能となります。
また、Nuxt.jsではデフォルトでasync/awaitの変換用のbabel-presetも導入されていますので、モダンな記法でこのように取得することが可能となっております。
実際に表示をみてみる
ここまで完了した段階で、実際に表示を見てみましょう。
現在サーバーが立ち上がっているなら自動で読み込まれているためそのまま /users/potato4dを。
もし一度落としているなら、再度
yarn devを行った上で
/users/potato4d
にアクセスしてみましょう。
このように表示されると成功です。
ソースコードを見ると、正しくSSRされた結果が返ってきていることがわかります。
このように、asyncDataと、axiosなどのHTTPライブラリを組み合わせることによって、Web APIからの取得結果をSSRに流すことが可能となります。
これを用いることにより、例えばサービス内の投稿について、ツイートされたときにコンテンツを表示する。Twitter CardやOGPなどを正しく表示する。ということが可能となります。
最後に、このサンプルについては私のGitHub上に掲載しておりますので、お手元にすぐNuxt.jsを試す環境がない場合は適宜ご参照ください。
おわりに
ここまででNuxt.jsの基本とできること・活躍しやすいシーンをご紹介した後に、簡単なサンプルアプリケーションを作るところまでを行ってみました。
実案件で投入する際は、新規でないとディレクトリやビルドシステムの移行コストがそれなりに存在しますが、新規においては効率的な開発にも大きく貢献し、将来的なSSR要望にも先んじて対応を行うことができます。
基本的にSPAの後からのSSR対応というものは非常にコストがかかるものでもありますので、これからのSPA開発においては、Nuxt.jsの存在は、開発効率化ツールとしても、また、SSRだけではない統合開発フレームワークとしても無視できないものになってくると考えております。
Nuxt.js単体がフロントエンド開発のフレームワークとして一定以上の存在意義をもつ未来や、ほかのNode.js製のフレームワークと組み合わせてのレンダリング用フレームワークとして利用される未来も十分にあるでしょう。
近々1.0のリリースが行われることで、rcにて大量にあったBreaking Changesについてもひとまずは収まることが予想されますし、日本語ドキュメントの1.0追従も盛んに行われております。
もし活躍できるシチュエーションに遭遇した時は、Nuxt.jsを是非利用してみると良いでしょう。
参考資料
本稿の執筆にあたって参照した情報ソースとなります。
- Nuxt.js 公式ページ(英語)
- v1.0 時代の機能一覧 日本語訳
- 本稿で使用したスターターテンプレート
- 本稿で使用したスキャフォールディングツール
- Nuxt.js 上での開発における babel の対応文法のソース(設定プリセット)