ダークサイドにようこそ!

限界クリエイターのブログ

Nuxt3 + Tailwind CSS + Three.js でポートフォリオをリニューアルしGitHub Actions で自動デプロイするようにした

ポートフォリオをリニューアルしました(ドメインも取りました)。メインビジュアルとしてフラクタル図形の3次元化を試みています。

followthedarkside.com

 

勉強がてら色々と初めてのものを導入してみたので、備忘録として記事にしておきます。Web開発って初心者向け情報だと「HTML+CSS+JSで簡単なサイト作ってみよう」から、ちょっと深掘りし出すと急に知らない言葉や概念が大量に出てきてようわからんってなりませんか。あとWordPressで稼ごう記事や怪しいオンラインスクールなど(WPが悪いわけじゃないんです)。

今回の記事は導入からデプロイまで網羅的に(雑に)書いてますので、Webは専門分野じゃないけどサイト作ってみたいなという方は参考になるかもしれません。何かしら役に立てばシェアいただけると嬉しいです。英語版もあります。

 

 

Vue2 からNuxt3 へ

GitHub Pages でホストしていた前のポートフォリオVue2(+Vue CLI + Vuetify)で作っていたのですが、上の記事にも書いているようにUIライブラリであるVuetify とホントに相性が悪くてミニマムな構成だけ作って放置……みたいな感じでした。せっかくCreativeCoding のような活動を昔からしているのに、やる気が消滅して見た目やインタラクションの遊び要素ゼロの残念な状態。ちょうど1年ぐらい経つということで、リニューアルするかと思ったのが今回のきっかけです。

また前回のポートフォリオ制作前後にVue3 がデフォルトになったぐらいのタイミングでしたので、今回のリニューアルに合わせてこちらもアップデートするかとなりました。あと調べてみると、Vue.js をより使いやすくするためのフレームワークとしてNuxt.js が人気らしいのでそれも試してみるかとなったのです。結果、Nuxt3 を使用してポートフォリオをリニューアルすることになりました。

Nuxt3 を導入するにあたって以下の記事を参考にさせていただきました。Nuxt2 と比べると情報が少なく開発途中でハマった点も多々あった気がするのですが、そちらは後述+気が向いたときに別記事で触れようかなと思います。

Installation · Get Started with Nuxt

Nuxt 3を使いこなすために基礎から徹底解説 | アールエフェクト

Nuxt.jsでポートフォリオサイトを作成してみた - Qiita ※こちらはNuxt2 の内容です。

 

あとNuxt に限らないですが、フレームワーク使ってWeb制作を効率化しようぐらいの時期になるとSPAやらSSGやら謎の文字列に遭遇することが増えます。前回と同じく全部忘れていたので改めて調べたりもしてました。その際に参考にさせていただいた記事も貼っておきます。こちら以外の記事を読んでもそうだったのですが、SPAは管理画面作成に使われやすいというのを知って「そうなのかー」などと思いました。

SPA/MPAとCSR/SSR/SSGの分類

SPA, SSG, SSRはどんなアプリケーションに向いている? (前編)|ファンタラクティブ株式会社|note

 

Tailwind CSS を導入する

「UI系のフレームワークは使いたくないな」「でもトレンドも知っておかないとな」という感じでCSSフレームワークであるTailwind CSS を導入しました。といっても一発でおしゃれボタン設置できます系ではなく、フレームワーク側にあらかじめ用意されているユーティリティクラスをHTML要素に適用する形で記述の手間を省くといった感じです(公式トップにあるデモがわかりやすい)。

ちなみに流れでDaisyUI もインストールしたのですがこちらはほぼ使いませんでした。やっぱり多少面倒でも自分でコーディングする方が性に合っているみたいです。

あと、公式の手順だとTailwind CLI を使用したものが紹介されていますが、Nuxt環境ならモジュール版(Nuxt Tailwind)が用意されておりそちらの方が勝手が良さそうなので、自分も後から気づいて入れ替えました。Tailwind はビルド後のサイズがデカくなりがちなのが、モジュール版だとPurgeCSS が初めから入っているので使っていないクラスを削除して容量削減できWebサイトの速度も改善できるみたいです。

その他、導入周り含め以下参考にさせていただきました。

Setup · Nuxt Tailwind

TailwindCSSを始めようとしている人へ

nuxt-tailwindをmodule版に切り替える - Qiita

Font Family - Tailwind CSS

Tailwind CSSで独自クラス(コンポーネント)を作成する

 

開発過程でTailwindも使ったNuxt用コンポーネントのパターンを色々試したついでに、GitHubにも一部アップしてます。ただアニメーション付きのレスポンシブ対応ナビゲーションバーとかグリッドレイアウトを作る上で普通のCSSやSass、jQueryも使った昔のコードを移植しており、現状のサイトは記法がぐちゃぐちゃになってます。めちゃくちゃ気が向いたら整理しようかな。

GitHub - FollowTheDarkside/nuxt-components-navigation-bar-example: Nuxt Components Navigation Bar Example

GitHub - FollowTheDarkside/nuxt-components-grid-layout-example: Nuxt Components Grid Layout Example

 

Nuxt3 環境にThree.js を導入する

ある程度ポートフォリオの構成が出来上がってきたので、ここで良さげなビジュアルを入れ込んでいきます。今回はJSで3Dコンテンツを作るためのライブラリであるThree.js を導入します。私ですら仕事でたまに使うぐらい有名。画像は関係ないですが、Three.js 公式にも昔ウケたLee Perry-Smith モデルのデモ。なぜか海外からスカウトも来た。

ちなみにNuxt2の環境に入れるのであれば、@misaki_mofu さんの記事とコードがとても参考になりますので私のはとくに見る必要ないです。ここではNuxt3 環境に導入する上で少しハマった点を抜粋しておきます。

 

シェーダーを書きたい

CG処理を凝り出すと必要になるシェーダーファイル(.flag, .vert, .glsl あたり)を読み込むのにraw-loader (ファイルの中身をテキストとして読み込む)を使うことがあります。ただ、Nuxt3だとデフォルトのビルドツールがViteになってるのでシェーダーファイルのimport時「hoge.glsl?raw」のように専用サフィックスを付ければ別途ローダーをインストールする必要がありません(ちなみにnuxt.config.tsの設定でVite からWebpack に戻すこともできます)。

Static Asset Handling | Vite

ViteでWebGL、Three.jsを練習するための環境構築をしてみた(TypeScript)

 

イベントバスの実装

ページ遷移やボタン押下時など、DOMの変化に合わせてThree.js で描画しているオブジェクトもグニョらせたい場合があります。そんな時にVue2 ではEventBus (Hubとも言う) の仕組みを使ってグローバルなイベントのやり取りができたのですが、Vue3からは公式ドキュメントにあるように$on や$off、$once メソッドが廃止されたようです。代わりにmitt あたりの外部ライブラリを使えとありますので私もそちらを導入しました。

プラグインの作成はplugins ディレクトリ内で行いますが、Nuxt2 と違いnuxt.config.ts に追記する必要はありません。Three.js側のソースではuseNuxtApp() を経由してイベントの購読を行います。あと以下の記事も参考になります。

Event bus in Nuxt3 - DEV Community

plugins/ · Nuxt Directory Structure

Vue + Mittでグローバルでイベントを取得できるようにする - さうな坊や.com

Nuxt3のsetup内ではthisの代わりにuseNuxtApp()を使用する - 独学プログラマ

 

3Dフラクタルを描画する(マンデルバルブ)

ここではThree.js で何を描画するかという話をします。興味がない人は飛ばしても構いません(寂しいけど)。

フラットなオブジェクトをヌルッと動かす方がモダンな感じがしてオシャレだな(コンペ受けも良いだろうな)と思いつつ、自分のポートフォリオですし好きなもん入れたいということでフラクタル図形を描画することにしました。以下は私の卒論より抜粋。

フラクタルとはフランスの数学者ブノワ・マンデルブロが導入した幾何学の概念であり、図形の部分と全体が自己相似になっているものをいう。自己相似とは、ある図形の一部分を取ってきたときにその一部分の形状と図形全体の形状とが相似であることを指している。 

 

簡単に書くと、図形の一部を拡大していくと同じ図形が現れる的なものがありますがアレです。今回はフラクタルの中でも有名なマンデルブロ集合を描画します。さらにThree.js の利点も活かして3次元化も行います。主張しすぎず、でもある程度の存在感を持たせるための色味の調整が地味に大変でした。

正確には3次元のマンデルブロ集合は存在しないのですが、計算に用いる複素数極座標から球面座標系に拡張して考えることで無限に発散しない点をプロットし3Dのフラクタルを描画することができます。私の理解力不足のため噛み砕いて説明するのが難しいですが、むかし参考にしたMandelbulb のwikiを貼っておきます。そして学生時代にお世話になりました山岸先生ありがとうございます。

Mandelbulb - Wikipedia

 

以下はopenFrameworks で作った昔の映像です。

youtu.be

 

お問い合わせフォームを作る

お問い合わせフォームってサーバ側の処理も考え出すと地味に大変です。簡単なのはメアドのリンクを貼っておきクリックしたユーザ側のメーラーを起動させるなど。

ただ今回はちゃんと入力フォーム画面を用意したかったのもあり、Googleフォームの埋め込み機能を使いつつデザインはカスタマイズして実装しました。デフォルトの埋め込みだと見た目が残念な感じになりますが、これだとサイト全体の雰囲気を損なわず問い合わせフォームを実現できます。以下の記事が大変参考になりました。ちなみにNetlifyのForms機能でも楽に実装できるらしいです(他のホスティングサービスでも使えるように今回は採用しませんでした)。

Google FormをHTML/CSSでデザインしたフォームで運用する方法

 

OGP の設定

いつも忘れがちなのですがOGP設定も行います(SNS等でURLシェアしたときに出るカードみたいなやつ)。ページごとに表示内容を変えたり動的に設定する必要がない場合、Nuxt ではnuxt.config.ts にてprefixやmetaタグの設定を行います。

Nuxt3でOGPを定義する

 

ちなみに私の方では、Twitternoteでカードが表示されないとなりだいぶハマりました(設定は合っているはずなのに)。どうもOGP設定前にシェアしようとしたときのキャッシュが残っている可能性が大きそう。note の方は意味不明です。ちなみに1日強ぐらい経過して表示されるようになりました。Twitterでは一部ページがまだ表示されないけど。

あまり関係ないですが、ChatGPTに聞いたらTwitterの古いキャッシュクリアの方法ばかり教えてくるのでめちゃくちゃストレスたまりました。この話は需要ありそうなので別記事にするかもしれないです。

Twitter、Card Validatorからプレビュー機能を削除。カード情報のキャッシュは最大7日 | gihyo.jp

 

SSG でビルドしてNetlify にファイル一式をアップする

ちょっと記事が長くなってますが、サイトが一通り完成しました。SSG(Static Site Generation)設定でビルドします。nuxt.config.ts は特にいじらず、「npx nuxi generate」コマンドを実行すると.output/public 以下に静的ファイルが出力されます(dist以下でも多分よいのですが公式のドキュメントに合わせています)。以下も参考。

Deployment · Get Started with Nuxt

Nuxt3入門(第1回) - Nuxtがサポートするレンダリングモードを理解する | 豆蔵デベロッパーサイト

 

ファイル一式が準備できましたので、ホスティングサービスにアップロードします。今回は無料枠があり使ってる人も多そうなNetlify にしました。前のポートフォリオで使ってたGitHub Pages もおすすめです(今回は勉強のため変えました)。

アップロードの仕方はファイルをドラッグするだけなので特に難しいことはありません。GitHubにアップしたリポジトリと連携させPushのタイミングでビルド&デプロイさせることもできるのですが、以下の記事を読ませていただき辞めとくかとなりました(私は無料枠を使い果たすことなさそうだけど)。ちなみに何も考えずNetlify を操作してると、しれっとGitHubへの連携を促してくるため気になる人は注意が必要です。

Netlifyに7ドル支払った話(GitHub ActionsでNetlifyにデプロイする) | Blog

 

独自ドメインを取得する

せっかく苦労してポートフォリオを作成したので、独自ドメインも取ることにします。私はGoogle Domains で取りました。普段は近所のスーパーでしか買い物してないのでドメイン選ぶの楽しかったです。Netlifyとの連携は以下の記事を参考にさせていただきました。

NetlifyのサイトにGoogle Domainsで購入したドメインを割り当てる | 定年後にWeb開発者目指す

Google Domainsで取得したドメインをnetlifyに設定する | hardworkers.dev

 

ちなみにDNSの設定にあたってよく分からない単語がたくさん出てくるのですが、ここでChatGPTが役に立ちました。明確な仕様や定義があるときはググるより意味を調べやすくて便利だなと思いました。

 

GitHub Actions を使ってPush 時に自動ビルド&デプロイする

ポートフォリオの公開までいけたのですが、変更のたびビルドしてファイルをアップするのは地味に面倒です。先述したようにNetlify側でビルドさせたくないので、GitHub Actions でビルドしNetlify へデプロイするようにします。後者だとパブリックリポジトリなら無料、プライベートでも月2,000分までビルド時間が使えます。私は以下の記事を参考に自動ビルド&デプロイの環境を用意しました。

GitHub Actions のクイックスタート - GitHub Docs

GitHub ActionsでNetlifyにデプロイする

 

私だけかもしれない地味にハマった点も書き残しておきます。ビルド後の.output/publicをactions-netlify の入力パスとして指定するのですが、エラーでファイルが見つからないと言われてしまいました。実はoutput直前のピリオドを打ち忘れていただけだったのですが、デバッグしてるとパス内にリポジトリ名が重複していたので1つ上の階層を指定したり、ピリオドに気付いたけど無駄にエスケープシーケンスにしたりとめちゃくちゃ時間取られてしまいました。結果、ふつうにパス書くだけで上手くいきました。dist指定ならこんなにハマらなかった。あとChatGPTにactions-netlify のバージョン差異などを無駄に指摘され惑わされたのもデカい。

 

さいごに

以上、長くなりましたがポートフォリのリニューアルから自動デプロイまでの話を書きました。リポジトリも公開しておきます(※本記事の執筆時点)。Webエンジニアの皆様、よかったらアドバイスなどいただけると嬉しいです。あと何かしら記事がお役に立ちましたらシェアいただけますと幸いです。仕事もください。

github.com

 

 

ここまで読んでいただきありがとうございました。

 

hahaeatora.hateblo.jp

hahaeatora.hateblo.jp

hahaeatora.hateblo.jp