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
相关产品推荐
相关产品推荐

