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

Node.js更新JSON后报link属性读取错误的免重启修复方案

问题根因

报错和必须重启才能读到新内容的问题,本质是require()的加载机制导致的:

  • Node.js会对所有通过require()引入的模块、JSON文件做持久缓存,第一次加载完成后内容就存在内存中,后续调用直接读缓存,根本不会重新读取磁盘上更新后的文件
  • 如果你更新JSON时用的是覆盖写入逻辑,写入瞬间文件可能处于不完整状态,或者你调整了JSON内的键值对,缓存内容和磁盘实际文件不匹配,就会抛出读不到link属性的错误

可行方案

根据你的业务场景选就行,都不需要重启进程:

  • 方案1:改动最小,清除require缓存后重新加载
    不用改现有业务逻辑,只需要在读取sources前删掉对应缓存,强制Node重新从磁盘拉取最新文件即可:

    // 提前拿到JSON文件的绝对路径,注意要补全.json后缀
    const sourcesPath = require.resolve('../folder/sources.json')
    
    // 每次读取前清缓存
    delete require.cache[sourcesPath]
    const sources = require(sourcesPath)
    // *记得加可选链容错,避免传入不存在的number时直接崩溃*
    const source = sources[number]?.link
    

    这个方案适合JSON体积小、读取频率不高的场景,缺点是每次读取都要走磁盘IO,高频调用会有不必要的性能损耗。

  • 方案2:用fs模块读取解析,灵活度更高
    放弃用require()加载JSON,改用Node内置的fs模块直接读文件内容、手动解析,适配更复杂的场景:

    const fs = require('fs')
    const path = require('path')
    // 提前拼接JSON文件的绝对路径,避免相对路径运行时出错
    const sourcesPath = path.join(__dirname, '../folder/sources.json')
    
    function getSources() {
      try {
        // 同步读取文件内容,指定编码拿到字符串
        const fileContent = fs.readFileSync(sourcesPath, 'utf-8')
        return JSON.parse(fileContent)
      } catch (err) {
        console.error('读取sources.json失败,请检查文件格式', err)
        // 出错时返回空对象,避免业务代码崩溃
        return {}
      }
    }
    
    // 业务中调用
    const sources = getSources()
    const source = sources[number]?.link
    

    如果你的bot读取这个配置的频率很高,可以加个文件监听,JSON更新时自动刷新内存里的配置,不用每次读都走磁盘:

    const fs = require('fs')
    const path = require('path')
    const sourcesPath = path.join(__dirname, '../folder/sources.json')
    
    // 内存里常驻最新的配置
    let sources = {}
    let refreshTimer = null
    // 初始化先加载一次
    refreshSources()
    // 监听文件改动,自动刷新配置
    fs.watch(sourcesPath, { persistent: false }, (eventType) => {
      if (eventType === 'change') {
        // 加100ms防抖,避免写入时多次触发导致读取半完成文件
        clearTimeout(refreshTimer)
        refreshTimer = setTimeout(refreshSources, 100)
      }
    })
    
    function refreshSources() {
      try {
        const content = fs.readFileSync(sourcesPath, 'utf-8')
        sources = JSON.parse(content)
      } catch (err) {
        console.error('sources.json更新失败,保留原有配置', err)
      }
    }
    
    // 业务代码直接读内存里的sources就行,永远是最新值
    const source = sources[number]?.link
    

    这个方案性能最好,适合高频读取配置的场景,一定要做好JSON解析错误的捕获,避免改JSON时写错格式直接把bot搞崩。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:31:04