Nuxt.js のような自動ルーティングを可能にする Vue CLI プラグインを作った

Nuxt.js という Vue.js で SSR をするアプリケーションが簡単に書けるフレームワークがあります。Nuxt.js は SSR だけでなく、webpack の設定やディレクトリ構造なども最初から決められており、規約がすでに存在することによる開発の効率化の面においても注目されています。

個人的に Nuxt.js で便利だと感じている機能にルーティングの自動解決レイアウト機能があります。通常の Vue Router を使ったアプリではルーティングの設定は自分で書く必要がありますが、Nuxt.js では pages/ ディレクトリ以下の構造から自動的にルーティングの設定を生成してくれます。また、Rails のレイアウトのように、各ページごとにレイアウトファイルを指定することができます。

これらの機能に慣れてしまうと、Nuxt.js を使っていないプロジェクトにおいて自分でルーティングの設定を書くのがとても面倒になってきたので、Nuxt.js じゃなくてもいい感じにする Vue CLI プラグインを書きました。

vue-cli-plugin-auto-routing

また、vue-cli-plugin-auto-routing は独立したパッケージを組み合わせているので Vue CLI プラグインを使えない環境の場合は以下の2つを直接使うと良いです。

vue-auto-routing: ルーティングの設定をディレクトリ構造から生成する webpack プラグイン
vue-router-layout: レイアウト機能を提供するコンポーネント

vue-cli-plugin-auto-routing の使い方

Vue CLI v3 用のプラグインなので、それで構築したプロジェクトでのみ使用することができます。Vue CLI v3 でプロジェクトを生成するには以下のようにします。

# vue-cli v3 をインストール
$ npm install -g @vue/cli

# プロジェクトを作成
$ vue create new-project

vue-cli-plugin-auto-routing を使うにはプロジェクトのディレクトリ内で以下のコマンドを実行します。

$ vue add auto-routing

これを実行すると router.js が書き換えられ、layouts/, pages/ ディレクトリが追加されます。これらのディレクトリ内にファイルを追加すると、Nuxt.js と同様に動作することがわかると思います。

vue-auto-routing と vue-router-layout

vue-cli-plugin-auto-routing で生成された router.js を見ると以下のように記述されています。

import Vue from 'vue'
import Router from 'vue-router'
import routes from 'vue-auto-routing'
import { createRouterLayout } from 'vue-router-layout'

Vue.use(Router)

const RouterLayout = createRouterLayout(layout => {
  return import(`@/layouts/${layout}.vue`)
})

export default new Router({
  routes: [
    {
      path: '/',
      component: RouterLayout,
      children: routes
    }
  ]
})

vue-auto-routingpages/ 以下のディレクトリ構造からルーティングを生成しています。vue-router-layout は現在表示されているコンポーネントに指定されているレイアウトを layouts 以下から選択して描画するためのコンポーネントです。createRouterLayout のコールバックでレイアウトのコンポーネントを返しています。

Nuxt.js と異なり、Vue Router の設定は隠蔽されていないので、カスタマイズの幅は広いと思います。例えば、createRouterLayout のコールバックを書き換えてレイアウトの解決の仕方を変えたり、routes に追加のルーティングを増やしたりできます。

Vue CLI v3 が使えない場合はこれらのライブラリを直接使うことができます。詳細な使い方は vue-auto-routingvue-router-layout の README を読んでください。

まとめ

Nuxt.js を使っていないプロジェクトにおいても pages/layouts/ 機能を使えるようにする Vue CLI プラグイン vue-cli-plugin-auto-routing を作りました。Vue CLI プラグインが使えない環境では vue-auto-routingvue-router-layout を使うことで同じ機能を使えるようにできます。

Vue Router のルーティングはいろいろと細かく設定できますが、実際に開発していると Nuxt.js のルーティングで十分に感じます。これからはルーティングの設定を手で書くことは少なくなっていくのではないかなーと思います。

vue-thin-modal v1.0.0 をリリースしました

去年から作っていた Vue のモーダルコンポーネント vue-thin-modal の v1.0.0 をリリースしました。仕事でも結構使っていて、特に大きな問題もなく、API も安定しているのでメジャーバージョンを上げました。

vue-thin-modal は世の中の多くのつらいモーダル実装を見て、つらくならなくするために作ったライブラリです。主に以下のような特徴があります。

  • モーダルはどこに置いても DOM の実態は <body> 直下にマウントされる (いわゆる Portal)。
  • モーダルが開くと通常のコンテンツ部分はスクロールが止まる。モーダル内のコンテンツがウィンドウサイズを超えてもスクロールできる。
    • これで発生する、スクロールバーが消えることによるガタツキを防ぐ実装もしている。
  • モーダルを閉じたときに元のコンテンツにフォーカスを戻す。
  • デフォルトの CSS スタイルが提供されていて、何もしなくてもそれっぽく動く。
  • 背景とモーダルコンテンツのトランジションが独立していて、柔軟に設定できる。
  • モーダルの表示はスタックで管理していて、モーダルの上にモーダルとかもやろうと思えばできる (UI 的にどうなんだというのは置いといて)。

モーダルのつらさについては CodeGrid 5周年記念パーティーで話しているので、そのスライドも見てみてください。

vue-thin-modal を作る際には Bootstrap ModalModaal をかなり参考にしました。特に Bootstrap Modal の作り込みはすごくて、その完成度の高さに驚いた覚えがあります。

関連ライブラリとして vuex-modal というものもあります。こちらは vue-thin-modal を作る前に作ったものですが、今は内部で vue-thin-modal を使用しています。

自分の欲しい機能はすべて実装したので、これからの展望は特にないですが、バグレポートや機能要望などは歓迎です!