はじめに
React+Vite+BrowserRouterで、STGや本番環境に/プロジェクト名/配下へデプロイするケースはよくあります。
このとき、リロードした際に画像が見えなくなる/ページ遷移が想定通りにいかないことがあります。
原因はBrowserRouterがルートパス/を起点とするため、画像やリンクが相対パスではなく現在のパスを基準に探してしまうからです。
これを解決するためには、Viteのbase設定を正しく行い、import.meta.env.BASE_URLを使ってリソースパスを統一することが重要です。
本記事では環境ごとにvite.config.tsでbaseを切り替え、リロードしても画像が消えない設定方法をまとめます。
Vitebase
とは?
Viteのbase
は、ビルド後の静的ファイルがどこに配置されるか決定するものです。
base: "/site-lp/"
と書くと、画像やCSSの参照はすべて /site-lp/
が先頭につきます。
開発/STG/本番でのbase
切り替え方
.env
を使わない方法。
①vite.Config.ts に環境分岐を書く
ポイント
const isStg = mode === "stg";
const basePath = isStg ? "/site-lp/" : "/";
全体
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import pkg from "./package.json" assert { type: "json" };
export default defineConfig(({ mode }) => {
const isStg = mode === "stg";
const basePath = isStg ? "/site-lp/" : "/";
return {
base: basePath,
plugins: [
react({
babel: {
plugins: ["@emotion/babel-plugin"],
},
}),
],
define: {
"import.meta.env.VITE_APP_VERSION": JSON.stringify(pkg.version),
},
};
});
②コマンドで mode
を渡す
環境 | コマンド | URL |
---|---|---|
開発 | vite dev |
http://localhost:5173/ |
STG | vite build --mode stg |
/site-lp/ 配下で公開 |
本番 | vite build --mode prod |
/ 配下で公開 |
import.meta.env.BASE_URL
を活用する
環境に依存せず、こう書けば安全。
<img src={`${import.meta.env.BASE_URL}icon/xxx.svg`} />
環境 | BASE_URL | 生成されるURL |
---|---|---|
開発 | / |
/icon/xxx.svg |
STG | /site-lp/ |
/site-lp/icon/xxx.svg |
本番 | / |
/icon/xxx.svg |
【補足】開発環境でも STG の動作を確認したい場合
vite dev --mode stg
とすれば、ローカルでも http://localhost:5173/site-lp/
配下で動く。
なぜリロードで壊れるのか
パスの解決が相対ではなく現在のパス基準になるからです。
例) /news/2 にいると、icon/xxx.svg → /news/2/icon/xxx.svg を探しにいってしまう。
まとめ
環境 | base | URL | コマンド |
---|---|---|---|
開発 | / |
http://localhost:5173/ |
vite dev |
STG | /site-lp/ |
/site-lp/ |
vite build --mode stg |
本番 | / |
/ |
vite build --mode prod |
- 開発は
/
前提で問題ない - STG/本番は
mode
に応じて切替 - パスは
import.meta.env.BASE_URL
を使えば共通化できる -
.env
を使わなくてもvite.config.ts
だけで対応可能 - BrowserRouter使用時はサーバーの設定も必要