Irgendwelche Ideen, wie ich ein automatisches Neuladen von Dateien in Node.js implementieren könnte? Ich bin es leid, den Server jedes Mal neu zu starten, wenn ich eine Datei ändere. Anscheinend lädt die require()
-Funktion von Node.js keine Dateien neu, wenn sie bereits benötigt wurden. Daher muss ich Folgendes tun:
var sys = require('sys'),
http = require('http'),
posix = require('posix'),
json = require('./json');
var script_name = '/some/path/to/app.js';
this.app = require('./app').app;
process.watchFile(script_name, function(curr, prev){
posix.cat(script_name).addCallback(function(content){
process.compile( content, script_name );
});
});
http.createServer(this.app).listen( 8080 );
Und in der Datei app.js habe ich:
var file = require('./file');
this.app = function(req, res) {
file.serveFile( req, res, 'file.js');
}
Aber das funktioniert auch nicht - ich bekomme einen Fehler in der process.compile()
-Anweisung, dass "Require" nicht definiert ist. process.compile
wertet die Datei app.js aus, hat jedoch keine Hinweise auf die globals von node.js.
Eine gute, aktuelle Alternative zu supervisor
ist nodemon
:
Überwachen Sie alle Änderungen in Ihrer node.js-Anwendung und starten Sie den Server automatisch neu - ideal für die Entwicklung
nodemon
verwenden:
$ npm install nodemon -g
$ nodemon app.js
node Supervisor ist großartig
verwendung zum Neustarten beim Speichern:
npm install supervisor -g supervisor app.js
von isaacs - http://github.com/isaacs/node-supervisor
ich habe einen einfachen Weg gefunden:
delete require.cache['/home/shimin/test2.js']
nodemon stand bei einer Google-Suche an erster Stelle und scheint den Trick zu vollbringen:
npm install nodemon -g
cd whatever_dir_holds_my_app
nodemon app.js
Wenn noch jemand zu dieser Frage kommt und diese nur mit den Standardmodulen lösen möchte, habe ich ein einfaches Beispiel gemacht:
var process = require('process');
var cp = require('child_process');
var fs = require('fs');
var server = cp.fork('server.js');
console.log('Server started');
fs.watchFile('server.js', function (event, filename) {
server.kill();
console.log('Server stopped');
server = cp.fork('server.js');
console.log('Server started');
});
process.on('SIGINT', function () {
server.kill();
fs.unwatchFile('server.js');
process.exit();
});
Dieses Beispiel gilt nur für eine Datei (server.js). Sie kann jedoch mit einem Array von Dateien, einer for-Schleife zum Abrufen aller Dateinamen oder durch Überwachen eines Verzeichnisses an mehrere Dateien angepasst werden:
fs.watch('./', function (event, filename) { // sub directory changes are not seen
console.log(`restart server`);
server.kill();
server = cp.fork('server.js');
})
Dieser Code wurde für Node.js 0.8 API erstellt. Er ist nicht für bestimmte Anforderungen geeignet, kann jedoch in einigen einfachen Apps verwendet werden.
UPDATE: Diese Funktion ist in meinem Modul implementiert simpleR , GitHub repo
Es gibt einen Node-Supervisor, den Sie installieren können
npm install supervisor
Edit: Meine Antwort ist veraltet. Node.js ist eine sich sehr schnell ändernde Technologie.
Ich wunderte mich auch über reloading -Module. Ich habe node.js geändert und die Quelle bei Github unter nalply/node veröffentlicht. Der einzige Unterschied ist die Funktion require
. Es hat ein optionales zweites Argument reload
.
require(url, reload)
Um app.js
im aktuellen Verzeichnis neu zu laden, verwenden Sie
app = require("./app", true);
Schreibe so etwas und du hast auto -reload:
process.watchFile(script_name, function(curr, prev) {
module = reload(script_name, true);
});
Das einzige Problem, das ich sehe, ist die Variable module
, aber ich arbeite gerade daran.
eine weitere Lösung für dieses Problem ist die Verwendung von forever
Eine weitere nützliche Funktion von Forever ist der optionale Neustart von Ihre Anwendung, wenn sich Quelldateien geändert haben. Das befreit dich Sie müssen nicht jedes Mal manuell neu starten, wenn Sie eine Funktion hinzufügen oder ein .__ beheben. Fehler. Um Forever in diesem Modus zu starten, verwenden Sie das Flag -w:
forever -w start server.js
Es gab ein aktuelles thread zu diesem Thema in der node.js-Mailingliste. Die kurze Antwort lautet nein. Derzeit ist es nicht möglich, erforderliche Dateien automatisch neu zu laden. Mehrere Personen haben jedoch Patches entwickelt, die diese Funktion hinzufügen.
Ich arbeite daran, ein ziemlich kleines Knoten-Ding zu erstellen, das Module nach Belieben laden/entladen kann (dh, Sie könnten möglicherweise einen Teil Ihrer Anwendung neu starten, ohne die gesamte App herunterzubringen) mit einem (sehr blöden) Abhängigkeitsmanagement, so dass alle Module, die davon abhängig sind, auch gestoppt werden, wenn Sie ein Modul stoppen möchten.
So weit so gut, aber dann bin ich auf die Frage gestoßen, wie man ein Modul neu lädt. Anscheinend könnte man das Modul einfach aus dem "Requirement" -Cache entfernen und die Arbeit erledigen lassen. Da ich den Knoten-Quellcode nicht direkt ändern möchte, habe ich einen very hacky-hack entwickelt, nämlich: search im Stack, den letzten Aufruf der Funktion "required" verfolgen, einen Verweis auf den Quellcode nehmen "cache" -Feld und..gut, löschen Sie die Referenz auf den Knoten:
var args = arguments
while(!args['1'] || !args['1'].cache) {
args = args.callee.caller.arguments
}
var cache = args['1'].cache
util.log('remove cache ' + moduleFullpathAndExt)
delete( cache[ moduleFullpathAndExt ] )
</ strike> Noch einfacher, eigentlich:
var deleteCache = function(moduleFullpathAndExt) {
delete( require.cache[ moduleFullpathAndExt ] )
}
Anscheinend funktioniert das gut. Ich habe absolut keine Ahnung, was diese Argumente ["1"] bedeuten, aber es macht seine Arbeit. Ich glaube, dass die Knoten-Jungs irgendwann eine Reload-Funktion implementieren werden, also denke ich, dass diese Lösung vorerst auch akzeptabel ist .. (übrigens, mein "Ding" wird hier sein: https://github.com/cheng81/wirez , geh in ein paar Wochen hin und du solltest sehen, wovon ich rede)
Hier ist ein Blogbeitrag über Hot Reloading for Node. Sie enthält einen github-Knotenzweig , den Sie verwenden können, um Ihre Installation von Node zu ersetzen, um das Hot Reloading zu aktivieren.
Von dem Blog:
var requestHandler = require('./myRequestHandler');
process.watchFile('./myRequestHandler', function () {
module.unCacheModule('./myRequestHandler');
requestHandler = require('./myRequestHandler');
}
var reqHandlerClosure = function (req, res) {
requestHandler.handle(req, res);
}
http.createServer(reqHandlerClosure).listen(8000);
Wenn Sie nun myRequestHandler.js ändern, wird der obige Code den lokalen requestHandler durch den neuen Code ersetzen und ersetzen. Alle vorhandenen Anforderungen verwenden weiterhin den alten Code, während alle neuen eingehenden Anforderungen den neuen Code verwenden. Alles ohne den Server herunterzufahren, Anfragen abzulösen, Anfragen vorzeitig zu beenden oder sich auf einen intelligenten Lastverteiler zu verlassen.
node-dev funktioniert super. npm install node-dev
Es gibt sogar eine Desktopbenachrichtigung, wenn der Server neu geladen wird, und gibt Erfolg oder Fehler in der Nachricht aus.
starten Sie Ihre App in der Befehlszeile mit:
node-dev app.js
Sie können nodemon ausNPM..__ verwenden. Wenn Sie den Express-Generator verwenden, können Sie diesen Befehl in Ihrem Projektordner verwenden:
nodemon npm start
oder im Debug-Modus
DEBUG=yourapp:* nodemon npm start
sie können auch direkt laufen
nodemon your-app-file.js
Ich hoffe das hilft.
nodemon
ist großartig. Ich füge einfach weitere Parameter zum Debuggen und Beobachten hinzu.
package.json
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon --watch server/**/*.js --inspect ./server/server.js"
}
nodemon --watch server/**/*.js --inspect ./server/server.js
Wohingegen:
--watch server/**/*.js
Starten Sie den Server nur dann neu, wenn Sie .js-Dateien im Ordner server
ändern.
--inspect
Remote-Debug aktivieren.
./server/server.js
Der Einstiegspunkt.
Fügen Sie dann die folgende Konfiguration zu launch.json
(VS-Code) hinzu und beginnen Sie jederzeit mit dem Debuggen.
{
"type": "node",
"request": "attach",
"name": "Attach",
"protocol": "inspector",
"port": 9229
}
Beachten Sie, dass es besser ist, nodemon
als dev-Abhängigkeit des Projekts zu installieren. Ihre Teammitglieder müssen sie also nicht installieren oder sich an die Befehlsargumente erinnern, sie npm run dev
und fangen an zu hacken.
lösung unter: http://github.com/shimondoodkin/node-hot-reload
beachten Sie, dass Sie die verwendeten Referenzen selbst beachten müssen.
das bedeutet, wenn Sie Folgendes getan haben: var x = required ('foo'); y = x; z = x.bar; und heiß reloadedit.
es bedeutet, dass Sie die in x, y und z gespeicherten Referenzen ersetzen müssen. in der Hot Reaload Callback-Funktion.
einige Leute verwechseln das heiße Neuladen mit dem automatischen Neustart Mein nodejs-autorestart-Modul verfügt auch über eine Upstart-Integration, um den automatischen Start beim Booten zu aktivieren. Wenn Sie eine kleine App haben, ist der automatische Neustart in Ordnung ist besser geeignet. einfach weil heißes nachladen schneller ist.
Ich mag auch mein Knoten-Zuflussmodul.
Nicht erforderlich, um nodemon oder andere Tools wie diese zu verwenden. Nutzen Sie einfach die Fähigkeiten Ihrer IDE.
Das Beste ist wahrscheinlich IntelliJ WebStorm mit Hot Reload-Funktion (automatisches Server- und Browser-Reload) für node.js .
eine andere einfache Lösung ist die Verwendung von fs.readFile anstelle von requir Sie können eine Textdatei mit einem Json-Objekt speichern und auf dem Server ein Intervall erstellen, um dieses Objekt erneut zu laden.
profis:
nachteile:
meine App-Struktur:
NodeAPP (folder)
|-- app (folder)
|-- all other file is here
|-- node_modules (folder)
|-- package.json
|-- server.js (my server file)
installiere zuerst reload mit diesem Befehl:
npm install [-g] [--save-dev] reload
dann ändere package.json :
"scripts": {
"start": "nodemon -e css,ejs,js,json --watch app"
}
jetzt müssen Sie reload in Ihrer Server-Datei verwenden :
var express = require('express');
var reload = require('reload');
var app = express();
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
console.log( 'server is running on port ' + app.get('port'));
});
reload(server, app);
und für die letzte Änderung, Ende Ihrer Antwort senden Sie dieses Skript :
<script src="/reload/reload.js"></script>
jetzt starte deine App mit diesem Code:
npm start
Hier ist eine Low-Tech-Methode für die Verwendung in Windows. Fügen Sie dies in eine Batchdatei mit dem Namen serve.bat
ein:
@echo off
:serve
start /wait node.exe %*
goto :serve
Führen Sie statt node app.js
von Ihrer Cmd-Shell aus serve app.js
aus.
Dadurch wird ein neues Shell-Fenster geöffnet, auf dem der Server ausgeführt wird. Die Batchdatei wird blockiert (aufgrund des /wait
), bis Sie das Shell-Fenster schließen. An diesem Punkt fragt die ursprüngliche Cmd-Shell "Batch-Job beenden (J/N)?" Wenn Sie "N" beantworten, wird der Server neu gestartet.
Schließen Sie bei jedem Neustart des Servers das Serverfenster und antworten Sie mit "N" in der Cmd-Shell.
Für Benutzer von Vagrant und PHPStorm ist file watcher ein schnellerer Ansatz
deaktivieren Sie die sofortige Synchronisierung der Dateien, sodass Sie den Befehl nur beim Speichern ausführen. Erstellen Sie dann einen Bereich für die * .js-Dateien und Arbeitsverzeichnisse und fügen Sie diesen Befehl hinzu
vagrant ssh -c "/var/www/gadelkareem.com/forever.sh restart"
wo für immer.sh ist wie
#!/bin/bash
cd /var/www/gadelkareem.com/ && forever $1 -l /var/www/gadelkareem.com/.tmp/log/forever.log -a app.js
Ich kam kürzlich zu dieser Frage, weil die üblichen Verdächtigen nicht mit verknüpften Paketen zusammenarbeiteten. Wenn Sie wie ich sind und npm link
während der Entwicklung nutzen, um effektiv an einem Projekt zu arbeiten, das aus vielen Paketen besteht, ist es wichtig, dass Änderungen in Abhängigkeiten auch ein Neuladen auslösen.
Nachdem Sie node-mon und pm2 ausprobiert hatten und ihre Anweisungen zum zusätzlichen Betrachten des Knotens node_modules befolgten, nahmen sie die Änderungen immer noch nicht auf. Obwohl die Antworten hier einige benutzerdefinierte Lösungen enthalten, ist ein separates Paket für so etwas sauberer. Ich bin heute auf node-dev gestoßen und es funktioniert perfekt ohne Optionen oder Konfiguration.
Aus der Liesmich:
Im Gegensatz zu Tools wie Supervisor oder Nodemon wird das Dateisystem nicht nach zu durchsuchenden Dateien durchsucht. Stattdessen hängt es an der Node-Funktion „request ()“, um nur die tatsächlich benötigten Dateien zu überwachen.
Benutze das:
function reload_config(file) {
if (!(this instanceof reload_config))
return new reload_config(file);
var self = this;
self.path = path.resolve(file);
fs.watchFile(file, function(curr, prev) {
delete require.cache[self.path];
_.extend(self, require(file));
});
_.extend(self, require(file));
}
Alles was Sie jetzt tun müssen, ist:
var config = reload_config("./config");
Und config wird automatisch neu geladen :)
loaddir ist meine Lösung zum schnellen Laden eines Verzeichnisses, rekursiv.
kann zurückkehren
{ 'path/to/file': 'fileContents...' }
oder { path: { to: { file: 'fileContents'} } }
Es hat callback
, das aufgerufen wird, wenn die Datei geändert wird.
Es behandelt Situationen, in denen Dateien so groß sind, dass watch
aufgerufen wird, bevor sie mit dem Schreiben fertig sind.
Ich verwende es seit ungefähr einem Jahr in Projekten und fügte kürzlich Versprechen hinzu.
Hilf mir, es zu testen!
Sie können Auto-Reload verwenden, um das Modul erneut zu laden, ohne den Server herunterzufahren.
npm install auto-reload
data.json
{ "name" : "Alan" }
test.js
var fs = require('fs');
var reload = require('auto-reload');
var data = reload('./data', 3000); // reload every 3 secs
// print data every sec
setInterval(function() {
console.log(data);
}, 1000);
// update data.json every 3 secs
setInterval(function() {
var data = '{ "name":"' + Math.random() + '" }';
fs.writeFile('./data.json', data);
}, 3000);
Ergebnis:
{ name: 'Alan' }
{ name: 'Alan' }
{ name: 'Alan' }
{ name: 'Alan' }
{ name: 'Alan' }
{ name: '0.8272748321760446' }
{ name: '0.8272748321760446' }
{ name: '0.8272748321760446' }
{ name: '0.07935990858823061' }
{ name: '0.07935990858823061' }
{ name: '0.07935990858823061' }
{ name: '0.20851597073487937' }
{ name: '0.20851597073487937' }
{ name: '0.20851597073487937' }
const cleanCache = (moduleId) => {
const module = require.cache[moduleId];
if (!module) {
return;
}
// 1. clean parent
if (module.parent) {
module.parent.children.splice(module.parent.children.indexOf(module), 1);
}
// 2. clean self
require.cache[moduleId] = null;
};
Heutzutage wird ein WebPack-Dev-Server mit Hot-Option verwendet. Sie können ein solches Skript in Ihre package.json einfügen: "hot": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --watch-poll",
und jede Änderung in Ihren Dateien wird automatisch eine Neukompilierung auslösen