You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 15:35:46