結局inertia.js + react + viteでリモートホストでHMRするにはどうしたらいいのか
令和ももう7年にもなって、blade
を使っているとしても 今時流石にbladeファイルを書いてF5とか押してる人はいないよな? jsはビルドしないとだからHMR
せざるを得ないから頑張ってる人がほとんどだろうけど、
それにしてもリモートに繋いでのHMR
する情報が少ない、リモートに繋いで何かコード書いてる人なんてあんまおらんからか...
HMRの設定(ベタな奴)
たとえば接続先が 35.72.31.192
であったら
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
export default defineConfig({
server: {
hmr: {
host: '35.72.31.192', // <-------- ここにベタベタなホスト記入
}
},
plugins: [
laravel({
input: 'resources/js/app.jsx',
refresh: true,
}),
react(),
],
});
基本、こんな事にしてあげればいい。まあ確かに動くっちゃ動く。
ただし、これはcommitするファイルなのでここにグローバルIPをベタっと書きたくないだろう。
これを評価しているファイル
node_modules/laravel-vite-plugin/dist/index.js 基本的にはこの中で色々やっている。ただし、この中のソースコードを読んでも特殊な環境変数をセットしたからそれが使われるという事は無さそうだ。
駄目なやつ(process.env.VITE_HMR_HOSTとかを取りに行く)
VITE_HMR_HOST
という変数を定義して .env に書いたとしよう。
VITE_HMR_HOST=35.72.31.192
この時以下のようにしてprocess.env.VITE_HMR_HOST
で取れるんじゃないかと思ったりしたが
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
console.log(process.env.VITE_HMR_HOST); // -> undefinedになる
export default defineConfig({
server: {
hmr: {
host: process.env.VITE_HMR_HOST || 'localhost',
}
},
plugins: [
laravel({
input: 'resources/js/app.jsx',
refresh: true,
}),
react(),
],
});
vite.config.jsを読む時点では .env は評価されておらず、これは使えない。
まあとりいそぎ環境変数はぶっこまれてるみたいだからnpmする時に環境変数つっこんでやればそれはそれでいいのかもしれんけどやっぱり .env に書きたい。
微妙に駄目なやつ(dotenvを使った事前読み込み)
というか今までこの方法でやっていたりした
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
import dotenv from 'dotenv';
// .env ファイルを読み込む
dotenv.config();
console.log('VITE_HMR_HOST:', process.env.VITE_HMR_HOST);
export default defineConfig({
server: {
hmr: {
host: process.env.VITE_HMR_HOST || 'localhost',
},
},
plugins: [
laravel({
input: 'resources/js/app.jsx',
refresh: true,
}),
react(),
],
});
これを行うと
VITE_HMR_HOST: 35.72.31.192
などとなり、一見よさそうだが
function resolveLaravelPlugin(pluginConfig) {
let viteDevServerUrl;
let resolvedConfig;
let userConfig;
const defaultAliases = {
"@": "/resources/js"
};
return {
name: "laravel",
enforce: "post",
config: (config, { command, mode }) => {
userConfig = config;
const ssr = !!userConfig.build?.ssr;
const env = loadEnv(mode, userConfig.envDir || process.cwd(), "");
console.log(env); // ここでenvの内容をdumpしてみる
とかすると
VITE_APP_NAME: '${APP_NAME}',
VITE_HMR_HOST: '35.72.31.192',
こうなっちゃう。すると
${APP_NAME}がそのまま展開されとる
こんな感じのtitleになってしまい見苦しい。これはおそらくenvの展開が2度行われちゃっているためなんじゃないかなと思う。
// dotenv.config();
とすれば
VITE_APP_NAME: 'Laravel',
VITE_HMR_HOST: '35.72.31.192',
このように正しく展開されている。グムム...
今までやってきたこと
if (process.env.NODE_ENV !== 'production') {
dotenv.config();
}
こんな風にして npm run build
の時だけdotenv.config()
しないようにとかいう小細工をしてきた、これはこれで流石に辛い
一応の解決: viteのloadEnvを使う
import { defineConfig, loadEnv } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
const host = env.VITE_HMR_HOST || (env.APP_URL ? new URL(env.APP_URL).host : 'localhost');
return {
server: {
hmr: {
host: host,
},
},
plugins: [
laravel({
input: 'resources/js/app.jsx',
refresh: true,
}),
react(),
],
};
});
こんな風にvite
のloadEnv
を呼びこんできて、これで評価する。これで何とかなるようだ。
この辺の設定込みのbleeze 初期ツリーをどこかに置こうかな
それでは今回は短い記事で失礼します。Happy web developping!
Discussion