问题描述
目前我正在从事一个个人项目,但在理解我的应用程序中 module.exports 的功能时遇到了问题...
我的应用结构如下:
app
├── common
│ ├── cmd
│ │ ├── run-cmd.js
├── routes
│ ├── system
│ │ ├── temp.js
我希望实现一种将可重用功能存储在我的应用程序中的单独位置(在此示例中为 run-cmd.js
)的方法,并在我的应用程序的其余部分 (temp.js
) 中轻松访问它们,而无需必须专门引用文件路径(例如:require(../../folder/folder/file)
这是run-cmd.js
:
const { spawn } = require("child_process");
module.exports.runcmd = (cmd,callback) => {
var command = spawn(cmd,[],{shell:true});
const REGEX_LINE_BREAK = /(\r\n|\n|\r)/gm;
var result = '';
command.stdout.on('data',function(data) {
console.log(data.toString())
result += data.toString().replace(REGEX_LINE_BREAK,"");
});
command.on('close',(code) => {
console.log("code: " + code)
return callback(result);
});
}
这是temp.js
:
var express = require('express'),router = express.Router(),runcmd = require('../../common/cmd/run-cmd');
// Add a binding to handle '/temp'
router
.get('/temp',(req,res) => {
runcmd('vcgencmd measure_temp',function(result) {
console.log("Result we are prepping to send: " + result);
res.json({result: result});
});
});
module.exports = router;
我觉得上面的 require()
示例违背了使用 module.exports 的灵活性的目的......在那里做像 require(./run-cmd)
甚至 require(from-root/path/run-cmd)
这样的事情会更好地参考在我的应用程序的其他位置。此外,在当前示例中,我收到一条错误消息,指出 TypeError: runcmd is not a function
。
谁能帮助我解决使用 module.exports
的一些困惑,并告诉我哪里出错了?
解决方法
有几种方法可以实现您的愿望。一个简单但有效的解决方案是向全局对象添加一个属性。这必须在您的主(条目)js 文件中完成,在任何 require
语句之前:
(假设您的入口 js 文件位于 app
文件夹中,则构建以下路径)
global.__runCmdPath = __dirname + '/common/cmd/run-cmd';
然后,在您希望从中要求 runCmd
的任何其他模块中,您可以简单地:
const runCmd = require(__runCmdPath);
您甚至可以将包含要导出的函数的脚本的基目录设置为全局对象的属性,然后只需附加单个脚本名称,例如:
const runCmd = require(__scriptsDir + '/run-cmd');
const runCmd2 = require(__scriptsDir + '/run-cmd2');
另一种策略是将脚本文件夹添加到 NODE_PATH
环境变量中,对于 UNIX,使用以下命令:
export NODE_PATH=./common/cmd
对于 Windows:
set NODE_PATH=./common/cmd
然后,您可以命令 node app.js
,这样,您就可以在任何地方require('run-cmd')
。只要您记得每次启动新的 shell 会话时都重新设置变量,这将起作用。
对于 TypeError: runCmd is not a function.
而言,如果您尝试直接从您需要的地方调用 runCmd,这种情况将继续发生。这是因为 require()
返回一个导出对象,而您导出的方法都属于该对象。
如果你想调用你导出的 runCmd 方法,在这种情况下,你必须这样做:
runCmd.runCmd('vcgencmd measure_temp',function(result) {
console.log("Result we are prepping to send: " + result);
res.json({result: result});
});
因此,您可能希望将包含导出对象的常量或 runCmd 函数的导出名称重命名为最适合您的名称。