无法在 NextJS 15 中使用共享变量

问题描述 投票:0回答:1

最少的代码

https://codesandbox.io/p/devbox/vqfy8t

问题

我尝试实例化一个类(Vault)

我希望在 nextJS 中的两个路由之间共享一个变量
/send-email/
    route.ts
/confirm-email/
    route.ts

此变量的作用是使用生成的代码保存电子邮件 ID。并确认代码是否有效。

这是实例化Vault类的语法!

let instance: VaultType | undefined = undefined;
export function getOrCreateVaultInstance(keys?: Map<string, string>): Vault {
  if (instance === undefined) {
    console.info("✨ Creating a new vault instance ✨");
    instance = new Vault(keys);
  }

  return instance;
}

这就是我调用保险库的方式(在发送电子邮件和确认电子邮件中):

const vault = deps?.vault || getOrCreateVaultInstance();

deps 是传递给路由函数的可选参数。这仅用于测试目的。

但是为什么金库被实例化两次呢?我希望保管库仅创建 1 个实例,并且它应该在其他两条路由或任何其他所需的路由之间共享。

为什么会发生这种情况?
我想要什么

在两个 nextJs 路由之间创建单个实例。

我认为问题与 NextJS 有关。 我使用的是最新版本的 NextJS (v.15)

截至 chatGPT 没有帮助...... 我尝试将类移出,并将其类型转移到另一个文件。并创建了一个

vaultSingleton.ts
文件以便仅创建一次。

我尝试为每个路由文件调用一次

getOrCreateVaultInstance
,然后像这样使用它:

const vaultInstance = getOrCreatVaultInstance();

function POST(req, res, deps){ 
   const vault = deps?.vault || vaultInstance;
   // ...
}

什么都没有改变。还是看了两次

console.info("✨ Creating a new vault instance ✨");
...

最少代码: https://codesandbox.io/p/devbox/vqfy8t

node.js typescript next.js
1个回答
0
投票

可能是因为

Node.js
中的 Module Caching
https://nodejs.org/api/modules.html#modules_caching

模块缓存注意事项

模块根据其解析的文件名进行缓存。由于模块可能会根据调用模块的位置(从 node_modules 文件夹加载)解析为不同的文件名,因此如果 require('foo') 解析为不同的文件,则不能保证它始终返回完全相同的对象.

我发现的解决方法是使用

globalThis
对象

我尝试在您的codesandbox中使用

globalThis
,但它仅使用以下代码记录了
✨ Creating a new vault instance ✨
一次:

// Store the instance on globalThis for a singleton pattern
export function getOrCreateVaultInstance(keys?: Map<string, string>): Vault {
  if (!globalThis.__vaultInstance) {
    console.info(`✨ Created a vault instance ✨`);
    globalThis.__vaultInstance = new Vault(keys);
  }

  return globalThis.__vaultInstance;
}

// Type assertion to expose the instance as the Vault type
declare global {
  var __vaultInstance: Vault | undefined;
}

以下是我回答的一些问题:
nodejs 中的单例模式 - 需要吗?

希望这有帮助:)

© www.soinside.com 2019 - 2024. All rights reserved.