この記事は自分のブログ記事からの再掲です
最近新しいWebAppを作るときにVite + Vue3で作成することが多いです。その際に
npm create vite@latest
で設定することが多いです。設定するなかでページ遷移が必要だと判断した場合はvue-router
を使用します。
vue-router
でルーティングする構造を考えるときにいくつかの候補がありますがその中でポピュラーなのはHashモードとHistoryモードの二つです。
HashモードはURLに#
が入りますがサーバーへの通信を遷移に行わないですし設定が楽です。
それに対してHistoryモードはサーバーへの通信が必要になりますが#
が入らないのでモニタリングやアナリティクスツールでページごとのデータを取りたかったりした場合にはこちらが最適です。
Vue-Routerを入れたいケースというのがそもそもページ遷移が必要だったり直リンクによるページの再訪したかったりなので、どうしてもリダイレクトのコールバックURLからしか受け取れない値があるが基本的にはページ遷移を必要としない場合以外基本的にHistoryモードを使用することになるケースがほとんどだと思います。
現在自分が管理しているブログでもそうだったんですが、viteを開発のために走らせている状態ではhistoryモードを使っていると開発エンドポイントのベースURL"/"
以外への直接のアクセスでも遷移できるのでいつも忘れたままディプロイしてしまうことがあります。
しかしcreate viteで作成するとserveを使ってビルドファイルを提供することになっているもののこれはベースURLに対してのみindex.htmlを返すので、詳細なパスへの直リンクでは404になってしまいます。そこで後から全部のパスにたいしてindex.htmlを返す処理が必要になってサーバーサイドを簡素なexpress appで処理することになります。
つまづいでいる初学者のかたもいるかもなので参考に、最低限のレベルはこんな感じで実装できます
https://github.com/kenjiwilkins/kw-blog-client/index.ts
import * as express from "express";
import rateLimit from "express-rate-limit";
import * as logger from "morgan";
const app = express();
app.use(express.static(__dirname + "/dist"));
app.use(
rateLimit({
windowMs: 10000, // 1 minute
max: 5, // limit each IP to 5 requests per windowMs
message: "Too many requests, please try again later.",
})
);
app.use(logger("common"));
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
// return index.html to all routes
app.get("*", (req, res) => {
res.sendFile(__dirname + "/dist/index.html");
});
app.listen(process.env.PORT || 443, () => {
console.log(`Server started on port ${process.env.PORT || 443}`);
});
やっていることとしてはどのパスへのアクセスであってもindex.htmlを返してねという処理です。
僕はフロントエンドエンジニアとして働いているのもあって、バックエンド触るときというのはたとえばE2E行うためにモックAPI書いたりするぐらいなのでバックエンドエンジニアたちがよしなにやってくれることを忘れてしまっていて趣味のアプリで抜け落ちちゃうんですよね。頭が上がりませんね。
どなたかnpm serve の設定につかうserve.jsonファイルだけでこの設定できる方法ご存知ですかね? redirectオプションを使うと無限にリダイレクトしてtoo many redirectエラー返されてしまいますし。