【问题标题】:Load and execute external file in node.js在 node.js 中加载并执行外部文件
【发布时间】:2013-07-10 21:17:35
【问题描述】:

从另一个节点 js 文件运行节点 js 文件是否容易/可能? 例如,我有两个文件 test1.js 和 test2.js。我想从 test2.js 执行 test1.js 文件。

【问题讨论】:

  • 你说的执行是什么意思?与在 test1.js 中做 require('test2.js') 有什么不同?
  • @adrianp "node test1.js" 这样我们正在执行或运行节点 js 文件。我想从 test2.js 运行 test1.js
  • @sudhakar,你在说什么like this
  • @kentcdodds 例如 test1.js 的内容 if (process.argv.length > 0) { var test_val = process.argv[1]; } 控制台.log(test_val);如果我在命令“node test1.js wow”中运行它,输出将是 wow。所以我想从 test2.js 得到输出“哇”
  • 您只想单独运行 test1 还是希望 test1 能够访问 test2 变量?

标签: node.js


【解决方案1】:

我认为完成您正在尝试做的事情的更好方法是按照我的其他答案所建议的去做。但是要按照您的问题在命令行上执行命令,您需要使用child_process.exec。例如:

var exec = require('child_process').exec,
    child;

child = exec('node test2.js {{args}}',
  function (error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
      console.log('exec error: ' + error);
    }
});

【讨论】:

    【解决方案2】:

    您只需运行require('test2.js'),然后在导出的对象上调用一个函数。来自documentation on modules

    Node 有一个简单的模块加载系统。在 Node 中,文件和模块是一一对应的。例如,foo.js 将模块 circle.js 加载到同一目录中。

    foo.js 的内容:

    var circle = require('./circle.js');
    console.log( 'The area of a circle of radius 4 is ' + circle.area(4));
    

    circle.js的内容:

    var PI = Math.PI;
    
    exports.area = function (r) {
      return PI * r * r;
    };
    
    exports.circumference = function (r) {
      return 2 * PI * r;
    };
    

    模块 circle.js 已经导出了函数 area() 和 circle()。要导出对象,请添加到特殊的导出对象。

    请注意,exports 是对 module.exports 的引用,使其仅适用于扩充。如果要导出单个项目,例如构造函数,则需要直接使用 module.exports。

    function MyConstructor (opts) {
      //...
    }
    
    // BROKEN: Does not modify exports
    exports = MyConstructor;
    
    // exports the constructor properly
    module.exports = MyConstructor;
    

    模块的本地变量将是私有的。在这个例子中,变量 PI 是 circle.js 私有的。

    模块系统在require("module")模块中实现。

    【讨论】:

    • 嗯...不知道为什么这个答案被否决了。这是与模块交互的正确方式,即使它不是公认的答案......
    • 如果我把它做成一个模块,我将无法单独运行它。我有一些任务的单独脚本,然后是一些可以按指定顺序运行所有必需任务的调度程序脚本。如果我的任务是带有导出的模块,我不能单独运行这些任务,我必须创建一些包装脚本来运行任务。
    • @J 只需将所有内容包装在一个函数中,然后测试脚本是否作为模块运行:// Allows us to run either directly or via another node.js script if (require.main === module) { // We are running directly runTest() } else { // We are a module in another script module.exports = runTest }
    【解决方案3】:

    这里有不同的场景 - 使用模块,以“正确的方式”加载它们 - 这是编写自己的代码时要走的路。

    “随机”.js 文件怎么样,例如通过网络抓取下载? (如果这是执行它们的好主意超出了这个答案的范围......)

    好吧 - 如果你只对副作用感兴趣,你可以只需要它们:

    test2.js:

    console.log('hello')
    

    test1.js:

    console.log('about to execute')
    require('./test2.js')
    console.log('done')
    

    注意require() 中的./。但是,如果你想运行它两次,这是行不通的:

    test3.js:

    console.log('about to execute twice?')
    require('./test2.js')
    require('./test2.js')
    console.log('surprise')
    

    这表明,require 像 Python import 一样工作 - 仅在文件尚未加载时才执行。但是 - 可以绕过它并强制重新加载:How to remove module after "require" in node.js?

    test4.js:

    console.log('about to execute twice!')
    require('./test2.js')
    delete require.cache[require.resolve('./test2.js')]
    require('./test2.js')
    console.log('NO surprise this time around')
    

    与 Python import 的区别在于,除非已导出,否则您无法导入任何内容。因此,您必须更改 required 文件并使用 module.exports 做一些事情。

    如果您使用的是node shell,还有一个替代方案:

    test5.js:

    console.log('the const below is private?')
    const x = 5
    

    然后:

    $ node
    > .load test5.js
    console.log('the const below is private?')
    const x = 5
    
    the const below is private?
    undefined
    > x
    5
    

    请注意,.load 中的文件名没有引号,也没有 ./。这在使用时有些冗长(与加载的脚本相呼应)。但这至少是使用脚本创建的值的某种方式。

    最后的警告:永远小心你将要执行的事情!

    【讨论】:

      猜你喜欢
      • 2011-07-11
      • 2017-05-10
      • 1970-01-01
      • 2017-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-26
      • 1970-01-01
      相关资源
      最近更新 更多