はじめに?
自作モノリスRailsアプリを Rails(バックエンド) + Nuxt3(フロントエンド)、に分割して、SPA(SSRあり)化してみました。
現在、Nuxt4にアップデート済み。
Easel
画像ビューア。
機能
・ユーザー登録/ログイン/ログアウト/ユーザープロフィール編集
・画像一覧/画像登録(アップロード、タグ付け)
・画像へのコメント(投稿/一覧/編集/削除)
・画像プロフィール編集
・レスポンシブ・デザイン(似非かも?)
スクリーンショット
画像一覧
未ログイン
ログイン済み
検索条件
ログイン
ユーザー登録
ユーザープロフィール
メールアドレス&パスワードでのログイン
Googleログイン
ユーザープロフィール編集
メールアドレス&パスワードでのログイン
Googleログイン
画像アップロード
画像詳細
ログイン済み
未ログイン
画像プロフィール編集
構成
フロントエンド: Nuxt4
バックエンド: Rails8.1
Nuxt4フロントエンド
Vue.js3 のAPIは Composition API を全面採用。
ビューまわりは、旧アプリ(Rails)のパーシャルViewを(レイアウトや機能については)そのままVue.jsのSFCに書き換えてUIコンポーネント化してから変更の後コミットしたのが始まりです。
現在は、初期実装から、それなりに変わっています。
利用技術
利用NPMパッケージ
レイアウト: Tailwind CSS v4 + daisyUI v5
入力バリデーション: Regle
国際化(i18n): Vue i18n + Nuxt I18n
通知: Vue Sonner
カレンダー: Vue Datepicker
ページング: なし (独自実装)
Googleログイン: Vue3 Google Sign-in
WYSWYGエディタ: Tiptap
画像拡大表示: GLightbox、Photoswipe
... etc
Railsバックエンド
WEB API と 管理画面(Rails Admin)で構成。
Rails8.1 + PostgreSQL。
※ Rails Adminについてはカスタマイズしていません。
(RailsAdminサイドでModelのdefault_scopeの無効化は行なっています。)
利用技術
DBサーバー: PostgreSQL
ストレージサーバー: MinIO (Amazon S3互換)
NoSQLキー/バリュー・ストア: Valkey (Redis互換)(Session Store用)
画像プロキシ: imgproxy
利用Gem
ログイン認証: devise + devise-jwt
画像アップロード: Shrine
タグまわり: No Fly List
論理削除: Discard
ページング: Pagy
UIのコンポーネント化: ViewComponent
JSONシリアライザ: Alba
JSONパーサ/マーシャラー: Oj
(簡易)管理機能: RailsAdmin
テスト: RSpec
フロントエンドツール: Vite Ruby (vite_rails)
画像プロキシ: imgproxy.rb
... etc
利用NPMパッケージ
レイアウト: Tailwind CSS v4 + daisyUI v5
... etc
旧バージョン(Rails)
バックエンドとフロントエンドが一体化したモノリス。
Hotwire(Stimulus + Turbo)、
画像詳細ページのコメント一覧/投稿/編集/削除機能に Vue.js3 を採用。
利用Gem
ログイン認証: devise
画像アップロード: Shrine
タグまわり: No Fly List
論理削除: Discard
ページング: Pagy
UIのコンポーネント化: ViewComponent
JSONシリアライザ: Alba
JSONパーサ/マーシャラー: Oj
(簡易)管理機能: RailsAdmin
フロントエンドツール: Vite Ruby (vite_rails)
画像プロキシ: imgproxy.rb
... etc
利用NPMパッケージ
レイアウト: Tailwind CSS v4 + daisyUI v5
... etc
履歴
-
Rails本体:
5.2 → 6 → 7.0 → 7.1 -> 7.2 → 8.0 → 8.1 と、バージョンアップを経てきています。 -
Railsまわり:
アップローダの変更: Refile → Shrine
ストレージの変更: プロジェクト内 → MinIO (AWS S3互換)
ページングの変更: Kaminari → Pagy
JSONシリアライザの変更: JSON:API Serialization Library → Alba
認証まわりの変更:Sorcery → devise
タグまわりの変更:ActsAsTaggableOn → No Fly List -
RailsのJS/CSSまわり:
Sprockets →
Sprockets + Webpacker (on Node.js) →
Sprockets + esbuild & sass →
Propshaft + esbuild & sass
(jsbundiling-rails + cssbundling-rails) →
Propshaft + Vite (vite_rails) -
JSバンドラ
Yarn → pnpm -
JSまわり
旧Railsフロントエンド:
Vue.js 2 → 3
JavaScript → TypeScript
Luminous → baguetteBox.js → GLightbox
Nuxtフロントエンド:
Nuxt3 → Nuxt4
VueQuill(Quill1) → Vue Quilly(Quill2) → Tiptap
Vuelidate → Regle
VCalendar → Vue Datepicker -
DBまわり
MySQL → PostgreSQL -
NoSQLキー/バリュー・ストアまわり
未導入 → Redis → Valkey -
画像プロキシ
未導入 → imgproxy -
CSSまわり
Bootstrap 4 → 5 → Tailwind CSS v4 + daisyUI v5
最後に
Nuxt3/4いいよ、Nuxt3/4!
上記アプリのSPA化に掛かった期間はちょろちょろ作成で数週間。
(初めての Nuxt3 アプリ作成、Nuxtを触るのも初めて、でした。)
Next.js/Remix v2(React) / TanStack Start(React/Solid.js)で 数週間で?RailsアプリをSPA化するのは、今のところ、自分には無理... と、以前、書いていましたが、面倒くさがらなければ、今なら時間を掛ければできそうです、でも、面倒くさいので、しません、ハマりどころもありそうなので...。
コードの解説は書きません。
コードは、全てを識っている(嘘?です、書いてみただけです)。














