2010-05-28 44 views
53

我想設置我自己的nodejs服務器,但我遇到問題。我無法弄清楚如何在不重新啓動它的情況下查看我的應用程序的更改。有沒有辦法編輯應用程序並查看node.js中的更改?當我想查看更改時,如何在不重新啓動nodejs的情況下編輯我的服務器文件?

+0

一個更好的方案是使用兩臺服務器作爲代理,二級倒下代理服務器nginx的時候處理第一個變爲脫機(504error)(使用nginx可以編輯重新加載/不重新啓動的配置),這樣所有請求在停止第一個服務器後自動切換到第二個服務器,第二個服務器用作備份以更新文件在第一臺服務器上。當第一次返回時,nginx會切換到第一臺服務器。有了這個解決方案,您不會失去任何請求。 – diti 2017-09-19 22:11:20

回答

47

結賬Node-Supervisor。您可以爲它提供一組文件以監視更改,如果它們中的任何一個發生更改,則會重新啓動服務器。如果由於其他原因而崩潰,它也會重新啓動它。

在NodeJS中未啓用「熱插拔」代碼,因爲它很容易意外地結束內存泄漏或未被垃圾收集的對象的多個副本。節點是關於讓您的程序意外快速,而不是意外泄漏。

編輯,事後7年:免責聲明,我寫了node-supervisor,但是在寫這個答案之前把項目交給了另一個維護者。

+0

那真是太棒了。 – PixMach 2014-04-18 13:32:07

+2

在開發中進行熱交換應該沒問題,服務器重新啓動後就可以了,這並不是說實現起來很容易 – 2015-09-13 02:34:30

+0

您提供的鏈接似乎表明這是您的項目。您能否澄清您的參與並添加適當的免責聲明(如果適用)? – HPierce 2016-09-17 18:21:12

58

結節是節點模塊加載,處理模塊的自動重新加載不重新啓動服務器(因爲這是你問的什麼):

http://github.com/kriszyp/nodules

結節不聰明的依賴跟蹤,以便當模塊重新加載而無需完全重新啓動時,重新執行適當的模塊工廠以保留正確的引用。

+0

whoa OP的實際答案! upvoted – 2015-09-13 02:35:01

+0

@Kris Zyp這是一個很好的解決方案,但它仍然積極維護? – 2015-11-11 10:08:37

8

使用此: https://github.com/remy/nodemon

只要運行你的應用程序是這樣的:nodemon yourApp.js

+5

Nodemon每次都會重新啓動服務器,僅用於開發。與羅伯特所要求的完全相反! :) – 2012-12-08 11:19:49

+1

@jasdeepkhalsa接受的答案也表明它重新啓動服務器。 – Loolooii 2015-06-22 09:21:55

+0

是的,接受的答案是OP的錯誤答案:) – 2015-09-13 02:36:32

3

什麼是「實時編碼」?

從本質上講,它是在程序運行時更改程序的一種方式,不需要 重新啓動它。然而,我們的目標是在我們(重新)啓動它時以 正常運行的程序結束。爲了有用,有一個 編輯器可以被自定義發送代碼到服務器。

請看:http://lisperator.net/blog/livenode-live-code-your-nodejs-application/

3

應該有一些偏重發生了什麼,而不是僅僅在OP shotgunning模塊。另外,我們不知道他正在編輯的文件都是JS模塊,或者他們都使用「require」調用。以下是一些鹽的情景,它們只是描述發生了什麼,所以你知道如何使用它。

  1. 你的代碼已經被加載並你需要有一種方式來告訴服務器哪些代碼更改,以便它可以重新加載它的服務器與運行它

    • 解決方案。您可以設置一個端點來接收信號,命令行中的命令或通過tcp/http發出的請求,這會告訴它哪些文件已更改,端點是否會重新加載它。

      //using Express 
      var fs = require('fs'); 
      app.get('reload/:file', function (req, res) { 
          fs.readfile(req.params.file, function (err, buffer) { 
           //do stuff... 
          }); 
      }); 
      
  2. 您的代碼可能有「需要」,在它調用加載和緩存模塊

    • 解決方案,因爲這些模塊由需要緩存,繼前一解,您需要在端點中有一行來刪除該參考文件

      var moduleName = req.params.file; 
      delete require.cache[moduleName]; 
      require('./' + moduleName); 
      

有很多需要注意的地方進入後面的這一切,但希望你發生了什麼,爲什麼一個更好的想法。

3

,如果你想重新加載模塊,而無需重新啓動節點過程中,您可以通過watchFile功能的幫助下FS做到這一點模塊和緩存清除的需要功能

比方說你加載一個簡單的模塊要求:

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

爲了觀看該文件並在更新時重新加載,請將以下內容添加到代碼中的方便位置。

fs.watchFile(require.resolve('./my_module'), function() { 
    console.log("Module changed, reloading..."); 
    delete require.cache[require.resolve('./my_module')] 
    my_module = require('./my_module'); 
}); 

如果你的模塊在多個文件中需要此操作不會影響其他任務,因此保持模塊中的全局變量和使用它,它從全球的需要,而不需要多次是一個選項。所以上面的代碼將是這樣的:

global.my_module = require ('./my_module'); 
//.. 
fs.watchFile(require.resolve('./my_module'), function() { 
    console.log("Module changed, reloading..."); 
    delete require.cache[require.resolve('./my_module')] 
    global.my_module = require('./my_module'); 
}); 
0

參考可在這裏所有的答案簡單直接的解決方法:

節點文檔中說,fs.watch的效率比fs.watchFile &它可以觀看整個文件夾。

(我剛開始使用這一點,所以不能確定是否有任何缺點)

fs.watch("lib", (event_type, file_name) => { 
    console.log("Deleting Require cache for " + file_name); 
    delete require.cache[ require.resolve("./lib/" + file_name)]; 
}); 
相關問題