DeNAのデザイン戦略室が主催するイベント「Frontend de KANPAI!」に菅沼がLTで登壇致します。
フロントエンドに関わる人の情報交換と交流を目的としているイベントで、お酒とおつまみの提供もあるので興味のある方は気軽にご参加ください!
制作過程における躓きや気付きのメモ
DeNAのデザイン戦略室が主催するイベント「Frontend de KANPAI!」に菅沼がLTで登壇致します。
フロントエンドに関わる人の情報交換と交流を目的としているイベントで、お酒とおつまみの提供もあるので興味のある方は気軽にご参加ください!
Nuxt.jsでは、外部サーバ等から非同期でデータを取得・表示する場合にも asyncData
を使ってあげることでクライアントサイドはもちろん、サーバサイドでもデータを取得し、HTMLで出力することが出来ます。
SSRできる本番環境があれば何の問題もないのですが、SSRせずプリレンダリングのみで運用する場合には、 asyncData
は静的ファイルをgenerateした時点でしか走っておらず、ページロード時にデータが更新されていない問題が起こり得ます。
例えばコーポレートサイト等で、別のサーバにWordPressが設置してあり、トップページのお知らせとしてWordPressから記事を取得するような場合を想定すると、こんな感じで作ってあげることで解決できます
// 非同期でデータを取ってくる関数
async function getPostData() {
return { data } = await axios.get('https://blog.example.com/wp-json/wp/v2/posts');
}
export default {
async asyncData(context) {
const obj = {};
if (context.isServer) { // asyncDataするのはサーバサイド(プリレンダリング時)のみ
obj.posts = await getPostData();
}
return obj;
},
async created() {
if (!this.$isServer) { // クライアントサイドはここで更新をかける
this.posts = await getPostData();
}
},
};
要は asyncData
を使うのはサーバサイド(プリレンダリング時)のみ。
クライアントサイドでは created
でデータの更新をかけてあげるわけです。
こうすることでプリレンダリング運用でも、一応(少し古いかもしれないけど)非同期データのHTMLもプリレンダリングされていて、ブラウザで訪れた際にはちゃんと最新の情報に更新されます。
node製サイトを開発時はwebpackを利用していればwebpack-dev-server
などを利用するのが常ですが、プロダクションビルド後のファイルで確認したい場合もあります。
そういうときにわざわざサーバーにアップロードしたり、MAMPなどを利用するのは面倒です。ですが、PhpStormであればビルドも含めてショートカット1発でサーバーを起動することができます!
今日はその設定をしていきましょう。設定は1分で終わります。
「Run」->「Edit Configurations」から「Run/Dubug Configurations」のウィンドウを表示し下記に設定します。
HostとPortは他のアプリケーションが利用中だと起動できないので、webpack-dev-server
やMAMPなどを利用している場合は被らないように設定するのが吉です。
次に「Before launch: Acvtive tool window」で「+」をクリックして「Run npm script」をクリックします。
すると「NPM Script」のウィンドウが開くので下記に設定します。
あとは^ R
または「Run」->「Run 'Preview server'(上記のName:で設定した名前)」をクリックすれば指定したHostとPortでサーバーが起動します。
PhpStormなどJetBrains製のIDEはWeb関係の技術と親和性が高いので、Web開発者は必携ですね。
Nuxt.jsを含めて、Vue.jsの2.xを使ってSSR(サーバーサイドレンダリング)をする場合に、 v-for
の箇所で下記のようなエラーが出る場合がある。
The client-side rendered virtual DOM tree is not matching server-rendered content.
再現したコードはこれ( items
は単純な文字列の配列)。
ちなみにVue.jsのバージョンは 2.2.6
<template v-for="item in items">
{{ item }}
</template>
回避するには、下記のように個々を要素で囲ってあげる。
<template v-for="item in items">
<span>{{ item }}</span>
</template>
クライアントサイドのみではエラーは出ず、ちゃんとレンダリングされるので、サーバ側の実行ロジックにバグがあるのかもしれない。
タイトルの通りですが、WP REST APIでカテゴリー情報を取得する場合、下記のエンドポイントを使いますよね。
/wp-json/wp/v2/categories
これに対してパラメータ per_page
で取得件数を設定できるのですが、実はこのパラメータ、1〜100の数値以外を渡すとエラーになります。
ドキュメントにも取りうる値の範囲は記載されていません
https://developer.wordpress.org/rest-api/reference/categories/
なんとなく語感がget_postsでよく使う posts_per_page
に似てるので-1を指定すれば全件取得できそうな気がするのですが、ところがどっこいできません。
おそらくパフォーマンスの問題で無茶な使い方を塞がれてるんだと思うのですが、100件以上になりうる可能性がある場合は、本当に必要なカテゴリーだけをパラメータ include
で指定して取得してあげるほうが良さそうです。
それでも100件以上欲しい場合は、パラメータ page
でしっかりロジカルにページングする必要がありそうです。