Javascript 如何在我的本地应用程序中正确使用模块导出

Javascript 如何在我的本地应用程序中正确使用模块导出,javascript,node.js,module.exports,Javascript,Node.js,Module.exports,目前我正在从事一个个人项目,在理解我的应用程序中的module.exports的功能时遇到了问题 我的应用程序结构如下所示: app ├── common │ ├── cmd │ │ ├── run-cmd.js ├── routes │ ├── system │ │ ├── temp.js 我希望实现一种方法,将可重用函数存储在我的应用程序中的一个单独位置(在本例中为run cmd.js),并使它们在我的应用程序的其余部分(temp.js)中易于访问,而无需特别引用文

目前我正在从事一个个人项目,在理解我的应用程序中的module.exports的功能时遇到了问题

我的应用程序结构如下所示:

app
├── common
│   ├── cmd
│   │   ├── run-cmd.js
├── routes
│   ├── system
│   │   ├── temp.js
我希望实现一种方法,将可重用函数存储在我的应用程序中的一个单独位置(在本例中为
run cmd.js
),并使它们在我的应用程序的其余部分(
temp.js
)中易于访问,而无需特别引用文件路径(例如:
require(../../folder/folder/file)

下面是
运行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);
    });
} 
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;
这里是
temp.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);
    });
} 
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(从root/path/run cmd)
在我的整个应用程序中的其他位置引用会更好。此外,在当前的示例中,我收到一个错误,说
TypeError:runCmd不是一个函数


有谁能帮我澄清一下使用
模块时的一些困惑。导出
并告诉我哪里出了问题?

有几种方法可以实现您的愿望。一种简单但有效的解决方案是向全局对象添加属性。这必须在主(条目)中完成js文件,在任何
require
语句之前:

(下面的路径是假设您的条目js文件位于
app
文件夹中构建的)

然后,在您需要
runCmd
的任何其他模块中,您可以简单地:

const runCmd = require(__runCmdPath);
您甚至可以将包含要导出的函数的脚本的基本目录设置为全局对象的属性,然后只附加单个脚本名称,如:

const runCmd = require(__scriptsDir + '/run-cmd');
const runCmd2 = require(__scriptsDir + '/run-cmd2');
另一种策略是使用以下UNIX命令将脚本文件夹添加到
节点路径
环境变量中:

导出节点路径=./common/cmd
对于Windows:

设置节点路径=./common/cmd
然后,您可以命令
node app.js
,这样,您就可以在任何地方
require('run-cmd')
。只要您每次启动新的shell会话时都记得重新设置变量,这就行了

关于
TypeError:runCmd不是一个函数。
,如果您试图从需要的位置直接调用runCmd,这种情况将继续发生。这是因为
require()
返回一个导出对象,而导出的所有方法都属于该对象

如果要调用导出的runCmd方法,在本例中,必须按以下方式执行:

runCmd.runCmd('vcgencmd measure_temp', function(result) {
            console.log("Result we are prepping to send: " + result);
            res.json({result: result});
        });

因此,您可能希望将包含导出对象的常量或runCmd函数的导出名称重新命名为最适合您的名称。

您是否查看了
require('path/to/runCmd')中的内容
提供给您?它是一个对象,定义的
模块。导出
,其中包含
runCmd
函数。对于绝对路径,您是否阅读过例如?@jornsharpe,感谢您的响应。在我上面的当前示例中,我使用的是
require('path/to/runCmd'))
如前所述,我得到了
类型错误:runCmd不是一个函数
。正确;再次强调,它不是一个函数,它是一个对象。请注销,看一看。这是一个很好的答案,我非常感谢您的回答。我唯一的问题是关于您对我的路径问题的解决方案。这样做有什么缺点吗?您提到了吗
“几种方法”
…这似乎是实现我尝试的目标的最常用或推荐的方法吗?非常感谢您的反馈!以上确实是我建议的策略,也是最常用的策略之一。唯一的缺点是全局对象已经有一些属性需要更改,所以不是所有的名称都需要更改可用。您可以参考这些。我已修改了我的答案,以包括另一种策略,这可能有助于您实现更干净的导入,但作为一个缺点,您需要在每次启动新的shell会话时设置一个环境变量。我的意思是“不应更改的属性”这是一个很好的解释,我认为这是一个有效的解决方案。我最终选择了全球路线,因为我觉得它最适合我的情况。再次感谢你!