MSW Worker就绪前Vue请求失败,已尝试延迟挂载仍未解决
问题根源
你遇到的核心问题是:useMyStatefulComposable.ts中的allResquests是在模块顶层作用域执行的,Vite加载该模块时会立即触发这部分请求逻辑。而你的MSW Worker是异步启动的,模块加载过程不会等待Worker就绪,导致首次请求绕过MSW直接发送到真实服务器,最终失败。
解决方案
方案一:将请求移至组合式函数内部(推荐)
把顶层请求逻辑放到组合式函数里,并在组件挂载后执行,确保此时MSW已经就绪:
// useMyStatefulComposable.ts import { onMounted, ref } from 'vue' export const useMyStatefulComposable = () => { const myReactiveData = ref(null) const fetchData = async () => { const allRequests = await Promise.allSettled(urls.map(url => fetch(url))) // 处理请求结果并赋值 myReactiveData.value = allRequests } // 组件挂载后触发请求,此时MSW已启动 onMounted(() => { fetchData() }) return { myReactiveData } }
方案二:封装为懒加载的单例请求
如果需要保持请求只执行一次(多组件共用结果),可以把请求包装成懒加载函数,确保首次调用在MSW就绪后:
// useMyStatefulComposable.ts import { onMounted, ref } from 'vue' // 缓存请求Promise,确保只执行一次 let allRequestsPromise: Promise<PromiseSettledResult<Response>[]> | null = null const fetchAllRequests = async () => { if (!allRequestsPromise) { allRequestsPromise = Promise.allSettled(urls.map(url => fetch(url))) } return allRequestsPromise } export const useMyStatefulComposable = () => { const myReactiveData = ref(null) onMounted(async () => { // 组件挂载后调用,确保MSW已生效 const results = await fetchAllRequests() myReactiveData.value = results }) return { myReactiveData } }
方案三:延迟加载包含请求的模块
通过动态导入,把App组件及其依赖的模块延迟到MSW启动完成后再加载:
// main.ts import { createApp } from 'vue' import { router } from './routes' import { pinia } from './pinia.setup' import { onUnhandledRequest } from './mocks/browser' const prepareWorkers = async () => { if (process.env.NODE_ENV === 'development') { const { worker } = await import('./mocks/browser') await worker.start({ onUnhandledRequest }) } } prepareWorkers().then(async () => { // 动态导入App组件,确保依赖模块在MSW就绪后才加载 const { default: App } = await import('./App.vue') const app = createApp(App) app.use(pinia) app.use(router) app.mount('#app') })
补充说明
你之前的延迟挂载方案无效,是因为import App from './App.vue'会同步加载所有依赖模块(包括useMyStatefulComposable.ts),模块顶层的请求会在MSW启动前就执行。只有确保请求逻辑的执行时机晚于MSW Worker的就绪时间,才能被正常拦截。
内容的提问来源于stack exchange,提问作者Lyokolux
相关产品推荐
相关产品推荐

