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

Node.js TS单例模块共享变量异常:修改后值未同步

解决单例实例在动态导入中未同步的问题

我遇到过类似的模块共享问题,虽然你的Singleton类逻辑看似正确,但在实际构建或模块加载流程中,可能出现实例状态没有被正确同步的情况。下面是几个可行的解决方案,按推荐优先级排序:

方案一:利用ES模块的天然单例特性(最推荐)

ES模块本身就是单例的——每个模块只会被加载执行一次,导出的对象/变量会被所有导入者共享同一个引用。完全没必要额外写Singleton类,简化你的global.ts:

// global.ts
export const global = {
  foo: "aaa"
};

这样修改后,你原有的main.ts和part1.ts代码不需要做任何改动,运行后part1会输出test:bbb。因为所有导入的global都是同一个对象,属性修改会在所有地方实时生效。

方案二:修复Singleton类的实现(如果必须使用类结构)

如果你坚持要用类的单例模式,需要确保实例不会被意外重置,同时导出稳定的引用:

// global.ts
class Singleton { 
  private static instance: Singleton; 
  private _foo!: string; 
  private constructor() { } 
  static getInstance() { 
    if (!Singleton.instance) { 
      Singleton.instance = new Singleton(); 
      Singleton.instance._foo = "aaa"; 
    } 
    return Singleton.instance; 
  } 
  get foo(): string { return this._foo; } 
  set foo(txt: string) { this._foo = txt; } 
}
// 直接导出单例实例,确保所有导入者拿到同一个引用
export const global = Singleton.getInstance();

另外,如果你在开发环境使用了热模块替换(HMR),HMR可能会重新加载模块导致单例实例被重置。可以添加HMR兼容代码来保留实例:

// global.ts 末尾添加HMR处理
if (module.hot) {
  module.hot.accept();
  // 热更新时恢复之前的实例
  if (module.hot.data?.instance) {
    Singleton.instance = module.hot.data.instance;
  }
  // 热更新前保存当前实例
  module.hot.dispose(data => {
    data.instance = Singleton.instance;
  });
}

方案三:检查模块导入路径

确保main.ts和part1.ts中导入global模块的路径完全一致。比如如果part1.ts在子目录中,导入路径应该是../global而不是./global——路径不一致会被模块解析器视为不同的模块,导致创建多个Singleton实例。


内容的提问来源于stack exchange,提问作者Mauro Sala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:42:45