静态初始化引起的pinia报错

Pinia 在应用注册前被静态初始化时触发 getActivePinia 报错的原因与解决方式。

#tech / dev / frame #resource / vue3 #type / howto #status / evergreen

静态初始化引起的pinia报错

[!info] related notes


报错信息:

pinia.js?v=e344808b:5731 Uncaught Error: [🍍]: "getActivePinia()" was called but there was no active Pinia. Are you trying to use a store before calling "app.use(pinia)"?
See https://pinia.vuejs.org/core-concepts/outside-component-usage.html for help.
This will fail in production.
    at useStore (pinia.js?v=e344808b:5731:13)
    at new GoalApplicationService (goalApplicationService.ts:9:31)
    at <static_initializer> (goalEventHandlers.ts:6:32)
    at goalEventHandlers.ts:1:1

问题相关代码

export class GoalEventHandlers {
  private static goalService = new GoalApplicationService();
}
export class GoalApplicationService {
    private readonly goalRepository: ReturnType<typeof useGoalStore>;
    constructor() {
        // 初始化GoalStore
        this.goalRepository = useGoalStore();
    }
}

app.mount('#app')
  .$nextTick(() => {
    // 初始化所有插件
    window.shared.ipcRenderer.on('main-process-message', (_event: any, message: any) => {
      console.log(message)
    })
    EventSystem.initialize();
  })

报错原因

众所周知,ts 是静态编译的,是指在模块加载时就执行的代码,而不是在实例创建或方法调用时执行,这就会导致提前执行相关代码。

EventSystem 会初始化 GoalEventHandlers,而 GoalEventHandlers 会获取 GoalApplicationService 的实例;GoalApplicationService 则会调用 pinia

静态编译顺序:

1. 引擎启动
2. 解析 main.ts
3. 解析 import 语句链
   ├── import EventSystem
   ├── import GoalEventHandlers  ← 🎯 这里!
   └── import GoalApplicationService
4. 执行静态初始化代码
5. 创建 Vue 应用
6. 注册 Pinia

解决方法

延迟执行

export class GoalEventHandlers {
  private static goalService: GoalApplicationService | null = null;

  // 延迟获取服务实例
  private static getGoalService(): GoalApplicationService {
    if (!this.goalService) {
      this.goalService = new GoalApplicationService();
    }
    return this.goalService;
  }
}

在后面的函数中再调用 getGoalService 来生成 goalService 实例,避免在刚加载时生成。

创建于 2025/1/1 更新于 2026/5/27