ebi です。定期ネタの WordPress 芸をやっていきます。
今回は一度やってみたかった WP REST API を利用したサイトに少し手出してみます。 React より Vue.js の方がまだ触ったことあるので NuxtJS を使ってみます。
また、 SSR だとホスティングするサーバをどうするかの問題が出てくるので SSG 前提のサイト構成にしてみようと思います。
そんなわけで実験がてらこう言う構成のサイト作りをやってみることにしました。
GitHub にコードも晒しておくので最終的なコードの細かい詳細見たい方は後で確認してください。
CMS として WordPress を採用している理由
正直自分自身にとって馴染みがある以外の理由は特にないです。
近年、 ContentFul や microCMS などのヘッドレスCMSが台頭してきているので、好みでそう言う CMS を選んでも良いと思います。
その辺、あえて雑多な感想を羅列しておくと
- WordPress 自体はこれからもしばらくはサイト作成ツールとしての利用でも使われ続けるであろうから、知名度やノウハウ、メンテナンスの継続性にある程度の保証はあると思うので、最近聞くようになったなレベルのヘッドレスCMSよりその点での信用度はある(使い慣れて損がない)
- 当たり前だが、 REST API のみを使う場合、配布されている無料・有償の WordPress テーマを利用したサイトのデザインテンプレートを使うのは難しい(根性で一部移植とはもちろんやろうと思えばできるだろうけど。あとその辺が使いまわせるようWordPress単体として静的ファイル化するプラグインも一応あるにはある)
あくまで活用するのはユーザ管理や記事投稿の部分になるが、とは言え ACF などの管理画面カスタマイズのノウハウがある場合はそう言ったものを活用することはできる - 既存の記事データを応用したい場合、管理されている記事コンテンツの内容やその中身、テーマテンプレートの作られ方や、依存プラグインなどの性質によって難易度や応用できる度は非常に左右される
Techracho みたいなブログサイトとして持っている単純な記事データは割と使い回せる見込みが高い。そのため、サイト表示の速度改善やセキュリティリスクの削減のために WordPress サイト周りのチューニングやサーバ構成の見直しを図るより、思い切って今回のようなサイト構成リニューアルを試みるのは割と悪くない話だと思う
WordPress の環境準備
WordPress が動く docker 環境を用意する
本題じゃないのであまり解説はしません。
- Dockerfile を用意します。 wp-cli 使いたい以上の説明は特にないです。
FROM wordpress:5.7-php7.4-apache
# install wp-cli
RUN set -ex; \
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar; \
chmod +x wp-cli.phar; \
mv wp-cli.phar /usr/local/bin/wp
- docker-compose.yml を用意します。今回は WordPress テーマの方は完全にどうでもいいので mount すらしてません。
version: '3.1'
services:
wordpress:
build: .
ports:
- 80:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: username
WORDPRESS_DB_PASSWORD: password
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
db:
image: mysql:5.7
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: username
MYSQL_PASSWORD: password
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
volumes:
wordpress:
db:
- docker 環境を立ち上げて WordPress の初期設定をします
ebi@LAPTOP-R8D4FNMF:~/git-clone/for-techracho/wp-rest-api-and-nuxtjs$ docker-compose up -d --build
Creating network "wp-rest-api-and-nuxtjs_default" with the default driver
Creating volume "wp-rest-api-and-nuxtjs_wordpress" with default driver
Creating volume "wp-rest-api-and-nuxtjs_db" with default driver
Building wordpress
[+] Building 6.2s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 259B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/wordpress:5.7-php7.4-apache 3.1s
=> CACHED [1/2] FROM docker.io/library/wordpress:5.7-php7.4-apache@sha256:37be4c1afbce8025ebaca553b70d9ce5d7ce4861a351e4bea42c36ee966b27bb 0.0s
=> => resolve docker.io/library/wordpress:5.7-php7.4-apache@sha256:37be4c1afbce8025ebaca553b70d9ce5d7ce4861a351e4bea42c36ee966b27bb 0.0s
=> [2/2] RUN set -ex; curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar; chmod +x wp-cli.phar; mv wp-cli.phar /usr/local/bin/wp 2.8s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:28908b82cc118042c71162d7a6d63593878e1d73e077da9a4aa7fd87db0b8ca0 0.0s
=> => naming to docker.io/library/wp-rest-api-and-nuxtjs_wordpress 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
Creating wp-rest-api-and-nuxtjs_wordpress_1 ... done
Creating wp-rest-api-and-nuxtjs_db_1 ... done
ebi@LAPTOP-R8D4FNMF:~/git-clone/for-techracho/wp-rest-api-and-nuxtjs$ docker-compose exec wordpress wp core install --url=localhost --title='Only Use REST API Site' --admin_user=admin --admin_email=admin@e
xample.com --allow-root
Admin password: GYfzQb35Ln*DraH5f6
Success: WordPress installed successfully.
適当な記事データを準備する
WordPress のテーマを探したことはありますか?デモサイトのリンクも貼ってあったりするのですがどのテーマも似たような記事が入っているのです。
つまりは公式からそう言うダミー記事(テーマユニットテスト用の)データが用意されているってことです。
本家の案内はここです。日本語版っぽいのを用意している人もどうやらいるようでしてここから拾えます。
今回は英語版を使いました。
- これを使ってダミーの記事を読み込みます。
docker-compose exec wordpress bash
してこんな感じ。
root@2a69f8496065:/var/www/html# wp plugin install wordpress-importer --activate --allow-root
Installing WordPress Importer (0.7)
Downloading installation package from https://downloads.wordpress.org/plugin/wordpress-importer.0.7.zip...
Unpacking the package...
Installing the plugin...
Plugin installed successfully.
Activating 'wordpress-importer'...
Plugin 'wordpress-importer' activated.
Success: Installed 1 of 1 plugins.
root@2a69f8496065:/var/www/html# curl -O https://raw.githubusercontent.com/WPTRT/theme-unit-test/master/themeunittestdata.wordpress.xml
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 550k 100 550k 0 0 1092k 0 --:--:-- --:--:-- --:--:-- 1090k
root@2a69f8496065:/var/www/html# ls
index.php readme.html wp-activate.php wp-blog-header.php wp-config-docker.php wp-config.php wp-cron.php wp-links-opml.php wp-login.php wp-settings.php wp-trackback.php
license.txt themeunittestdata.wordpress.xml wp-admin wp-comments-post.php wp-config-sample.php wp-content wp-includes wp-load.php wp-mail.php wp-signup.php xmlrpc.php
root@2a69f8496065:/var/www/html# wp import themeunittestdata.wordpress.xml --authors=create --allow-root
Starting the import process...
Processing post #1724 ("Keyboard navigation") (post_type: post)
-- 1 of 180 (in file themeunittestdata.wordpress.xml)
-- Mon, 19 Jul 2021 20:48:16 +0000
-- Imported post as post_id #1724
-- Added terms (79) for taxonomy "post_tag"
以下略
WP REST API の軽い動作確認
詳しくはドキュメントを参照してください
http://localhost/wp-json/wp/v2/posts
とかで JSON を受け取れることが確認できます。
(以下スクショはFirefoxでアクセスしたので勝手に整形されてます)
NuxtJS の初期設定する
create-nuxt-app をしてみる
ので、また NuxtJS 用の node が入った docker 環境から準備していきます。
- 適当に Node 公式の docker イメージをベースにして nuxtjs サービスを docker-compose.yml に追加しました。 volumes の指定でこのあと作成する NuxtJS アプリの素材置き場を予めマウントしています。
nuxtjs:
image: node:14
user: node
working_dir: /home/node
tty: true
ports:
- 3333:3000
volumes:
- ./frontend/for-wp-rest-api:/home/node/for-wp-rest-api
あとは再度 docker-compose up -d
して、 exec してみて作業していきます。
ebi@LAPTOP-R8D4FNMF:~/git-clone/for-techracho/wp-rest-api-and-nuxtjs$ docker-compose exec nuxtjs bash
node@e8b19f43f548:~$ npm install create-nuxt-app
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
> ejs@2.7.4 postinstall /home/node/node_modules/ejs
> node ./postinstall.js
Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)
npm WARN saveError ENOENT: no such file or directory, open '/home/node/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/home/node/package.json'
npm WARN node No description
npm WARN node No repository field.
npm WARN node No README data
npm WARN node No license field.
+ create-nuxt-app@3.7.1
added 382 packages from 199 contributors and audited 382 packages in 13.494s
9 packages are looking for funding
run `npm fund` for details
found 1 moderate severity vulnerability
run `npm audit fix` to fix them, or `npm audit` for details
node@af31c278a423:~$ npm init nuxt-app for-wp-rest-api
create-nuxt-app v3.7.1
✨ Generating Nuxt.js project in for-wp-rest-api
? Project name: for-wp-rest-api
? Programming language: JavaScript
? Package manager: Npm
? UI framework: Vuetify.js
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: ESLint, Prettier
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Static (Static/Jamstack hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Continuous integration: None
? Version control system: None
npm WARN deprecated core-js@2.6.12: core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could
cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.
npm WARN deprecated querystring@0.2.1: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
> core-js@2.6.12 postinstall /home/node/for-wp-rest-api/node_modules/@nuxt/babel-preset-app/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"
> core-js@2.6.12 postinstall /home/node/for-wp-rest-api/node_modules/@nuxt/babel-preset-app/node_modules/core-js
> node -e "try{require('./postinstall')}catch(e){}"
Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!
The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:
中略
> for-wp-rest-api@1.0.0 lint:js /app/for-wp-rest-api
> eslint --ext ".js,.vue" --ignore-path .gitignore . "--fix"
� Successfully created project for-wp-rest-api
To get started:
cd for-wp-rest-api
npm run dev
To build & start for production:
cd for-wp-rest-api
npm run build
npm run start
For TypeScript users.
See : https://typescript.nuxtjs.org/cookbook/components/
- 言われた通りに dev 環境を立ち上げたいのだけど、どうやら Docker 環境で立ち上げた develoment 環境のサイト画面をホスト側のブラウザで開くには設定変更が必要そうなので、ドキュメントに従って nuxt.config.js に一部だけ追記します
server: {
host: '0' // デフォルト: localhost
},
- こんな感じで development サーバが立ち上がって、
http://localhost:3333
にアクセスして初期表示っぽい画面が出たらおしまい
node@6240940fa15f:~$ cd for-wp-rest-api/
node@6240940fa15f:~/for-wp-rest-api$ npm run dev
> for-wp-rest-api@1.0.0 dev /app/for-wp-rest-api
> nuxt
╭────────────────────────────────────────╮
│ │
│ Nuxt @ v2.15.7 │
│ │
│ ▸ Environment: development │
│ ▸ Rendering: server-side │
│ ▸ Target: static │
│ │
│ Listening: http://172.30.0.3:3000/ │
│ │
╰────────────────────────────────────────╯
ℹ Preparing project for development 17:33:48
ℹ Initial build may take a while 17:33:48
ℹ Discovered Components: .nuxt/components/readme.md 17:33:48
✔ Builder initialized 17:33:48
✔ Nuxt files generated 17:33:48
✔ Client
Compiled successfully in 8.03s
✔ Server
Compiled successfully in 7.04s
ℹ Waiting for file changes 17:33:57
ℹ Memory usage: 216 MB (RSS: 469 MB) 17:33:57
ℹ Listening on: http://172.30.0.3:3000/
- ホットリロードも上手く動いていました。ただ、これだと全然 SSG した静的サイト状態ではありません。
じゃあどうするかと言うと、npm run generate
でnuxt generate
してくれて、 dist ディレクトリ配下に静的ファイルが置かれる。これをデプロイすればよい
また、npm run start
でnuxt start
されて、この状態だと静的サイトのホスティングをしてくれるそうです
WP REST API との連携を試す
NuxtJS では pages ディレクトリに置く .vue ファイルで勝手にルーティング作ってくれます。便利ですね。
と言うことで、とりあえずTOPページと各投稿ページを作ってみます。
index.vue
をこんな感じで書き換えました。サイト内の全投稿データを一度に取ってきているわけではないですが、その辺りは今の段階では無視します。
<template>
<div>hogehuga
<ul>
<li v-for="post in posts" :key="post.id">
id: {{ post.id }}<br>
slug: {{ post.slug }}<br>
title: {{ post.title.rendered }}
</li>
</ul>
</div>
</template>
<script>
export default {
async asyncData({$axios}) {
const posts = await $axios.$get('http://wordpress/wp-json/wp/v2/posts')
return { posts }
}
}
</script>
- pages ディレクトリ配下に articles ディレクトリを切って、
_id.vue
ファイルを作っていきます
とこれを追加しながら気付いたんですが、SSRする時のWordPressサイトは wordpress を見に行けばいいんだけど、クライアントサイドでは localhost を見に行きたいのでその辺の分岐を判断させるprocess.client
とかも足しました
<template>
<div>this is article detail page.
<h2>{{ post.title.rendered }}</h2>
<!-- eslint-disable-next-line vue/no-v-html -->
<div v-html="post.content.rendered"></div>
</div>
</template>
<script>
export default {
async asyncData(context) {
const wpSiteDomain = process.client ? 'localhost' : 'wordpress'
const post = await context.$axios.$get(`http://${wpSiteDomain}/wp-json/wp/v2/posts/${context.params.id}`)
return { post }
}
}
</script>
TOPページの方も同様の変更を加えたのと、リンクを足しました
<template>
<div>hogehuga
<ul>
<li v-for="post in posts" :key="post.id">
id: {{ post.id }}<br>
slug: {{ post.slug }}<br>
<NuxtLink :to="'/articles/'+post.id">title: {{ post.title.rendered }}</NuxtLink>
</li>
</ul>
</div>
</template>
<script>
export default {
async asyncData({$axios}) {
const wpSiteDomain = process.client ? 'localhost' : 'wordpress'
const posts = await $axios.$get(`http://${wpSiteDomain}/wp-json/wp/v2/posts`)
return { posts }
}
}
</script>
- 一通り準備してみたので
npm run generate
してみます
どうやらリンクを NuxtLink でちゃんと貼っておけば(ここ伏線)勝手にクローリングして動的ルーティングも解決してくれるらしい?天才か? 🤔
node@6240940fa15f:~/for-wp-rest-api$ npm run generate
> for-wp-rest-api@1.0.0 generate /home/node/for-wp-rest-api
> nuxt generate
ℹ Doing webpack rebuild because pages/index.vue modified 20:31:24
ℹ Production build 20:31:24
ℹ Bundling for server and client side 20:31:24
ℹ Target: static 20:31:24
ℹ Using components loader to optimize imports 20:31:24
ℹ Discovered Components: node_modules/.cache/nuxt/components/readme.md 20:31:24
✔ Builder initialized 20:31:24
✔ Nuxt files generated 20:31:24
✔ Client
Compiled successfully in 18.10s
✔ Server
Compiled successfully in 7.55s
Hash: 95aae7fb42d112dc083f
Version: webpack 4.46.0
Time: 18097ms
Built at: 07/20/2021 8:31:43 PM
Asset Size Chunks Chunk Names
../server/client.manifest.json 16.8 KiB [emitted]
026bb8a.js 2.36 KiB 8 [emitted] [immutable] runtime
06c3360.js 224 KiB 1 [emitted] [immutable] commons/app
506c179.js 3.91 KiB 0 [emitted] [immutable] app
7a8387e.js 6.58 KiB 3 [emitted] [immutable] components/tutorial
8f34255.js 946 bytes 4 [emitted] [immutable] components/vuetify-logo
LICENSES 407 bytes [emitted]
a020b88.js 534 KiB 9 [emitted] [immutable] [big] vendors/app
a0680e3.js 826 bytes 5 [emitted] [immutable] pages/articles/_id
a8fbb47.js 12.7 KiB 10 [emitted] [immutable] vendors/pages/inspire
ca3c55d.js 1.85 KiB 2 [emitted] [immutable] components/nuxt-logo
f6103f7.js 683 bytes 7 [emitted] [immutable] pages/inspire
fb35e2f.js 920 bytes 6 [emitted] [immutable] pages/index
+ 2 hidden assets
Entrypoint app = 026bb8a.js 06c3360.js a020b88.js 506c179.js
WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
a020b88.js (534 KiB)
Hash: 0ea6a566ee2cb2b83c27
Version: webpack 4.46.0
Time: 7546ms
Built at: 07/20/2021 8:31:50 PM
Asset Size Chunks Chunk Names
components/nuxt-logo.js 5.89 KiB 1 [emitted] components/nuxt-logo
components/tutorial.js 7.13 KiB 2 [emitted] components/tutorial
components/vuetify-logo.js 4.98 KiB 3 [emitted] components/vuetify-logo
pages/articles/_id.js 2.05 KiB 4 [emitted] pages/articles/_id
pages/index.js 2.25 KiB 5 [emitted] pages/index
pages/inspire.js 10.6 KiB 6 [emitted] pages/inspire
server.js 649 KiB 0 [emitted] app
server.manifest.json 779 bytes [emitted]
+ 7 hidden assets
Entrypoint app = server.js server.js.map
ℹ Full static generation activated 20:31:51
ℹ Generating output directory: dist/ 20:31:51
ℹ Generating pages with full static mode 20:31:51
✔ Generated route "/inspire" 20:31:51
✔ Generated route "/" 20:31:52
✔ Generated route "/articles/1784" 20:31:54
✔ Generated route "/articles/1" 20:31:54
✔ Generated route "/articles/1781" 20:31:54
✔ Generated route "/articles/1782" 20:31:54
✔ Generated route "/articles/1786" 20:31:54
✔ Generated route "/articles/1785" 20:31:54
✔ Generated route "/articles/1778" 20:31:54
✔ Generated route "/articles/1787" 20:31:54
✔ Generated route "/articles/1783" 20:31:54
✔ Generated route "/articles/1788" 20:31:54
✔ Client-side fallback created: 200.html 20:31:54
✔ Static manifest generated
- 簡単じゃん?これで完璧? 😄
⇒ そこまで甘くはない 😡
こんな感じで画像パスはWordPressサイトを向いているままなので、デプロイしたいならWordPressがアップロードした画像を持って来るのと、画像パスを置き換えをしないといけなそうです(冒頭の図で説明してますが)
WordPress でアップロードした画像ファイルの取り扱いを解決する
あまりモチベーションが湧く楽しそうな課題じゃないので一旦飛ばします 😇
と言うか、元々は端末によって利用する画像選ぶとかそう言う画像最適化モジュール(参考)って言うのがフロントエンド的にあって凄いらしいので触りたかったのですが、HTML全体をWordPressから貰ったもの表示するだけとなると画像表示用のコンポーネントを使うようにさせる用途と合わない気がしました。
画像圧縮をやるにしてもWordPressからアップロードする時点でプラグインで済ませれば良い気がしてきたので今回はやりません。
となると、やるべきことは画像アップロードディレクトリの同期と generate 完了後のHTMLが参照している img の src を書き換えるだけになりました。
仕上げる。ページ整えたり実際にデプロイしたり
- Vuetify の pagination コンポーネントを使おうとしたら、リンククリック時の制御を指定すると言う形でしかカスタマイズできなかった
するとボタン部分を NuxtLink 化できなそうで nuxt generate でページネーションのリンクを踏んだあとの2ページ目以降のページが生成されませんでした 😭
と言うことで、自前で適当にページネーションのロジック書いてコンポーネント作りました。玄人はどうしてんの…… 🙄 - せっかく本来 WordPress の Gutenberg で作ったブロックである程度レイアウト指定がされているのがこのままだと引き継げません
その場合、この辺りの CSS ファイルを assets 配下に持って来て nuxt.config.js で指定してスタイルを当てるとなんとなく綺麗になります。もっと良い持ってき方がありそうな気もしますが。
// Global CSS: https://go.nuxtjs.dev/config-css
css: [
'@/assets/css/wp-block-library/style'
],
- GitHub Pages へのデプロイを考えるにあたって、ドキュメントルートの調整を行っておきます。
これは nuxt.config.js の末尾に以下を足せば良さそうです(参考)
router: {
base: '/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/'
},
上記設定後に npm run generate
したファイルを軽く覗いてみると、以下のようになったことが確認でき、これで GitHub Pages 環境にデプロイしても動きそうです
( development の base も変わっちゃうので、base: process.env.NODE_ENV == 'production' ? '/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/' : '/'
とかにしてもいいかも)
</div></div></div></div></div></div> <div class="row my-5 justify-center"><a href="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/archives/1" class="v-btn v-btn--is-elevated v-btn--has-bg v-btn--router theme--light v-size--default"><span class="v-btn__content">
all article archives
</span></a></div></div></div></main> <footer class="v-footer v-sheet theme--light v-footer--absolute" style="left:0;right:0;bottom:0"><span>© 2021</span></footer></div></div></div></div><script defer src="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/_nuxt/static/1628038218/state.js"></script><script src="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/_nuxt/b410278.js" defer></script><script src="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/_nuxt/81a6dc0.js" defer></script><script src="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/_nuxt/c9dd595.js" defer></script><script src="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/_nuxt/18164a9.js" defer></script><script src="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/_nuxt/9d78f39.js" defer></script><script src="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/_nuxt/6215724.js" defer></script><script src="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/_nuxt/22b3dc8.js" defer></script>
</body>
</html>
画像周りリベンジ
方針としては、 nuxt generate
の処理にカッコよくフックする感じでパス変換の処理を仕込めると良さ気なのでそれを目指します。
フックの案内はここにあります。
- WordPress からアップロードした画像はなんやかんやで NuxtJS 管理下の static ディレクトリ下に持って来れたものとします。ここに置いておくと
nuxt generate
した後も dist フォルダ配下に置いてくれるようになるのでここに置いてます
今回はdocker cp wp-rest-api-and-nuxtjs_wordpress_1:/var/www/html/wp-content/uploads ./frontend/for-wp-rest-api/static
と詰まらない処理で終わらせました - Node.js で真面目に処理を書けそうにないので、せめてファイル探索や文字列置換の処理が楽になりそうなそれらしきパッケージを見つけてきてまず
npm i -D replace-in-file
でインストールしました - nuxt.config.js の末尾に
generate:done
にフックする処理を足します
hooks: {
'generate:done': async generator => {
const replace = require('replace-in-file')
const options = {
files: 'dist/**/*.html',
from: 'src="http://localhost/wp-content/uploads',
to: 'src="/for-techracho/wp-rest-api-and-nuxtjs/frontend/for-wp-rest-api/dist/uploads',
}
const results = replace.sync(options);
console.log('Replacement results:', results);
}
}
これで npm run generate
を実行すると、こんな感じで generate 完了後に独自処理として今追加したファイル内の文字置換も実行されるようになりました。
node@3f442c55f636:~/for-wp-rest-api$ npm run generate
> for-wp-rest-api@1.0.0 generate /home/node/for-wp-rest-api
> nuxt generate
ℹ Doing webpack rebuild because nuxt.config.js modified 17:07:07
ℹ Production build 17:07:08
ℹ Bundling for server and client side 17:07:08
ℹ Target: static 17:07:08
ℹ Using components loader to optimize imports 17:07:08
ℹ Discovered Components: node_modules/.cache/nuxt/components/readme.md 17:07:08
✔ Builder initialized 17:07:08
中略
✔ Generated route "/articles/1163" 17:07:41
✔ Generated route "/articles/1031" 17:07:41
✔ Generated route "/articles/555" 17:07:41
✔ Client-side fallback created: 200.html 17:07:41
✔ Static manifest generated 17:07:41
Replacement results: [ 17:07:41
{
file: 'dist/200.html',
hasChanged: false
},
{
file: 'dist/archives/1/index.html',
hasChanged: false
},
{
file: 'dist/archives/2/index.html',
hasChanged: false
},
{
file: 'dist/archives/3/index.html',
hasChanged: false
},
{
file: 'dist/archives/4/index.html',
hasChanged: false
},
{
file: 'dist/archives/5/index.html',
hasChanged: false
},
{
file: 'dist/archives/6/index.html',
hasChanged: false
},
{
file: 'dist/archives/7/index.html',
hasChanged: false
},
{
file: 'dist/archives/8/index.html',
hasChanged: false
},
{
file: 'dist/archives/9/index.html',
hasChanged: false
},
{
file: 'dist/articles/1/index.html',
hasChanged: false
},
{
file: 'dist/articles/1000/index.html',
hasChanged: false
},
{
file: 'dist/articles/1011/index.html',
hasChanged: false
},
{
file: 'dist/articles/1016/index.html',
hasChanged: false
},
{
file: 'dist/articles/1031/index.html',
hasChanged: true
},
{
file: 'dist/articles/1148/index.html',
hasChanged: false
},
{
file: 'dist/articles/1149/index.html',
hasChanged: false
},
{
file: 'dist/articles/1150/index.html',
hasChanged: false
},
{
file: 'dist/articles/1151/index.html',
hasChanged: false
},
{
file: 'dist/articles/1152/index.html',
hasChanged: false
},
{
file: 'dist/articles/1158/index.html',
hasChanged: true
},
{
file: 'dist/articles/1161/index.html',
hasChanged: false
},
{
file: 'dist/articles/1163/index.html',
hasChanged: true
},
中略
デプロイ先で動作確認
- デプロイしたけどちょっとおかしい。どうやら
_nuxt
以下のファイルが上手く取り扱えていないようです。調べてみると、 GitHub Pages では_
始まりのファイルやフォルダ名がNGらしい - と言うことで nuxt.config.js の build プロパティに以下のように追記して再生成&デプロイをしました
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
publicPath: '/nuxtjs/'
},
- 多分これで無事デプロイできたと思います
(見ても大して面白くないですが実際に動くのを見たければこちらから)
感想など
- ルーティングやレイアウトの仕組み整備がしてあって
nuxt generate
でサイト生成するまでのハードルは低くて良いと思いました - 実際やってみると、まともなサイトを作ろうと思う上ではまだまだ解決しないといけない課題は色々ありますが、ノウハウ溜まれば二個目、三個目の案件は自信を持ってやれそうです
あるいは NuxtLink の件みたいに SSG がまだ茨の道かもしれないので、素直に Netlify みたいなお馴染みのサービスを使って SSR 寄りでホスティングする方が楽な気もします - 別に WordPress とかでコンテンツ管理する前提じゃないにしても、コーポレートサイトとか作る上で素の HTML 書くくらいならこう言うフレームワークで構成されていく方が
楽しい嬉しい時もありそうなので、 NuxtJS 単体でも何かで使う機会があると良いですね - Techracho みたいにひたすらページ数多くなりそうなサイトで SSG する時の処理時間とかはどうなの?ってところは要検証ですがチラっと調べた限り、千や一万ページオーダーならイケるのかもしれないです(microCMS運営さんの検証記事)