2016-01-13 91 views
3

我想根據環境以兩種不同的方式啓動應用程序。從簡單腳本啓動主節點應用程序的最佳方式

在的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,因爲它會開始一個新的過程,父母將終止。

UPDATE:我對使用多個npm命令的替代解決方案不感興趣。我特別想了解使用各種方法從另一個節點腳本啓動一個節點腳本的優點/缺點/資源使用/性能影響,這些方法使用各種各樣的child_process方法。

+0

給出了一個答案,請讓我知道如果有什麼事情你都弄不清 - 很高興,如果需要擴大。 – arcseldon

+0

嗨,請你可以查看我的答案,並讓我知道你是否覺得有幫助(upvote/mark as answer)。如果您需要更多信息,請告訴我 - 歡迎提供進一步支持。 – arcseldon

回答

0

我認爲這種方法不適合。

中的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" 
} 
... 
} 
+1

這對於生產來說很好,但它無法在開發中使用nodemon啓動應用程序。 – emkman

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 

以上,我們的開發環境是EXEC根據要求與nodemon以及我們的生產環境節點

更新基於OP反饋

這child_process方法是最好的,從開始你的主節點的應用程序。這是我的問題的重點

你所問的是非典型的 - 但是,當然有選擇:

如果你想背景節點實例,則容易從命令控制這個(&)等

但是,如果你真的想這樣做,那麼在過去我選擇使用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的nces。因此它專門用於運行Node的新實例。

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

還有更多選項,詳情請參閱documentation

+0

是的,這是一個不錯的選擇。我也可以在使用ENV或其他變量的'start'中使用bash stye if語句,但這仍然不能回答我最好從哪個** child_process **方法啓動主節點應用程序的問題。這是我的問題的主要觀點。 – emkman

+0

根據OP的反饋意見更新答案。 – arcseldon

1

如下

require('child_process').spawn()開始儘快在流發送回從子進程的數據作爲子進程開始執行之間spawn()exec()child_processfork()的差異。當你運行這個命令時,它發送一個系統命令,它將在它自己的進程上運行,而不是在你的節點進程中執行代碼。在此,不會創建新的V8實例,並且處理器上只有一個節點模塊副本處於活動狀態。當您希望子進程向節點返回大量數據時使用它。

require('child_process').fork()是spawn的一個特殊實例,它運行V8引擎的新實例。這實際上意味着您正在創建多個工作在相同節點代碼庫上的不同任務。

require('child_process').exec()從子進程返回緩衝區。默認緩衝區大小爲200k。它是異步的,但它會等待子進程結束並嘗試一次返回所有緩衝的數據。如果您的子進程的返回數據大於200k,那麼您將超出maxBuffer。

PM2

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

child_process.exec的源代碼是用來啓動的node.js應用程序。 PM2也有cluster模式,這裏使用culster.for()。在child_process.fork之上實現了cluster.fork

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 
    ... 
} 

IMO,PM2是啓動node.js應用程序的一個很好的選擇。它也可以使用PM2-devdevelopment模式啓動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

+0

我已閱讀您引用的文檔和文章,但希望更深入地瞭解每個選項的含義。例如,自發布這個問題以來,我開始在512MB服務器實例上使用execFile啓動一個應用程序,並且它似乎在泄漏內存。也許是因爲它將緩衝流傳回給父節點?此外,你推薦exec,因爲PM2使用它,但@arcseldon在他的回答中推薦fork。我試圖在沒有幾天的實驗的情況下找到共識。 – emkman

相關問題