Svelteルーティングライブラリ'Routify'についてまとめる
Routify を選定するまで
Routify とは
Svelteにて使用するルーティングライブラリになるもの。SvelteはコンパイルしてHTML/CSS/JSを生成するものでRouterのような機能は用意されておらず、RoutifyのようなRouterを活用してSPAを作成していく。
なぜ Routify か
既存のプロジェクトにおいてpage.jsを使用してルーティングを行なっていた。見た目はSPAになっておりルーティングされているが、ページの永続化が実現できていなかった。
そのために上記のようなRouterにあたるものを使用する経緯となった。
他にも'svelte-routing'や'svelte-spa-router'などの他ライブラリももちろんありました。
ですが、ドキュメントの細かさ、記述の方法(これは個人の意見が大きいかもしれません)においてRoutifyがいいかなと思い選定しました。
こちらRoutifyのドキュメントになります。
使用方法
インストール
npm i -D @roxi/routify npm-run-all
package.jsonへの記述
"scripts": {
"webpack": "webpack",
+ "routify": "routify",
+ "build": "routify -b && webpack --mode production",
- "build": "webpack --mode production",
+ "watch:routify": "routify",
+ "watch:webpack": "webpack --mode development --watch",
+ "dev": "run-p watch:*",
- "dev": "webpack --mode development --watch",
"start": "sirv public --single"
},
コマンドについて
公式ドキュメントから
routify -b is shorthand for routify --single-build. Single-build doesn’t watch for file changes and produces a leaner routes.js file.
routify -b は、routify --single-build の省略形です。シングルビルドはファイルの変更を監視せず、無駄のない routes.js ファイルを生成します。(日本語訳)
Note: You might also want to add the .routify folder to .gitignore, since it is only needed during development.
注: 開発中にのみ必要になるため、.routify フォルダーを .gitignore に追加することもできます。(日本語訳)
run-p
コマンドはroutifyと一緒にインストールしたnpm-run-all
をインストールしていれば使用できた。
(自分はそれに気が付かずインストールしておらず、routify & webpack --mode development --watch
としてしまいRoutifyが監視状態になり処理が終了せずwebpackのビルドへ移行しなかった。)
記述方法について
ルートファイルのApp.svelteへ下記の記述を行う
<script>
import { Router } from "@roxi/routify";
import { routes } from "../.routify/routes";
</script>
<Router {routes} />
構成について
どのようにしてURLごとに設定を行うかについてのイメージについて、SvelteのフレームワークであるSvelte Kitのような記述になると思っている。
In Routify, files in src/pages correspond to URLs.
Routify では/src/pages
内のファイルが URL に対応します。(日本語訳)
- /pages
- _layout.svelte
- /blog
- index.svelte → /blog
- /blog
- [post].svelte → /blog/:post
- about.svelte → /about
- index.svelte → /
基本はこのようにファイル、またはディレクトリ名がURLとしてマッピングされることになる。
- index.svelteは
/
の扱いになる - [post].svelteのような記述になる場合は、パラメータとしてpost=xxxxxxとして取得できる
Files and directories prefixed with an underscore will not be picked up by Routify.
アンダースコアで始まるファイルとディレクトリは、Routify によって取得されません。(日本語)
404s can be caught with _fallback.svelte. The first _fallback.svelte that's found while traversing back through parent folders will be used.
404 は _fallback.svelte でキャッチできます。親フォルダーをトラバースして戻るときに見つかった最初の _fallback.svelte が使用されます。(日本語)
今では標準だと思うが、このように404ページが用意されているのは個人的には嬉しい
ルーティング設定について追記(2023/5/8)
下記のように二つのURLのパターンがあったとする
- /users/1/account
- /users/example
前者は
/users
/[id]
/account
と設定できるが後者の場合は/exampleの部分が先ほど設定した/[id]と重なってしまう。
試した結果
/users
/[id]
exmaple.svelte
/account
とすると、[id]のワイルドカードの値の一つとして扱われる。
/users
/exmaple
/[id]
/account
とすると、/exampleとして/users/exampleに一致するのでそのコンポーネントを表示してくれる。
さらに追記
ルーティングのパスの優先順位について
/xxxx/a
にアクセスしたい場合、
/xxxx配下にある
- ディレクトリ名
- パスに一致するファイル名(上記例だとa.svelte)
- ワイルドカードに設定しているファイル
の順番に表示される優先順位が設定される。
パラメータについて
下記のように記述する
<script>
import { params } from "@roxi/routify";
export let post
$: post = $params.post
</script>
インポートしたparamsをデコレータとして使用し、/blog/100
と100という値を取得したい場合、[post]の部分がワイルドカードとなる。後述するがクエリパラメータやaタグ内のhref属性についても$url
のようにデコレータとして機能を活用できる。
レイアウトについて
基本的には下記にある_layout.svelteにてコンポーネントのラッピングを行う。
サンプルコード
<slot>
<!-- この部分で設定したルーティングが行われる -->
</slot>
Layouts are recursive, so whenever a page is displayed, all layouts from all its parent folders are applied. Layouts must always have a
<slot>
tag.
レイアウトは再帰的であるため、ページが表示されるたびに、すべての親フォルダーのすべてのレイアウトが適用されます。 レイアウトには常に<slot>
タグが必要です。(日本語)
SSR、SSGについて
サポートはされているが今回は使用していないので割愛させていただきます。
ナビゲーションについて
aタグを使用したナビゲーションは下記の通り
import { url } from "@roxi/routify";
<a href={$url('/introduction')}>
A link to the introduction section on your left
</a>
-
URL
http://localhost:8000/introduction
-
/src/pages/introduction/index.svelte or /src/pages/introduction.svelte が描写される
$url
は単なるリンクではなく、現在配置されているレイアウトに相対的な値にする -
$isActive
のようなヘルパーも用意されている(後述に記載)
Helpers について
今回routifyを使用する上で主に使用した機能
$url
- /src/pages配下にあるファイル、ディレクトリに関するパスをうまくまとめ、ブラウザのURLの影響を受けないURLとなる。
$url
をつけないパスの場合はページ自体が読み込まれる。
$isActive
- 指定されたパスと現在の位置が一致するか判別してくれます。active時にスタイルを変える際に使用。
$goto
- プログラムによりナビゲーションしてくれる。
$params
- パラメーターを受け取りたい時に使用。[]内に指定した値がキーとして取得できるようになる。
$metatags
- ページのメタデータを設定する際に使用する。主にtitleやdescriptionになる。
$afterPageLoad
- ページが読み込まれた後に呼び出される。ページ自体が読み込まれるより、コンポーネントが切り替わるイメージなのでタブを切り替えた後にAPIを叩く。などに使用した。
$isChangingPage
- ページが読み込まれている場合はtrueを返す。ローディング画面などユーザビリティを下げないために使用した。
他にも使用できる機能や、紹介した機能の詳細などは下記をご覧ください。
Config について
今回は例としてドキュメントにそってシンプルな/src/pages
としましたが、実際のプロジェクトになると一貫していかないと思うのでConfigファイルを少しだけですが紹介します。
設定場所
下記のように種類があります。
上から順に優先順位が高いようです。今回は自分は2番目のroutify.config.js
を使用しました。
Location | Example | Case style |
---|---|---|
package.json | "routify": {"routifyDir": ".routify"} | camelCase |
routify.config.js | module.exports = { routifyDir: '.routify'} | camelCase |
.env | ROUTIFY_DIR=.routify | SNAKE_CASE |
CLI | npx routify --routify-dir .routify | kebab-case |
設定したオプション
-
pages
Default value./src/pages
- パスを設定ためにRoutifyに読み込ませるために/pagesディレクトリのパスを設定できる
2.sourceDir
Default valueドキュメントに記載なし
- 設定するHTMLファイルのパスを設定できる。ドキュメントに記載がなく、開発時に
npm run dev
を打った際に作成されたRoutifyのファイル群を見て設定できるか試したら無事できたので載せておく。
module.exports = {
sourceDir: './public/html',
pages: './src/interface/presenters/pages',
// childProcess: true,
}
デバックやignoreなど他機能はあるので詳細は下記をご覧ください。
まとめ
最後に選定にあたって、ドキュメントの充実さを上げましたが使用事例などネットで調べた際になかなか見つからなかったのがあり今回使用した機能などを中心に記事を書かせていただきました。もちろん他に便利な機能もあるのは承知ですがライブラリの移行をメインに行ったので今後も上記にあがらなかった機能を使用していくことになると思うので、その際は別記事でまたまとめていきたいと思います。
なるべくドキュメントに沿っていますが、自分なりの解釈が入っています。日本語の記事が少なかったので記事にさせていただきましたが、お手数ですが詳細を知りたい方はドキュメントの方をご覧になってください。
Discussion