【发布时间】:2019-11-21 16:52:31
【问题描述】:
我正在尝试为我的 node.js CLI 应用程序编写一个插件系统。
应用程序应从 .json 文件中获取描述,并从 .js 文件中获取实际功能,所有这些都设置在特定文件夹中。
应用程序在启动时检查此文件夹并需要每个 .json 文件
根据 json 数据,它会加载一个包含 module.exports = {functions }
如何在其他时间(在用户输入后,或在 10 秒计时器后)从主文件访问这些函数)?
function fakeuserinput(x, y) {
console.log(math.divide(x, y));
})
}
setTimeout(fakeuserinput(10, 2), 10000);
(第二个问题:有没有比使用 eval() 更好的方法?)
main.js
//commands is an array of all .json files
commands.forEach(function(cmd){
// eval(cmd.module) = require('./plugins/'+cmd.module+'.js'); doesnt work
require('./plugins/'+cmd.module+'.js');
console.log(cmd.name+'\n'+cmd.module);
// console.log(eval(cmd.module).eval(cmd.name)(10, 2));
console.log(eval(cmd.name)(10, 2));
})
数学.js
module.exports = {
multiply: function (x, y) {
return x * y;
},
divide: function (x, y) {
return x / y;
},
add: function (numbers) {
return numbers.reduce(function(a,b){
return a + b
}, 0);
},
subtract: function (numbers) {
return numbers.reduce(function(a,b){
return a - b
}, 0);
},
round: function (x) {
return Math.round(x);
},
squared: function (x) {
return x * x;
},
root: function (x) {
return Math.sqrt(x);
}
}
divide.json
{
"name": "divide",
"module": "math",
"commands": [
[
"how much is (integer) / (integer)",
"how much is (integer) divided by (integer)",
"what is (integer) / (integer)",
"what is (integer) divided by (integer)",
"(integer) / (integer)",
"(integer) divided by (integer)"
]
],
"description": "Divide x by y"
}
我可以在不知道函数名称的情况下加载函数,如下所示:
main.js
//commands is an array of all .json files
commands.forEach(function(cmd){
console.log(cmd.name);
console.log(eval(cmd.name)(10, 2));
})
function divide(x, y) {
return x / y;
}
function multiply(x, y) {
return x * y;
}
但是当它在另一个文件的 module.exports 中时,我被困在试图访问该函数。
json 文件的代码 -> 数组
var folder = './plugins/';
fs.readdir(folder, function (err, files) {
if (err) {
console.log('Couldn\'t read folder contents: '+err.message);
return;
}
files.forEach(function (file, index) {
if (file.substr(-5) == '.json') {
let path = folder+file;
fs.readFile(path, 'utf8', function (err, data) {
if (err) {
console.log('Couldn\'t read JSON file: '+err.message);
}
commands.push(JSON.parse(data));
console.log('Command added: '+file.substr(0, file.length-5));
});
}
});
});
错误信息: ReferenceError: 数学未定义
【问题讨论】:
-
是的,不使用
eval肯定有更好的方法来做到这一点 -
在浏览器上,您可以在服务器上使用
window[cmd.name]... 获得该功能,也许在global上? -
不,不要使用
global。模块的要点是完全避免使用全局命名空间。我目前正在写一个应该更容易使用的答案。 -
我试过 global[]() 但据我了解,这不适用于 module.exports。在测试它时无法让它工作。
-
不是 100% 确定这是否是您想要做的,但请查看 npmjs.com/package/require-dir
标签: javascript node.js node-modules