从命令行运行脚本中的函数(Node JS)

win*_*wes 168 javascript command-line node.js

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

Lee*_*Gee 258

没有评论你为什么要这样做,或者什么可能是更标准的做法:这里是你的问题的解决方案....承担我的命令行所需的报价类型可能会有所不同.

在你的db.js,导出init功能.有很多方法,但例如:

module.exports.init = function () {
  console.log('hi');
};
Run Code Online (Sandbox Code Playgroud)

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

node -e 'require("./db").init()'
Run Code Online (Sandbox Code Playgroud)

对于其他读者来说,OP的 init功能可以被称为任何东西,它并不重要,它只是问题中使用的特定名称.实际上,如果您喜欢这种描述性较低的语法,可以避免它:

module.exports.init = function () {
  console.log('hi');
};
Run Code Online (Sandbox Code Playgroud)

要实现这一点,请使用"特殊" db.js参考功能init:

node -e 'require("./db").init()'
Run Code Online (Sandbox Code Playgroud)

请记住,这是对函数的引用db.js,而不是对函数的调用!

您还可以使用Node命令行选项来要求模块:

init

db.js

...在这种情况下,您可以将您的模块添加init到全局命名空间,但是留下其他开发人员并不是一件好事,所以我将其作为扭曲的练习.

  • 这是一个有用的提示,用于测试从AWS lambda运行的一些javascript - 谢谢 (64认同)
  • 如果其他人试图在他们的package.json中作为npm脚本尝试这样做,我尝试使用单引号和内部双引号,但直到我切换它们才能工作:"start":"node - e \"require('./ server')()\"", (17认同)
  • 如果函数是异步的,会发生什么? (9认同)
  • 作为对@ AlexHinton评论的补充,我现在使用以下方法来模仿事件和回调:`node -e'require("./ index").handler(require("./ fixtures/sample_event_01.json")), {},console.log)'`.中间的`{}`将是上下文,随意调整.console.log也有点原始但是一个不错的开始.当然,您也可以编写专用的CLI.js,而这些CLI.js又需要()其他注释中所述的index.js/handler. (3认同)
  • 感谢@winhowes的答复,我只是使用了示例`module.exports.init = function(){console.log('hi'); };`和-node -e'require(“ ./ db”)。init()'`对我不起作用。我不确定我做错了什么,但是按照您的想法,我使用了`module.exports = myFunction,`,然后使用了node -e'require(“ ./ myFunction”)()'为我工作。 (2认同)
  • @LeeGee这是一个完美的例子:我有一个我想运行的脚本。由于我自己的原因,我决定用 JavaScript 编写它。现在我想运行它。我碰巧想到了一个特定的应用程序,这就是我来到这里的原因。 (2认同)

Gaz*_*dge 32

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

module.exports.someFunction = function () {
  console.log('hi');
};
Run Code Online (Sandbox Code Playgroud)

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

"scripts": {
   "myScript": "node -e 'require(\"./someFile\").someFunction()'"
}
Run Code Online (Sandbox Code Playgroud)

从终端,您可以打电话

npm run myScript
Run Code Online (Sandbox Code Playgroud)

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

  • 在我的机器(Windows 10)上,我必须切换双引号和单引号,如下所示: "myScript": "node -e \"require('./someFile').someFunction()\"" 否则 Node 会只需打印出单引号内的命令,但不对其进行评估。也许这解决了@CalvinDale 和ferr 的问题。 (8认同)
  • 如果我们想在函数调用中添加一个参数怎么办? (5认同)

eye*_*mew 25

尝试make-runnable.

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

现在你可以这样做:

node db.js init
Run Code Online (Sandbox Code Playgroud)

任何进一步的args都会传递给该init方法.


Mat*_*t K 11

有时您想通过 CLI 运行一个函数,有时您想require从另一个模块运行它。这是两者的方法。

// file to run
const runMe = () => {}
if (require.main === module) {
  runMe()
} 
module.exports = runMe
Run Code Online (Sandbox Code Playgroud)


Paw*_*wel 10

将run-func安装到您的项目中

npm i -D run-func
Run Code Online (Sandbox Code Playgroud)

运行任何导出的功能

run-func db.js init
Run Code Online (Sandbox Code Playgroud)

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

run-func db.js init param1 param2
Run Code Online (Sandbox Code Playgroud)

这也可以从package.json中的"scripts"部分运行

"db-init": "run-func db.js init"
Run Code Online (Sandbox Code Playgroud)

init必须在db.js文件中导出重要信息

module.exports = { init };
Run Code Online (Sandbox Code Playgroud)

或ES6出口

export { init };
Run Code Online (Sandbox Code Playgroud)

  • 感谢“npx”,我们可以执行“npx run-func file.js functionName”,而无需全局安装 run-func。#获胜! (4认同)
  • 您应该提到,您是包 [`run-func`](https://github.com/DVLP/run-func) 的贡献者之一... (4认同)

chr*_*arx 10

2022 年更新 - 如果您已切换到 ES 模块,则无法使用 require 技巧,您需要使用动态导入:

node -e 'import("./db.js").then(dbMod => dbMod.init());'
Run Code Online (Sandbox Code Playgroud)

或使用 --experimental-specifier-resolution=node 标志:

node --experimental-specifier-resolution=node -e 'import("./db").then(dbMod => dbMod.init());'
Run Code Online (Sandbox Code Playgroud)


Siy*_*lav 8

简单方法:

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

现在进入帮助程序目录并转到节点控制台

 helpers $ node
Run Code Online (Sandbox Code Playgroud)

2)需要db.js文件

> var db = require("./db")
Run Code Online (Sandbox Code Playgroud)

3)调用你的函数(在你的情况下,它的init())

> db.init()
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


Dav*_*ave 7

如果您打开db.js到一个模块中,你可以要求它db_init.js,只是:node db_init.js

db.js:

module.exports = {
  method1: function () { ... },
  method2: function () { ... }
}
Run Code Online (Sandbox Code Playgroud)

db_init.js:

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

db.method1();
db.method2();
Run Code Online (Sandbox Code Playgroud)


Fil*_*man 7

您还可以使用ts-node类似于 @LeeGoddard答案 的方式运行 TypeScript 。
就我而言,我想单独使用appinit来进行测试。

// app.ts

export const app = express();

export async function init(): Promise<void> {
   // app init logic...
}
Run Code Online (Sandbox Code Playgroud)
// commonjs
npx ts-node -e 'require("./src/app").init();'
// esmodule
npx ts-node -e 'import("./src/app").then(a => a.init());'
Run Code Online (Sandbox Code Playgroud)


To *_*Kra 5

这个很脏但是可以用 :)

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

因此,我这样做了,在脚本中删除了对main()的调用,而是在脚本结尾处放了以下检查:

if (process.argv.includes('main')) {
   main();
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为这根本不脏。它简单、明确并且有效。:-) (2认同)

Nat*_*tch 5

我做了一个 IIFE,就像这样:

(() => init())();
Run Code Online (Sandbox Code Playgroud)

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

  • 但是如果你运行:`node init.js` 并且文件包含一个 IIFE,它就会工作。我想我没有完全理解你的问题。对不起。 (2认同)