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

NextJS开发环境下Map实例因热重载重置问题求助

Next.js开发环境热重载导致Map实例重置问题

在Next.js开发环境中,热重载会重置downloadTokens这个Map实例,生产构建运行后该问题消失。以下是相关代码、调试日志及解决思路:

相关代码

1. Map模块代码

const downloadTokens = new Map<string, string>(); console.log("instance created") export default downloadTokens;

2. API处理器代码

import * as fs from 'fs';
import {NextApiRequest, NextApiResponse} from "next";
import {getProductCode} from "@/store/schematic/DownloadToken";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    if (req.method != 'GET')
        return res.status(400).json({status: 400, messages: "Invalid method, instead make a get request!"})

    const downloadToken = req.headers['authorization'];
    if (!downloadToken)
        return res.status(400).json({status: 400, messages: "Invalid token!"})

    const productCode = getProductCode(downloadToken as string);
    const fileName = `${productCode}.schematic`

    const fileBuffer = fs.readFileSync(`${process.cwd()}/data/schematics/${fileName}`);
    if (fileBuffer.length == 0)
        return res.status(500).json({status: 500, messages: "Unable to find the schematic file. Please contact the administrator."})
    const blob = Buffer.from(fileBuffer);

    res.setHeader("Content-Type", "application/octet-stream");
    res.setHeader("Content-Disposition", `attachment; filename=${fileName}`)
    return res.status(200).send(blob);
}

3. DownloadToken工具函数

import {randomUUID} from "node:crypto";
import downloadTokens from "./DownloadTokenMap";

console.log(`downloadTokens instance : ${downloadTokens}`);

export function generate(productCode: string): string {
    const token = randomUUID();
    downloadTokens.set(token, productCode);
    console.log(downloadTokens)
    return token;
}

export function getProductCode(token: string): string | null {
    const productCode = downloadTokens.get(token);
    console.log(downloadTokens)
    return productCode ? productCode : null;
}

调试日志

✓ Compiled /api/capture in 111ms (145 modules)
instance created
downloadTokens instance : [object Map]
Map(1) {
  'b85801bd-6e9c-4af7-aa4a-35d5530b5ed9' => 'SC-SKYBLOCK_LOBBY-1'
}
 POST /api/capture?orderId=xxxx 200 in 2132ms
✓ Compiled in 305ms (762 modules)
✓ Compiled /api/download/schematic in 44ms (148 modules)
instance created
downloadTokens instance : [object Map]
Map(0) {}
 ⨯ Error: ENOENT: no such file or directory, open '/Users/...

原因及解决思路

问题根源

Next.js开发环境的热重载机制会在代码变更时重新加载相关模块,模块级别的变量(如这个Map实例)会在每次重载时重新初始化,导致之前存储的token数据丢失。生产环境中代码是一次性构建加载,不存在模块重载,因此问题不会出现。

解决方案

  1. 使用Node.js全局对象存储
    将Map挂载到global对象上,确保模块重载时实例不会被重置:

    // DownloadTokenMap.ts
    declare global {
      var downloadTokens: Map<string, string>;
    }
    
    // 仅在全局对象未初始化时创建实例
    if (!global.downloadTokens) {
      global.downloadTokens = new Map<string, string>();
      console.log("instance created");
    }
    
    export default global.downloadTokens;
    

    该方案适合开发环境临时使用,注意添加全局变量的TypeScript类型声明以避免语法报错。

  2. 改用持久化外部存储
    如果需要数据在服务重启后保留,或者适配多实例部署场景,建议使用Redis、数据库等外部存储替代内存Map,开发和生产环境都能保持数据一致性。

  3. 禁用特定模块热重载(不推荐)
    可在next.config.js中配置,对包含Map的模块禁用热重载,但会降低开发效率,仅作为临时应急方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 17:19:57