Vue 3 + Pinia 環境で発生する「Cannot access ‘router’ before initialization」エラーの解決方法
エラーの概要と発生条件
Vue 3 アプリケーションで以下のようなエラーが発生することがあります。
このエラーって、いつどういうときに出るの?
ReferenceError: Cannot access 'router' before initialization というこのエラーは、Vue Router を app に組み込む前に、router オブジェクトを使用しようとした場合に発生します。特に循環参照が原因となるケースが多いです。
循環参照があると、まだ初期化されていない router を呼び出してしまうんだ。
原因の具体的なパターン
今回の例では、次のような依存関係の循環がありました。
どういう構造がまずいの?
main.ts → router/index.ts → stores/auth.ts → main.ts というループが存在しており、router の初期化前に main.ts が読み込まれることで、router の参照に失敗しています。
こういうときは、依存を切り離して別モジュールに逃がすのが定番だね。
解決策:Firebase 初期化処理の分離
循環参照を防ぐため、Firebase 関連の初期化処理を main.ts から分離し、firebase.ts という新しいモジュールに移動します。
Firebase の初期化が main.ts にあるのが原因ってこと?
はい。auth ストアが Firebase の auth オブジェクトを使いたくて main.ts を参照しており、これが循環参照の原因です。そこで、Firebase 初期化コードを firebase.ts に分けて、両者が独立に firebase.ts を参照するようにします。
依存の分離によって、main.ts に戻らない構造を作るのがポイント!
firebase.ts の内容
// firebase.ts
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
const firebaseConfig = {
// your firebase config
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
export { app, auth };
main.ts の修正
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { auth } from './firebase'; // 修正箇所
const app = createApp(App);
app.use(router);
app.mount('#app');
auth.ts の修正
// auth.ts
import { defineStore } from 'pinia';
import { auth } from '../firebase'; // main.ts ではなく firebase.ts を参照
export const useAuthStore = defineStore('auth', {
// state, actions など
});
まとめ
Vue プロジェクトで循環参照が発生すると、初期化前の変数参照によるエラーに繋がります。
チェックリスト!まずは依存関係を整理→分離→再構築の順で修正しよう。


コメント