React LocationをElectronで使う方法
※本ページはプロモーションが含まれていますElectronでReact Locationを使うと、サーバを使ったローカル環境なら動きますが、buildしてファイルパスでのアクセスになると機能しなくなります。
公式ドキュメントによると、Memory Routingを使うとのこと。
書いてあるとおり、createMemoryHistoryにルートパスを設定し、ReactLocationに渡します。
import { createMemoryHistory, ReactLocation } from '@tanstack/react-location' // Create a memory history const memoryHistory = createMemoryHistory({ initialEntries: ['/'] // Pass your initial url }) // Set up a ReactLocation instance with the memory history const location = new ReactLocation({ history: memoryHistory, })
これで一応うまくいくのですが、新規ウィンドウを開くと、指定したURLではなくルートに設定したページが開かれるか、ファイルアクセスエラーが出ます。
力技ですが、lodadUrlをハッシュ使用のパスにし、「initialEntries」に表示させたいパスを入れる方法で解決しました。
メインプロセスで、別ウィンドウで開きたいURLをハッシュを使ってロードする。
// index.htmlまでのパス。index.htmlの後に「#」をつけ、その後にルーティングを書く。 const loadUrl = 'path/to/html/index.html#/hoge/fuga'; //ハッシュ付きのパスをロード window.loadUrl(loadUrl)
レンダープロセスでは、URLを解析して
// 現在のパスとハッシュプロパティをつなげる let path = window.location.pathname + window.location.hash; // index.htmlを探す let index = path.indexOf("index.html"); // index.htmlが存在したらパスを変更 if (index) { // ローカルパスからindex.html以降の値を取得。 const localPath = path.substring(index); // パスが「index.html」だけならpathをルートに設定 if (localPath === "index.html") { path = "/"; } else { // ハッシュパラメーターがある場合は、「index.html#」を取り除いてパスを作成 path = localPath.replace("index.html#", ""); } } // 開発環境では、「#」が残るので削除。 path = path.replace("#/", ""); // initialEntriesにpathを設定 const memoryHistory = createMemoryHistory({ initialEntries: [path], }); export const location = new ReactLocation({ history: memoryHistory });
後は「Router」の「location」で上記「location」を渡せばOK。
おわりに
スマートなやり方では無いですが、とりあえず動いて良かったです。
React Locationのloaderを使いたくてなんとか解決しました。
React RouterならhashRouterで簡単に解決します。