ハダノ元教頭が GIGAスクール と DX人材育成 について考えるブログ
この記事では、
のその後について述べます。
🔗「生成AI用にデスクトップPCを追加購入した件」 で述べたように、ノートPCでやっていたことをデスクトップPCでもできるように頑張りました。
データは 🔗パーソナルクラウド にバックアップしていました。
プログラムは、重要なものから順にインストールしていきました。ブログも早く引っ越したかったのですが、子ども食堂タブレット教室への影響を考え、春休みを「ブログメンテナンス期間」としました。
ブログシステムは、記事データをデスクトップPCに移しただけでは動きません。Vue.js
や Nuxt.js
などのプログラムをインストールする必要があります。
2年前と同じ要領でやってみましたが、エラーの嵐に打ちのめされました。
どうやら、この2年間で開発環境が様変わりしていたようです。
おまけに、インストールコマンドまで変わっていました。たった2年間で浦島太郎です。
そのままインストールすると最新バージョンになって動かないのなら、古いバージョンを指定してインストールすれば動くかもしれません。ただ、これは持続可能ではありません。Vue2 の公式サポートが2023年で終了したからです。
を読むと、お先真っ暗な感じです。
それでも、Vue
+ Nuxt
を捨てて、React
+ Next
へ鞍替えしようとは思いません。乗り換えは最後の手段です。
冷静になると、
、、、と方針が固まってきました。
新・旧の書き方が混在した解説資料が多い中、
ならば、Nuxtバージョンv3.5.2、全編Composition API + script setupを使用……とあるので大丈夫そうです。
// pages/articles/_slug.vue 【 旧バージョン 】
<script>
export default {
async asyncData ({ $content, params, redirect, store }) {
const content = await $content('articles').where({ path: '/articles/' + params.slug }).fetch()
if (content.length > 0) {
return {
content: content[0],
contenturl: store.state.baseurl + content[0].path,
imgurl: store.state.baseurl + '/img/' + content[0].thumbnail
}
} else {
redirect('/articles')
}
},
head () {
・・・・・・
↓
// pages/articles/[slug].vue 【 新バージョン 】
<script setup>
const route = useRoute()
const path = route.path
const { data: content } = await useAsyncData(path,() => queryContent(path).findOne())
const h1title = content.title
const formatDate = (date) => new Date(date).toLocaleDateString()
const contenturl = useBaseurl() + content._path
const imgurl = useBaseurl() + '/img/' + content.thumbnail
useHead({
・・・・・・
、、、比べてみると、ずいぶん書き方が違います。ファイル名も _slug.vue
→ [slug].vue
と変わりました。
use で始まる Composables関数 は、Nuxt3 側が用意してくれたものが大幅に増えたうえに、簡単に自作してどこでも使えるようになりました。 → 🔗Nuxt3の本気を見た~Composablesの可能性~
これまでは、次のようになっていました。
pages
├ articles
| ├ page
| | └ _id.vue
| ├ index.vue
| └ _slug.vue ⇒ 各記事表示用ページ
├ category
| └ _slug
| ├ page
| | └ _id.vue
| └ index.vue
├ tag
| └ _slug
| ├ page
| | └ _id.vue
| └ index.vue
└ index.vue
_slug.vue 以外の7つのvueファイルは、記事一覧表示用なので基本的なつくりは同じです。
それでも、category
や tag
など 🔗リテラル を打って各動作を指定する必要があったため、別々に作っていました。前回、「layout は、うまく使えず、原因不明のままです。……」となっていましたが、今回は何とかしたいものです。
処理を分ける際のネックとなっていたのが、オブジェクトのキーの指定です。
を読んでやってみたら、リテラル を打たなくてよくなりました。
// pages/category/_slug/page/_id.vue
async asyncData ({ store, $content, params, redirect }) {
const ipp = store.state.indexPerPage
const h1title = store.getters.getCategoryTextBySlug(params.slug)
// Categoryテキスト取得専用メソッド
............
const content = await $content({ deep: true })
.where({ category: { $contains: params.slug } })
// リテラル【 category 】をObjectのKeyに指定
.sortBy('createdAt', 'desc')
.skip(pfrom).limit(ipp)
.fetch()
・・・・・・
↓
// pages/category/[slug]/page/[id].vue
......
const ipp = useIndexPerPage()
......
// コンテンツの種類による場合分け
if (route.params.slug) {
if (mapCat.get(route.params.slug)) {
parent = 'category'
child = route.params.slug
h1title = mapCat.get(child) // 連想配列からCategoryテキスト取得
} else {
if (mapTag.get(route.params.slug)) {
parent = 'tag'
child = route.params.slug
h1title = mapTag.get(child) // 連想配列からTagテキスト取得
}
............
const { data: contents } = await useAsyncData(rpath,() => queryContent('articles')
.where({[parent]:{$contains:child}})
// 【 [変数] 】でObjectのKeyに変数展開
.sort({createdAt:-1, $numeric:true}) // 日付を数値順でソート
.skip(pfrom).limit(ipp)
.find()
・・・・・・
これで、7つのVueファイルのコードを共通化できます。layouts
フォルダに listing.vue
として保存し、index.vue
や [id].vue
は次のように書いておけばよいのです。
<template>
<NuxtLayout name="listing">
※ listing.vue の <slot /> に差し込む中身があれば書く
</NuxtLayout>
</template>
結果的に、7つのVueファイルは同じものになりました。コードを修正するときは、listing.vue
だけをいじればよく、保守性がアップしました。
ブログシステムがだいたい動くようになったので、デプロイ(ネットにアップ)してみることにしました。
「 GitHubのリモートリポジトリにプッシュ → Cloudflare Pages に自動デプロイ 」という設定にしていたので、更新は楽でした。
ところが、「Cloudflare PagesとGitHubのリポジトリを連携させ、接続するGitリポジトリを選んで……」という手順で、今回の新しいリポジトリを選択しようとしましたがうまくいきません。どうやら、いったんプロジェクトを削除してやり直すしかないようです。削除を試みましたが、エラーでそれもできません。『最初が肝心』と思い知らされました。
次の手として、「前のGitHubリモートリポジトリをクローンしてローカルリポジトリを作り、そこに新しいブログシステムを移す」ことにしました。
あきらめの悪いハダノは、
という記事を見つけ前を向こうとしますが、--overwrite-dir
フラグが廃止されたと知ってガックリ。そもそも create-nuxt-app
は、Nuxt2
時代のものでした。
「もしや、Nuxt3
のインストールコマンド npx nuxi init
に何かないか?」と思って 🔗Nuxt公式ページ を見ると、
--force 〔Force clone to any existing directory.〕
というオプションがあるではありませんか。
最終的に、
1. GitHubのリモートリポジトリをクローンし、.gitフォルダ 以外を削除。
2. 親フォルダへ移動し、Nuxtプロジェクトを上書き作成(content も同時に)。
> npx nuxi init プロジェクト名 --force -t content
☑npm
3. gitリポジトリは初期化せず、既存のものを使う。
> Initialize git repository?
□Yes / ☑No
4. モジュール(@nuxtjs/google-adsense, @nuxtjs/seo)をインストール。
5. だいたい動くプロジェクトからファイルをコピー(.nuxt, node_modules以外 )。
6. nuxt.config.ts等を修正し、npm run dev で動作確認。
7. GitHubへコミット・プッシュ。
8.Cloudflare Pages デプロイの詳細-ビルドログを確認。
という流れで、やっとデプロイにこぎつけました。
ビルド コマンド:npx nuxt generate
や NODE_VERSION
:20.11.0
などの変更をし、
🔗ビルドエラー回避のため、nuxt.config.ts に 以下を加えました。
nitro:{
prerender: {
failOnError: false,
},
},
開発環境では動いたのに、本番環境では動かず(リロードが必要)、useAsyncData
のキャッシュ制御を見直す一幕もありましたが、何とか予定したものができあがりました。
cd c:\nuxth\nuxthblog
npm run dev
cmd /k
いつものバッチファイル(rundev.bat)でエラーが出たので調べると、
という報告があがっていました。
で、とりあえずエラーは消えました。
「今動いているシステムをバージョンアップするだけだから、一から作るより楽だろう」という考えは甘すぎました。
持続可能なシステムとは、「ピラミッドのように堅固なもの」ではなく、「自転車のように動いているもの」だと知りました。
世界は常に変化しています。完璧に見えるピラミッドも風化していきます。状況に対応しながら走り続ける自転車でありたいものです。そのためには、「学ぶ」「作る」というペダルをこぎ続けるしかありません。
今回、さまざまなエラーに苦しみながら実感したことは、「問題の切り分け」の大切さです。
、、、それぞれのレベルごとにバージョン間の互換性はあるので、新しいものが出たからといってすぐに移行しなくてもよさそうです。ただし、年代ごとに想定している環境があるので、ある程度そろえる必要があります。
例えば、JavaScriptの関数を定義する方法として、「function宣言」のほかに「アロー関数」が出てきました。現在、どちらも使用可能ですが、Vue2:function宣言 ⇒ Vue3:アロー関数 と移り変わっています。参考資料に出てくるコードを理解して利用するためには、古いやり方に固執してはいけません。逆に、新しい書き方を有効にするために、Node.js のバージョンを上げる必要も出てきます。
、、、実際にやってみて、記事の時点とは状況が変わっていたものも多かったのですが、基本的な考え方は身につきました。
Vue2,Nuxt2 に慣れた人からすると「破壊的変更」かもしれませんが、Vue3,Nuxt3 になって「素のJavaScript」に近づいた感じがします。ネストが浅くすっきり書けるので、言われるほど悪くありません。それどころか、もっと新しい書き方を試してみたくなります。
自前のブログシステムなので、使っていきながら改良していきます(自転車操業になるかも?)。中身が全部わかっているというのは、安心です。
これからも応援よろしくお願いします。