【问题标题】:Run function in script from command line (Node JS)从命令行(Node JS)在脚本中运行函数
【发布时间】:2015-08-27 06:15:42
【问题描述】:

我正在用 Node.js 编写一个 Web 应用程序。如果我有一些 JS 文件 db.js,其中有一个函数 init,我怎么能从命令行调用该函数?

【问题讨论】:

  • @Pawel 我更喜欢接受的答案,因为它不需要安装可能失去支持或包含漏洞的第三方依赖项。使用任何依赖项都会带来风险,因此将依赖项限制在经过良好审查和维护的依赖项始终是一个好主意。
  • 你也可以使用包npmjs.com/package/invoke-script

标签: javascript node.js command-line


【解决方案1】:

如果您将db.js 变成一个模块,您可以从db_init.js 中要求它,只需:node db_init.js

db.js:

module.exports = {
  method1: function () { ... },
  method2: function () { ... }
}

db_init.js:

var db = require('./db');

db.method1();
db.method2();

【讨论】:

    【解决方案2】:

    没有评论您为什么要这样做,或者什么可能是更标准的做法:这是您问题的解决方案....请记住,您的命令行所需的引号类型可能会有所不同。

    在您的db.js 中,导出init 函数。方法有很多,但例如:

    module.exports.init = function () {
      console.log('hi');
    };
    

    然后这样调用它,假设您的db.js 与您的命令提示符位于同一目录中:

    node -e 'require("./db").init()'
    

    对于其他读者来说,OP 的 init 函数可以被称为任何东西,这并不重要,它只是问题中使用的特定名称。

    【讨论】:

    • 这是测试从 AWS lambda 运行的一些 javascript 的有用提示 - 谢谢
    • 如果函数是异步的会发生什么?
    • 如果其他人试图在他们的 package.json 中作为 npm 脚本执行此操作,我尝试在其中使用单引号和双引号,但在我切换它们之前它不起作用: "start": "node -e \"require('./server')()\"",
    • 感谢@winhowes 的回复,我只是使用了您的示例module.exports.init = function () { console.log('hi'); };node -e 'require("./db").init()' 不知何故对我不起作用。我不确定我做错了什么,但按照你的想法,我使用了module.exports = myFunction, ,然后node -e 'require("./myFunction")()'为我工作。
    • 作为对@AlexHinton 评论的补充,我现在使用以下内容来模仿事件和回调:node -e 'require("./index").handler(require("./fixtures/sample_event_01.json"), {}, console.log)'。中间的{} 是上下文,可以随意调整。此外,console.log 有点原始,但是一个不错的开始。当然,您也可以编写一个专用的 CLI.js,它反过来 require() 的 index.js/handler,如其他 cmets 所述。
    【解决方案3】:

    试试make-runnable

    在 db.js 中,在末尾添加require('make-runnable');

    现在你可以这样做了:

    node db.js init
    

    任何进一步的 args 都会以列表或键值对的形式传递给 init 方法。

    【讨论】:

    • 这是最好的答案!
    【解决方案4】:

    2020 年更新 - CLI

    正如@mix3d 指出的那样,您可以运行一个命令,其中file.js 是您的文件,someFunction 是您的函数,可选地后跟以空格分隔的参数

    npx run-func file.js someFunction "just some parameter"
    

    就是这样。

    上例中调用file.js

    const someFunction = (param) => console.log('Welcome, your param is', param)
    
    // exporting is crucial
    module.exports = { someFunction }
    

    更详细的说明

    直接从 CLI 运行(全局)

    安装

    npm i -g run-func
    

    用法即运行函数“init”,必须导出,见底部

    run-func db.js init
    

    从 package.json 脚本运行(本地)

    安装

    npm i -S run-func
    

    设置

    "scripts": {
       "init": "run-func db.js init"
    }
    

    用法

    npm run init
    

    参数

    以下任何参数都将作为函数参数传递init(param1, param2)

    run-func db.js init param1 param2
    

    重要

    函数(在本例中为init)必须导出到包含它的文件中

    module.exports = { init };
    

    或 ES6 导出

    export { init };
    

    【讨论】:

    • 我在考虑使用 eye_mew 的建议来使用 make-runnable,但我认为这比这要好得多。谢谢。
    • @luis.espinal 我很高兴你发现这很有用。后台魔法少,无需修改文件。除非一个函数没有被导出,否则它必须被导出,但这就像常规的 ES6 模块及其导入/导出一样合乎逻辑。
    • 这对我不起作用; $ run-func db.js init bash: run-func: 找不到命令
    • 感谢npx,我们可以在无需全局安装run-func 的情况下执行npx run-func file.js functionName。 #wining!
    • 您应该提到,您是包run-func...的贡献者之一...
    【解决方案5】:

    简单的方法:

    假设您在项目结构的 helpers 目录中有 db.js 文件。

    现在进入 helpers 目录并进入节点控制台

     helpers $ node
    

    2) 需要 db.js 文件

    > var db = require("./db")
    

    3) 调用你的函数(在你的例子中是它的 init())

    > db.init()
    

    希望对你有帮助

    【讨论】:

      【解决方案6】:

      如果你的文件只包含你的函数,例如:

      我的文件.js:

      function myMethod(someVariable) {
          console.log(someVariable)
      }
      

      像这样从命令行调用它不会发生任何事情:

      node myFile.js
      

      但是如果你改变你的文件:

      我的文件.js:

      myMethod("Hello World");
      
      function myMethod(someVariable) {
          console.log(someVariable)
      }
      

      现在这将在命令行中运行:

      node myFile.js
      

      【讨论】:

      • 没错,这就是运行JS文件的方法。这个问题更多地是针对我是否可以运行一个特定的函数(在许多可能的函数中),其中唯一的变化是命令行输入而不是每个函数调用的 JS 文件本身
      • 这不是处理这个人要求的场景
      • @jobmo 是,他们想从 cmd 行运行一个方法,这样做。 (我自己是通过谷歌搜索问题来到这里的,所以其他人可能会欣赏答案),别担心,您可以选择多种答案
      • 没错,问题是关于从 cmd 行运行方法。在这个答案中,执行了 myFile.js。就是这样。它没有执行任何功能。然后碰巧该文件具有一个函数,并且该函数在文件内部被调用。这就是我的观点。
      • 您刚刚解释了答案从命令行执行函数:+1:
      【解决方案7】:

      根据其他答案,将以下内容添加到someFile.js

      module.exports.someFunction = function () {
        console.log('hi');
      };
      

      然后您可以将以下内容添加到package.json

      "scripts": {
         "myScript": "node -e 'require(\"./someFile\").someFunction()'"
      }
      

      然后你可以从终端调用

      npm run myScript
      

      我发现这是一种更容易记住命令并使用它们的方法

      【讨论】:

      • 在我的 Win10 机器上,这种语法只是简单地回显脚本(在 PowerShell 或命令提示符终端中)。直接运行它而不是通过 'npm run' 会抛出指向 require 参数开头的 'Unexpected token'。我还没弄清楚如何让它工作。
      • @CalvinDale 在这里相同,只是我可以在 powershell 中运行脚本本身就好了。
      • 在我的机器(Windows 10)上,我必须切换双引号和单引号,如下所示: "myScript": "node -e \"require('./someFile').someFunction ()\"" 否则 Node 只会打印出单引号内的命令,但不会对其进行评估。也许这解决了@CalvinDale 和ferr 的问题。
      • 如果我们想在函数调用中添加一个参数怎么办?
      【解决方案8】:

      这个很脏但可以工作:)

      我将从我的脚本中调用main() 函数。以前我只是在脚本末尾调用 main 。但是我确实添加了一些其他函数并从脚本中导出它们(以在代码的其他一些部分中使用函数) - 但我不想每次在其他脚本中导入其他函数时都执行 main() 函数。

      所以我这样做了, 在我的脚本中,我删除了对 main() 的调用,而是在脚本末尾放置了这个检查:

      if (process.argv.includes('main')) {
         main();
      }
      

      所以当我想在 CLI 中调用该函数时:node src/myScript.js main

      【讨论】:

      • 对我来说已经足够了,并且不会在package.json 脚本中强制双引号转义
      【解决方案9】:

      我做一个 IIFE,类似这样的:

      (() => init())();
      

      此代码将立即执行并调用 init 函数。

      【讨论】:

      • 但是如果你运行:node init.js 并且该文件包含一个 IIFE,它将起作用。我想我没有完全理解你的问题。对不起。
      • 完全明白,但如果代码包含其他函数,它们可能会或可能不会被调用
      • 如果你愿意,你甚至可以将其简化为(init)(); :)
      【解决方案10】:

      有时你想通过 CLI 运行一个函数,有时你想从另一个模块require 它。以下是如何做到这两点。

      // file to run
      const runMe = () => {}
      if (require.main === module) {
        runMe()
      } 
      module.exports = runMe
      

      【讨论】:

      • 这是迄今为止最好的答案!谢谢!
      【解决方案11】:

      也许这个方法不是你的意思,但谁知道它会有所帮助

      index.js

      const arg = process.argv.splice(2);
      
      function printToCli(text){
          console.log(text)
      }
      
      switch(arg[0]){
          case "--run":
              printToCli("how are you")
          break;
          default: console.log("use --run flag");
      }
      

      并运行命令node . --run

      命令行

      probuss-MacBook-Air:fb_v8 probus$ node . --run
      how are you
      probuss-MacBook-Air:fb_v8 probus$ 
      

      你可以添加更多的 arg[0] , arg[1], arg[2] ...等等

      node . --run -myarg1 -myarg2

      【讨论】:

        【解决方案12】:

        灵感来自https://github.com/DVLP/run-func/blob/master/index.js

        我创建https://github.com/JiangWeixian/esrua

        如果文件index.ts

        export const welcome = (msg: string) => {
          console.log(`hello ${msg}`)
        }
        

        快跑

        esrua ./index.ts welcome -p world
        

        将输出hello world

        【讨论】:

        • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
        【解决方案13】:

        如果你想在你的 .env 文件中包含环境变量,你可以使用env-cmd:

        npx env-cmd node -e 'require("./db").init()'
        

        如果您也想在文件中运行特定函数,请使用run-func

        npx env-cmd npx run-func db.js init someArg
        

        或者,要为接受的答案提供论据,您必须执行以下操作:

        npx env-cmd node -e 'require("./db").init(someArg)'
        

        与为命令提供不同的参数相比,在此处编写/更新表达式不太明确(例如,当您检查时更容易错过),因此我建议将env-cmdrun-func 一起使用。

        注意:我通常也会在必要时在末尾添加--experimental-modules

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-07
          • 1970-01-01
          • 2019-06-11
          • 2019-01-02
          • 1970-01-01
          • 2011-03-10
          • 2021-08-15
          • 2018-10-05
          相关资源
          最近更新 更多