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

JavaScript:多文件导入类实例时如何保持单例同步?

How to Share a Single Security Instance Across Multiple ES Modules?

Let's break down why you're seeing separate instances and how to fix this:

First, Understand the Root Cause

ES modules are designed to be singletons by default—when you import the same module multiple times, it should only execute once, and all imports reference the same exported value. The fact that you're getting separate instances almost always means your module is being loaded multiple times, not that your singleton pattern is broken. Common reasons include:

  • Inconsistent import paths (e.g., mixing aliases like @/security with relative paths like ../security)
  • Build tool or runtime configuration issues (like incorrect module resolution in your development environment)
  • Cache inconsistencies in your dev server or browser

Fix 1: Ensure Consistent Import Paths

Double-check that every file importing the Security module uses the exact same path. For example:

  • If you use import security from "@/security" in file1.js, make sure file2.js uses the exact same line—don't switch to import security from "./security" or another variant.
  • Verify your alias configuration (if you're using one like @) is set up correctly across your project so all paths resolve to the same file.

Fix 2: Validate Your Singleton Implementation (Optional but Robust)

Your singleton code is mostly correct, but we can make it more foolproof by preventing external instantiation with a private constructor:

import crypto from 'crypto';
const deleteMillis = 3600 * 1000;

class Security {
    activeSessions: Record<string, { ua: string }>;
    private static instance: Security;

    // Private constructor stops external code from creating new instances
    private constructor() {
        this.activeSessions = {};
        console.log("Security instance initialized ONCE"); // Use this to confirm only one instance is made
    }

    getSession(session: string, ua: string): { ua: string } | undefined {
        const currentSession = this.activeSessions[session];
        if (!currentSession) return;
        if (ua !== currentSession.ua) return;
        return currentSession;
    }

    addSession(ua: string): string {
        const session = crypto.randomUUID();
        this.activeSessions[session] = { ua };
        setTimeout(() => this.removeSession(session), deleteMillis);
        return session;
    }

    removeSession(session: string): void {
        delete this.activeSessions[session];
    }

    static getInstance(): Security {
        if (!Security.instance) {
            Security.instance = new Security();
        }
        return Security.instance;
    }
}

// Export the single instance
const security = Security.getInstance();
export default security;

Fix 3: Check Your Runtime/Build Configuration

If you're using a dev environment like CodeSandbox or a bundler like Webpack/Vite:

  • Clear the browser cache and restart your dev server to rule out stale module caches.
  • For Node.js projects: Ensure your package.json has "type": "module" set to enable proper ES module behavior.
  • For TypeScript projects: Verify tsconfig.json has moduleResolution set to NodeNext or Node16 to ensure consistent module resolution across files.

Alternative: Stick to the Original Module (No Singleton Pattern Needed)

Remember—ES modules are singletons by default! Your original code (without the singleton pattern) should work if the module is loaded once. Add a top-level console log to confirm if your module is being loaded multiple times:

// In security.js
console.log("Security module loaded");
const security = new Security();
export default security;

If this log appears more than once in your console, your module is being loaded multiple times—fix the path/configuration issue first, and your original code will work as intended.

内容的提问来源于stack exchange,提问作者Shivam Sahil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:05:24