Web サイト制作にこそ Nuxt.js がベストマッチである理由

業務委託でSCOUTERのフロントエンド周りの開発をお手伝いしている、 花谷拓磨(id:potato4d) です。

SCOUTER は、先日自社のコーポレートサイトを Nuxt.js + WP REST API 構成にてリニューアルいたしました。

普段であれば SPA や SSR が必要な高度なアプリケーションなど、主にWebアプリケーション開発の文脈で語られる事が多い Nuxt.js ですが、何故Webサイトであえて Nuxt.js を採用したのか、そしてそのメリットから、実際に利用しての課題点まで、制作を担当した私自ら知見を存分にご紹介したいと思います。

新しいコーポレートサイトのご紹介

f:id:potato4d:20180315110402p:plain

まずは何はともあれ成果物から。

今回のコーポレートサイトでは、 Vue がアニメーションと親和性が高いこともあり、ブランディングサイトとして十分な価値を示せるようにリッチに仕上げました。Webサイトとしての Nuxt.js がどのように動くかも含めて、よろしければ是非一度ごアクセスください。

corp.scouter.co.jp

技術構成

f:id:potato4d:20180315112001p:plain

Nuxt.js 本体のご紹介に移る前に、技術構成もご紹介しておきます。 既にあるサーバーを流用しているので、 EC2 インスタンス上に NGINX と WordPress が載っているところからスタート。 現在利用している技術は以下となっています(前段にNGINXは別途立っています)。

基本的にはほぼすべてを Nuxt.js で賄っていますが、古いコーポレートサイトのお知らせやプレスリリースを WordPress で管理してています。 今後もビジネスメンバーが使いやすいように CMS として WordPress をそのまま残しながらも、開発自体は WP REST API を利用して API 経由で記事情報を取得し、コストをかけずに運用できる形としました。

Express はエッジ利用しており、お問い合わせやエントリーなどの細かなバックエンド API の受け皿としてピンポイントで使われています。

Nuxt.js でWebサイトを作るとなると、大抵の場合お問い合わせのために Express を挟むか AWS Lambda を挟んで generate で静的サイトとしてホストするかの二択になるでしょう。今回は記事ソースが WordPress であり、 SSR は必須のため、 Express としました。

何故 Nuxt.js を採用したのか?

f:id:potato4d:20180315110458p:plain

冒頭でも書きましたが、 Nuxt.js といえばやはりWebアプリケーション、 SPA での開発のフレームワークと思われがちです。

しかしながら、今回はWebサイト制作です。一件オーバーエンジニアリングに見える技術採用ですが、実は全くそんなことはなく、 Nuxt.js を利用することで非常に高い生産性のもとにWebサイトを作ることが可能 です。

以下に、主な採用利用をご紹介します。

コンポーネント指向の恩恵を受けながら、Vue の資産のもと SEO に強い Web サイト構築基盤の活用

やはり何より大きいモチベーションは コンポーネント指向及びモダン JavaScript 文化のもとに Webサイト を構築できる というところにあります。

SCOUTER は主にWebサービスの会社ということもあって、 Web制作の鉄板である ejs や Pug などのテンプレートエンジンと、Sass + 設計パターン(SMACSS や FLOCSS)での開発ということは滅多にありません。 それだけでなく、もはや前述のようなスタックでの、いわゆる従来の「Web制作」まわりのスキルは、 Web サービス開発者視点では、時代から取り残されつつあるものとなっています。

また、 SCOUTER の場合は、コンポーネント指向を中心に据えるために Vue を幅広く使っており、 jQuery によるダーティなアニメーションの実装を行う機会は殆どないため、できれば Vue のアニメーションなどをフル活用したいところです。

しかしながら、 Web サイトとなると SEO, OGP 都合でモダン JavaScript フレームワークは使えないことが多いのは世の常。いくら Google が読んでくれようと、いくら世の中のクローラーが進化しようと、効果の高い TwitterFacebook がきちんと対応してくれるまでどうしようもないですし、 Google ですら、非同期な JavaScript は読んでくれない始末です。

そんな中、 SEO friendly なままに Vue の記法やコンポーネント指向を流用できる Nuxt.js は、まさにWeb制作と救世主となりえる技術でした。 コンポーネントで部品を組み合わせることで今後のエントリー種別の増加なども容易ですし、コードもDOMを直接書き換えないため非常にわかりやすいように仕上げることができます。

Scoped CSS による手軽で破綻しづらいCSS管理

f:id:potato4d:20180315110833p:plain

次の大きな要因として、Scoped CSS の存在が挙げられます。 Scoped CSS とは、Vue コンポーネント内で、そのコンポーネント限定の閉じた CSS を適用できる機能であり、 全てを Scoped で書いてしまうと、基本的に意図しない範囲に CSS があたってしまって壊れるということを避けらる という大きなメリットがあります。

勿論、コードベースが大きくなればなるほど、 Scoped であっても管理をうまくやっていく必要はありますが、こと Web サイトに限ってはそこまで肥大化しないことから、気軽にコンポーネントを切って、 CSS の設計に頭を悩ませる必要なく記述が可能となり、簡単にスコープ内に閉じ込められる強力さがダイレクトに効いてきます。

Node.js 製フレームワークとの親和性

最後に、 Node.js のフレームワークとの親和性が挙げられます。昔のようにレンタルサーバーで PHP が動いていた時代から変わったこともあり、お問い合わせをどのように実装するかは Web サイトの悩みどころの一つです。

静的サイトの場合はロジックをもたせることができないので、サーバーレス的に Lambda で解決する方法もありますが、 Nuxt.js の場合は SSR サーバーが他のNodeフレームワークと連携しやすいという特徴があるので、気軽に機能拡張を Express で行うことができます。

Express と親和性が高いと、特定の処理が差し込みやすくなるので、 SSR サーバーが薄く作られていて他の技術と組み合わせやすいのは大きなアドバンテージとなります。

以上のような理由から、 Nuxt.js の採用に至りました。

Nuxt.js を採用した結果について

そうして実装が進み、完成後の成果物の結果、以下のような良いことがありました。

CMSの手軽さを残したままフロントエンドエンジニアが管理しやすいシステムになった

先述の通り、これまでのコーポレートサイトは WordPress で管理されており、かつデザインの為に様々なプラグインが使われていました。サービスローンチ当初に作られたということもあり、場当たり的なプラグインが多く、フロントエンド・サーバーサイドのエンジニアともになかなか触りがたい独自知識の領域が生まれてしまっていました。

そこを今回のリニューアルによって Nuxt.js へと置き換えたことにより、社内で十分使われている Vue(and Nuxt.js)を利用した環境となり、以前より圧倒的にコードを管理できる人間が増えました。また、開発側は管理がしやすくなっていながらも、 WP REST API という形での WordPress の続投により、非エンジニアにとってはいつもの管理画面を引き続き利用でき、大きな体験の変更なくコンテンツの運用が可能な状態となっています。

ロジックの追加拡張や要素の追加で破綻しづらいWebサイトが完成した

また、技術面でのメンテナビリティの向上も挙げられます。

SPA 、特に Vue の技術を使わないでWebサイトを作った場合、 DOM の直接的な変更や jQuery プラグインCSS 設計などで段々と拡充のコストが大きくなっていきます。 しかしながら、今回は全て Vue で書かれていることにより、見た目の更新もしやすく、また、一部に Vuex を利用することで機能面にも幅を持たせておくことができています。

課題点

一方で、割りと入り組んだ使い方をしているので幾つか課題があります。

特に WP REST API との連携によるものですが、これについて WordPress に限った話ではなく、情報リソースを外部にもたせている場合は等しく起きるでしょう。

Web サイトにおける SSR 内での API 連携のレイテンシ

おおよその場合何よりもネックになるのはここかと思います。

普通であればWebサイトの1ページを読むのに必要なHTTPリクエストは一回であり、他のアセットに関してページの読み込みと同時に多数のHTTPリクエストが走る形となりますが、 SSR 内で API を叩く場合はこの内部での API へのリクエストが一回余分に発生します。

クライアントから SSR サーバーへ、 SSR サーバーから WordPress へとリクエストを送り、その上でデータを返却してきますが、 SSR の結果がでるまでクライアントは他のアセットを読み込むことはありません。 どうあがいても、この段階で最低でも数十〜数百msのレイテンシが挟まってしまうのは課題でしょう。とくに、 WordPress の場合、カテゴリなどの重いデータ取得がある場合は将来的に秒単位で待つことになることも考えると、キャッシュエンジンなどを有効活用するべきでしょう。

また、そもそも WordPress などのように開発陣以外も触ることができるシステムが必要でなければ、 Nuxtentを利用して静的サイトとして Markdown ベースで管理する。といった方法が最も賢い選択であると思います。

WP API の認証付き API の取り扱い

また、 WordPress のような CMS の場合、下書きという概念がついてくるのも厄介です。記事情報の API は Headless なのでプレビューはできれば本番サイトでみたい反面、一般ユーザーには勿論見えては困ります。こうした場合の認証をどうするか。という問題が常に存在します。

この解決は、基本的に以下のどちらかをとることになりますが、どちらをとっても大差はないため、よりメンテナンスしやすいほうをとると良いでしょう。

  • Express などで専用の認証付きルーティングを作成し、そこで Cookie を付与した上で、特定の Cookie を所持している場合、CMS API の Authrization ヘッダーに Cookie の Credential を追加する
  • CMS の管理画面で Cookie を付与した上で、特定の Cookie の場合は CMS API の Authrization ヘッダーに Cookie の Credential を追加する

LocalStorage や IndexedDB では SSR 側に情報を渡すことはできないので、少々泥臭いですがここでは Cookie を使うのがおすすめです。

おわりに

SCOUTERでは、バックエンドはモダンな Laravel であることは勿論、フロントエンドも多くの領域で Nuxt.js が使われており、他にはない新鮮な環境でのフロントエンド開発を行うことが可能できます。もし Nuxt.js を使ったフロントエンド開発に興味があるかたは、是非以下の新コーポーレートサイトへのリンクよりご応募ください!

corp.scouter.co.jp

また、今月末に SCOUTER 主催で Nuxt Meetup が開催されるとのことですので、こちらもよろしければどうぞ!

nuxt-meetup.connpass.com