从简单脚本启动主节点应用程序的最佳方法

时间:2016-01-13 08:27:59

标签: node.js npm

我想根据环境以两种不同的方式启动应用。

在package.json中:

"scripts": {
    "start": "node start.js" 
}

然后在脚本中检查环境变量并执行正确的命令:

// start.js
var env = process.env.NODE_ENV;

if (env === 'development') {
    //run './node_modules/.bin/nodemon main.js' 
}

if (env === 'production') {
    //run 'node main.js'
}

//do I need to exit?
process.exit(1);

此处execforkspawn是否理想?我不需要start.js和main.js之间的通信,我想要最少的开销。我希望它能够直接运行特定于环境的命令。我倾向于fork,因为它将启动一个新流程,父母将终止。

更新:我对使用多个npm命令的替代解决方案不感兴趣。我特别希望了解使用各种 child_process 方法从另一个节点脚本启动一个节点脚本的优缺点/资源使用/性能影响。

3 个答案:

答案 0 :(得分:2)

我倾向于做类似的事情:

var env = process.env.NODE_ENV || 'development';

在主引导应用程序文件(app.js,main.js,start.js或其他任何名称)中,因为我的常用用例是本地开发工作。因此,如果没有设置任何内容,它将使用开发,如果我已经明确设置了一个环境变量,它会使用它(通常只设置为生产,但可以包括测试等)。

然后,对于生产,您只需要设置NODE_ENV环境变量(在部署到实时环境时,像Heroku这样的云服务设置非常简单。)

您有时会看到的另一种模式是:

var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';

这实际上也是在更新process.env.NODE_ENV赋值,这意味着如果你还有其他地方也在检查proces.env.NODE_ENV的值,那么你也不必再继续使用“||”发展''检查。这不是我倾向于使用的模式,但你会在野外看到它。

您的 npm 脚本条目看起来不错,但是没有什么可以阻止您定义其他内容,调用shell脚本,设置env变量等。 如果您准备制作一个,我建议明确说明:

eg.In package.json:

"scripts": {
    "start": "npm run dev"
    "dev": "nodemon start.js",
    "prd": "NODE_ENV=production node start.js" 
}

这样,你就不必混淆了:

npm run dev
// same as npm start

npm run prd

上面,我们的开发环境使用 nodemon 执行,我们的生产环境使用 node 执行。

根据OP反馈进行更新

哪个child_process方法最适合从中启动主节点应用程序。这是我的问题的主要观点

你问的是非典型的 - 但是,当然有选择:

如果要对节点实例进行后台处理,那么可以通过bash(&)等从命令行轻松控制它。

但是,如果您真的希望这样做,那么过去我选择使用NPM模块 - cluster

npm install cluster

这允许您从主进程生成子实例 - 在您的情况下,只需将子实例计数设置为1.

var cluster = require('cluster')
  , app = require('./main');

cluster(app)
  .set('workers', 1)
  // other configuration here

最后,如果你不想使用集群,那么问题更多的是“如何在节点内启动另一个node.js应用程序”:

使用 child_process.fork()。它类似于spawn(),但用于创建V8的全新实例。因此它专门用于运行Node的新实例。

var fork = require('child_process').fork;
var child = fork('./main');

还有其他选项,请参阅documentation了解详情。

答案 1 :(得分:1)

我认为这种方法不合适。

package.json中的

{
  ...
  "scripts": {
    "start": "NODE_ENV=production node ./app"
  }
  ...
}

然后

npm start

更新1

如果你在Windows机器中就像这样使用它

set NODE_ENV=development&& nodemon server.js

如果您的机器不是Windows机器,请使用此

{
...
"scripts": {
 "start": "NODE_ENV=development nodemon ./src/server/app.js"
 }
 ...
}

答案 2 :(得分:1)

spawn()的{​​{1}},exec()fork()之间的差异如下

  子进程开始执行后,

child_process开始在流中从子进程发回数据。运行此命令时,它会发送一个系统命令,该命令将在其自己的进程上运行,而不是在您的节点进程中执行代码。在此,将不会创建新的V8实例,并且处理器上只有一个节点模块的副本处于活动状态。当您希望子进程将大量数据返回到Node时使用它。

     

require('child_process').spawn()是spawn的一个特殊实例,它运行V8引擎的新实例。这实际上意味着您要创建在同一节点代码库上运行的多个工作人员以执行不同的任务。

     

require('child_process').fork()从子进程返回一个缓冲区。默认缓冲区大小为200k。它是异步的,但它等待子进程结束并尝试一次返回所有缓冲的数据。如果子进程的返回数据大于200k,那么将超出maxBuffer。

根据PM2

的源代码
require('child_process').exec()

var exec = require('child_process').exec; 用于启动node.js应用。 PM2也有child_process.exec模式,此处使用clusterculster.for()已在cluster.fork

之上实施
child_process.fork

IMO,if (cluster.isMaster) { // Master: // Let's fork as many workers as you have CPU cores for (var i = 0; i < numCPUs; ++i) { cluster.fork(); } } else { // Worker: // Let's spawn a HTTP server // (Workers can share any TCP connection. // In this case its a HTTP server ... } 是启动node.js应用程序的一个不错的选择。它还可以使用PM2development模式启动node.js.可以找到更多详细信息here

来源:

http://www.codingdefined.com/2014/08/difference-between-fork-spawn-and-exec.html https://nodejs.org/api/cluster.html#cluster_cluster_fork_env