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

Express+Node.js中如何获取.js文件更新后的导出数组?

Express/Node.js中定时更新的数组无法返回最新值的解决办法

问题描述

在Express+Node.js项目中,我将一个会被定时脚本更新的数组从.mjs文件导入到路由API中,但发现脚本更新数组后,API始终返回初始值,无法获取最新数据。尝试用fs.readFileSync读取.mjs文件并通过JSON.parse解析,但因为文件是JS模块格式而非JSON,解析失败。

问题原因

Node.js的ES模块导入机制会缓存模块内容,一旦路由模块导入了.mjs里的数组,后续即使文件内容被修改,路由使用的依然是导入时缓存的初始值,不会重新读取文件。

解决步骤

将存储数组的方式从JS模块改为JSON文件,每次API请求时动态读取并解析JSON文件,确保获取最新数据:

  • 将原本导出数组的.mjs文件替换为JSON格式文件,用对象包裹数组内容
  • 在API的get请求处理函数中,使用fs.readFileSync读取JSON文件,通过JSON.parse解析后返回数组
  • 修改定时更新脚本,使其将更新后的数组写入JSON文件而非JS模块

解决后代码示例

Arrays/bookFiles.json

{
  "name": "bookFiles",
  "array": [
    ["CSSNotesForProfessionals.pdf","/mnt/Data/Books/CSSNotesForProfessionals.pdf","pdf","application/pdf"],
    ["JS for Beginners.pdf","/mnt/Data/Books/JS for Beginners.pdf","pdf","application/pdf"],
    ["alqamoosulwaheed.pdf","/mnt/Data/Books/alqamoosulwaheed.pdf","pdf","application/pdf"]
  ]
}

routes/book.mjs

import express from "express";
import * as fs from 'fs'
export const book = express.Router();

book.get("/",(req,res)=>{
    // 每次请求时读取最新的JSON文件
    const data = JSON.parse(fs.readFileSync('/home/abdurehman/LocalNas/backend/Arrays/bookFiles.json','utf-8'))
    res.send(data.array)
})

修改后的更新脚本/fmgr.mjs(关键部分)

将原脚本中写入.mjs的逻辑改为写入JSON:

// 替换原arrayGroup.forEach中的写入逻辑
arrayGroup.forEach(function (array) {
    console.log(array)
    // 写入JSON文件而非JS模块
    fs.writeFile(
        __dirname + "Arrays/" + array.name + ".json",
        JSON.stringify(array),
        function (err) {
            if (err) {
                return console.log(err);
            }
        }
    );
})

原问题代码

原Arrays/bookFiles.mjs

export const bookFiles=[]

原routes/book.mjs

import express from "express";
export const book = express.Router();
import { bookFiles } from "../Arrays/bookFiles.mjs";

book.get("/",(req,res)=>{
    const data=bookFiles
    res.send(data)
})

主文件/app.mjs

import express from 'express';
import { zip } from './routes/zip.mjs';
import { office } from './routes/office.mjs';
import { compressed } from './routes/compressed.mjs';
import { image } from './routes/images.mjs';
import { book } from './routes/book.mjs';
import { videos } from './routes/videos.mjs';

var app = express()
app.use("/zipFiles",zip)
app.use("/officeFiles",office)
app.use("/videoFiles",videos)
app.use("/compressedFiles",compressed)
app.use("/bookFiles",book)
app.use("/imageFiles",image)

app.listen("5000")

原更新脚本/fmgr.mjs

import * as fs from 'fs';
import {fileTypeFromFile} from 'file-type';
import * as path from 'path';
import * as url from 'url';

var compressedFiles = [];
var imageFiles = [];
var videoFiles = [];
var undefinedFiles = [];
var bookFiles = [];
var zipFiles = [];
var officeFiles = [];

const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

async function chaosofFiles() {
    const getAllFiles = function (dirPath, arrayOfFiles) {
        const files = fs.readdirSync(dirPath)
        arrayOfFiles = arrayOfFiles || []
        files.forEach(function (file) {
            if (fs.statSync(dirPath + "/" + file).isDirectory()) {
                arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles)
            } else {
                arrayOfFiles.push(path.join(dirPath, "/", file))
            }
        })
        return arrayOfFiles
    }

    const myFiles = [];
    getAllFiles("/mnt/Data", myFiles)

    const filesextensions = await Promise.all(myFiles.map(async (file) => {
        const type = await fileTypeFromFile(file);
        const name = file.split('\\').pop().split('/').pop();
        let array = [];
        if (type == undefined) {
            array = [name, file, "undefined", "undefined"]
        } else {
            array = [name, file, type.ext, type.mime];
        }
        return array;
    }))

    compressedFiles = [];
    imageFiles = [];
    videoFiles = [];
    undefinedFiles = [];
    bookFiles = [];
    zipFiles = [];
    officeFiles = [];
    filesextensions.forEach(function (array) {
        const mime = array.at(3);
        const ext = array.at(2);
        if (ext.includes("zip")) {
            zipFiles.push(array)
        } else if (mime.includes("image")) {
            imageFiles.push(array)
        } else if (mime.includes("compressed")) {
            compressedFiles.push(array)
        } else if (mime.includes("video")) {
            videoFiles.push(array)
        } else if (mime == "undefined") {
            undefinedFiles.push(array)
        } else if (mime.includes("office")) {
            officeFiles.push(array)
        }
        else if (mime.includes("pdf")) {
            bookFiles.push(array)
        }
    })

    const arrayGroup = [
        { name: "compressedFiles", array: compressedFiles },
        { name: "imageFiles", array: imageFiles },
        { name: "videoFiles", array: videoFiles },
        { name: "zipFiles", array: zipFiles },
        { name: "officeFiles", array: officeFiles },
        { name: "bookFiles", array: bookFiles },
        { name: "undefinedFiles", array: undefinedFiles }
    ]

    arrayGroup.forEach(
        function (array) {
            console.log(array)
            fs.writeFile(__dirname + "Arrays/" + array.name + ".mjs", "export const " + array.name + "= ()=>{ return " + JSON.stringify(array.array)+";}", function (err) {
                if (err) {
                    return console.log(err);
                }
            });
        }
    )
}

chaosofFiles()

async function waitUntil() {
    return await new Promise(resolve => {
        const interval = setInterval(() => {
            chaosofFiles()
        }, 10000);
    });
}
waitUntil()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:12:05