Node.js如何在main.js动态设置环境变量供所有文件读取?
问题描述
我有多份运行测试并将结果写入日志的脚本,还有用于创建、更新日志的辅助函数。希望根据脚本运行时间动态命名日志文件,因此需要在触发所有测试的main.js中存储文件名变量,并让helper-functions.js中的函数都能访问它。
尝试在main.js中设置环境变量process.env.LOGFILE,发现createLogs函数可以读取,但导出到其他文件的updateLogs函数无法读取。不过在helper-functions.js中硬编码该环境变量时,两个辅助函数都能正常使用。请问如何在main.js中动态设置process.env.LOGFILE并让所有辅助函数都能读取?(注:因安全限制无法使用第三方包)
现有代码
main.js
const d = new Date(); const logName = "fooBar"; process.env.LOGFILE = logName + "-" + d.getDay() + "-" + d.getMonth() + "-" + d.getFullYear() + ".json"; createLogs(logName); // Running tests on other files...
helper-functions.js
//If I uncomment the below it works, but file name is hard coded. //process.env.LOGFILE = "customLogs.json"; //Create log file when scripts are first run const createLogs = (logName) => { exec('git branch --show-current', (err, stdout, stderr) => { if (err) { console.log("Error getting git branch:" + stderr); } const startTime = ((Date()).toLocaleString()).split('GMT')[0]; const branchName = stdout ? stdout.replace(/(\r\n|\n|\r)/gm,"") : "no-branch"; let repObjString = `{"details":{"name": "${logName}","time": "${startTime}","branch": "${branchName}"},"report":{}}`; const logFileName = `logs/${process.env.LOGFILE}`; //<== THIS WORKS if (!fs.existsSync(logFileName)) { console.log("Log doesnt exist. Making one..."); fs.writeFile(logFileName, repObjString, function (err) { if (err) throw err; console.log('Creating file!'); }); } }); } // Update logs const updateLogs = (logObj) => { const logName = `logs/${process.env.LOGFILE}`; //<== THIS DOES NOT WORK fs.readFile(logName, 'utf8', function (err, logData) { if (err) throw err; Object.assign(logData["report"], logObj); fs.writeFile (logName, logData, function(err) { if (err) throw err; console.log('Log updated'); }); }); }
解决方案
方法1:直接传递文件名参数(最可靠)
避免依赖环境变量,直接将动态生成的文件名作为参数传递给createLogs和updateLogs,这是最直观且不易出问题的方式:
修改helper-functions.js
//Create log file when scripts are first run const createLogs = (logName, logFileName) => { // 添加logFileName参数 exec('git branch --show-current', (err, stdout, stderr) => { if (err) { console.log("Error getting git branch:" + stderr); } const startTime = ((Date()).toLocaleString()).split('GMT')[0]; const branchName = stdout ? stdout.replace(/(\r\n|\n|\r)/gm,"") : "no-branch"; let repObjString = `{"details":{"name": "${logName}","time": "${startTime}","branch": "${branchName}"},"report":{}}`; const fullLogPath = `logs/${logFileName}`; // 使用传入的参数 if (!fs.existsSync(fullLogPath)) { console.log("Log doesnt exist. Making one..."); fs.writeFile(fullLogPath, repObjString, function (err) { if (err) throw err; console.log('Creating file!'); }); } }); } // Update logs const updateLogs = (logObj, logFileName) => { // 添加logFileName参数 const fullLogPath = `logs/${logFileName}`; // 使用传入的参数 fs.readFile(fullLogPath, 'utf8', function (err, logData) { if (err) throw err; // 修复bug:读取的logData是字符串,需先转为JSON对象 const parsedLogData = JSON.parse(logData); Object.assign(parsedLogData.report, logObj); fs.writeFile(fullLogPath, JSON.stringify(parsedLogData), function(err) { if (err) throw err; console.log('Log updated'); }); }); } // 导出函数 module.exports = { createLogs, updateLogs };
修改main.js
const d = new Date(); const logName = "fooBar"; const logFileName = logName + "-" + d.getDay() + "-" + d.getMonth() + "-" + d.getFullYear() + ".json"; const { createLogs } = require('./helper-functions'); createLogs(logName, logFileName); // 运行测试时,调用updateLogs需传递logFileName // 示例:const { updateLogs } = require('./helper-functions'); // updateLogs(testResult, logFileName);
方法2:在辅助模块中导出可修改的文件名变量
在helper-functions.js中定义可导出的变量,main.js中设置该变量的值,所有辅助函数直接访问该变量:
修改helper-functions.js
// 定义可导出的文件名变量 let logFileName = ''; //Create log file when scripts are first run const createLogs = (logName) => { exec('git branch --show-current', (err, stdout, stderr) => { if (err) { console.log("Error getting git branch:" + stderr); } const startTime = ((Date()).toLocaleString()).split('GMT')[0]; const branchName = stdout ? stdout.replace(/(\r\n|\n|\r)/gm,"") : "no-branch"; let repObjString = `{"details":{"name": "${logName}","time": "${startTime}","branch": "${branchName}"},"report":{}}`; const fullLogPath = `logs/${logFileName}`; // 使用模块内变量 if (!fs.existsSync(fullLogPath)) { console.log("Log doesnt exist. Making one..."); fs.writeFile(fullLogPath, repObjString, function (err) { if (err) throw err; console.log('Creating file!'); }); } }); } // Update logs const updateLogs = (logObj) => { const fullLogPath = `logs/${logFileName}`; // 使用模块内变量 fs.readFile(fullLogPath, 'utf8', function (err, logData) { if (err) throw err; const parsedLogData = JSON.parse(logData); Object.assign(parsedLogData.report, logObj); fs.writeFile(fullLogPath, JSON.stringify(parsedLogData), function(err) { if (err) throw err; console.log('Log updated'); }); }); } // 导出变量和函数 module.exports = { createLogs, updateLogs, logFileName };
修改main.js
const d = new Date(); const logName = "fooBar"; const { createLogs, logFileName: helperLogFileName } = require('./helper-functions'); // 设置辅助模块中的文件名变量 helperLogFileName = logName + "-" + d.getDay() + "-" + d.getMonth() + "-" + d.getFullYear() + ".json"; createLogs(logName); // 其他测试文件导入后可直接使用,无需重复传递
方法3:确保模块加载顺序(修复环境变量问题)
如果坚持使用环境变量,问题大概率是其他导入updateLogs的模块,在main.js设置process.env.LOGFILE之前就加载了helper-functions.js。需保证main.js是程序入口,先设置环境变量再导入其他模块:
修改main.js
// 第一步:先设置环境变量 const d = new Date(); const logName = "fooBar"; process.env.LOGFILE = logName + "-" + d.getDay() + "-" + d.getMonth() + "-" + d.getFullYear() + ".json"; // 第二步:再导入辅助函数和测试模块 const { createLogs } = require('./helper-functions'); createLogs(logName); // 最后导入并运行测试 require('./test-module-1'); require('./test-module-2');
这样所有后续导入的模块,包括它们引用的helper-functions.js,都会读取到已设置好的环境变量。
内容的提问来源于stack exchange,提问作者MeltingDog
相关产品推荐
相关产品推荐

