页面刷新触发ReferenceError:无法在初始化前访问BaseRepository
问题描述
我有如下代码结构:
BaseRepository抽象类:包含Axios客户端实例和通用方法AuthRepository类:继承自BaseRepositoryAuthService模块:通过AuthRepository处理登录及登录状态检查
打开路由时会向API发送请求,在Axios请求拦截器中使用AuthService获取并验证token完成授权:如果能获取到token就添加到请求头,否则跳转到登录页重新登录。
首次从登录页登录并使用Web应用时一切正常,但刷新页面时会出现错误:ReferenceError: can't access lexical declaration 'BaseRepository' before initialization
BaseRepository 代码
import { BackendClient } from "@/repositories/clients"; import type { AxiosError, AxiosInstance, AxiosResponse } from "axios"; // 其他导入 export default abstract class BaseRepository { protected readonly client: AxiosInstance = BackendClient; // 通用方法 }
AuthRepository 代码
import { BaseRepository } from "@/repositories/base"; class AuthRepository extends BaseRepository { constructor() { super() } // 其他方法 } const authRepository = new AuthRepository(); export default authRepository;
Axios Client(BackendClient)代码
import axios, { type AxiosInstance } from "axios"; import { AuthService } from "@/modules/auth"; import router from "@/router"; import appConfig from "@/config"; const client: AxiosInstance = axios.create({ baseURL: appConfig.backendClient.baseUrl, headers: { "Access-Control-Allow-Origin": "*", }, validateStatus: (status: number): boolean => { var isValid = (status < 400 || status == 401); console.log("requestvalidatestatus", isValid); return isValid; } }) const TOKEN_EXCLUDE_ENDPOINTS = [ 'Auth/Login', 'Auth/Register', 'Auth/RefreshAccessToken' ] client.interceptors.request.use(async (config) => { var requestUrl = config.url; for(var excludeEndpoint of TOKEN_EXCLUDE_ENDPOINTS) { if(requestUrl?.startsWith(excludeEndpoint)){ return config; } } var token = await AuthService.getAccessToken(); if(!token) { router.push('/login'); } console.log("token",token); config.headers.Authorization = `Bearer ${token}`; return config; }) export default client;
AuthService 代码
import { AuthRepository } from "@/repositories"; class AuthService { async login(request: LoginRequest, rememberMe: boolean, forceLogin: boolean = false) { // 其他逻辑 return await AuthRepository.login(request); } // 其他方法 } const authService = new AuthService(); export default authService;
问题原因分析
这个错误的核心是循环依赖导致的模块初始化顺序混乱,具体依赖链如下:
BaseRepository直接导入并初始化了BackendClient(Axios实例)BackendClient顶部静态导入了AuthServiceAuthService导入了AuthRepositoryAuthRepository又继承自BaseRepository
刷新页面时,应用会重新启动并触发路由相关的API请求,此时模块初始化顺序被打乱:
- Axios拦截器会提前执行,此时
BaseRepository还未完成初始化,但AuthRepository已经在尝试继承它,而AuthRepository又被AuthService引用,AuthService又在拦截器里被调用,最终触发了"无法在初始化前访问变量"的错误。
首次登录正常是因为初始化顺序是从登录页开始,模块是按依赖顺序逐步加载的,没有触发提前执行的拦截器逻辑。
内容的提问来源于stack exchange,提问作者Eren Sönmez
相关产品推荐
相关产品推荐

