Des idées sur la façon dont je pourrais implémenter un rechargement automatique des fichiers dans Node.js? J'en ai assez de redémarrer le serveur chaque fois que je modifie un fichier. Apparemment, la fonction require()
de Node.js ne recharge pas les fichiers s'ils ont déjà été requis, je dois donc faire quelque chose comme ceci:
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 );
Et dans le fichier app.js , j'ai:
var file = require('./file');
this.app = function(req, res) {
file.serveFile( req, res, 'file.js');
}
Mais cela ne fonctionne pas non plus - je reçois une erreur dans la déclaration process.compile()
qui dit que le mot «besoin» n’est pas défini. process.compile
évalue le app.js , mais n'a aucune idée sur les globaux de node.js.
Une bonne alternative à supervisor
est nodemon
:
Surveillez tout changement dans votre application node.js et redémarrez automatiquement le serveur - idéal pour le développement
Pour utiliser nodemon
:
$ npm install nodemon -g
$ nodemon app.js
le superviseur de noeud est génial
utilisation pour redémarrer lors de la sauvegarde:
npm installer supervisor -g supervisor app.js
par isaacs - http://github.com/isaacs/node-supervisor
j'ai trouvé un moyen simple:
delete require.cache['/home/shimin/test2.js']
nodemon est arrivé en premier dans une recherche google, et il semble faire l'affaire:
npm install nodemon -g
cd whatever_dir_holds_my_app
nodemon app.js
Si quelqu'un en arrive encore à cette question et veut le résoudre en utilisant uniquement les modules standard, j'ai créé un exemple simple:
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();
});
Cet exemple ne concerne qu'un fichier (server.js), mais peut être adapté à plusieurs fichiers à l'aide d'un tableau de fichiers, d'une boucle for pour obtenir tous les noms de fichiers ou en consultant un répertoire:
fs.watch('./', function (event, filename) { // sub directory changes are not seen
console.log(`restart server`);
server.kill();
server = cp.fork('server.js');
})
Ce code a été conçu pour l’API Node.js 0.8, il n’est pas adapté à certains besoins mais fonctionne dans certaines applications simples.
UPDATE: Cette fonctionnalité est implémentée dans mon module simpleR , GitHub repo
Il y a Node-Supervisor que vous pouvez installer par
npm install supervisor
Edit: Ma réponse est obsolète. Node.js est une technologie qui évolue très rapidement.
Je me suis aussi interrogé sur les modules reloading. J'ai modifié node.js et ai publié le source sur Github à nalply/node . La seule différence est la fonction require
. Il a un deuxième argument optionnel reload
.
require(url, reload)
Pour recharger app.js
dans le répertoire en cours, utilisez
app = require("./app", true);
Ecrivez quelque chose comme ceci et vous aurez auto -reload:
process.watchFile(script_name, function(curr, prev) {
module = reload(script_name, true);
});
Le seul problème que je vois est la variable module
, mais j'y travaille maintenant.
une autre solution à ce problème utilise pour toujours
Une autre possibilité utile de Forever est qu’il peut éventuellement redémarrer votre application lorsque des fichiers source ont changé. Cela vous libère d'avoir à redémarrer manuellement chaque fois que vous ajoutez une fonctionnalité ou corrigez un punaise. Pour démarrer Forever dans ce mode, utilisez l'indicateur -w:
forever -w start server.js
Il y avait un récent thread sur ce sujet sur la liste de diffusion de node.js. La réponse courte est non, il n'est actuellement pas possible de recharger automatiquement les fichiers requis, mais plusieurs personnes ont développé des correctifs qui ajoutent cette fonctionnalité.
Je travaille sur la création d’un "nœud" de nœud assez petit, capable de charger/décharger des modules à volonté (donc, c’est-à-dire que vous pourriez pouvoir redémarrer une partie de votre application sans la supprimer entièrement). J'incorpore une gestion de la dépendance (très stupide), de sorte que si vous voulez arrêter un module, tous les modules qui en dépendent seront également arrêtés.
Jusqu'ici tout va bien, mais je suis ensuite tombé sur la question de savoir comment recharger un module. Apparemment, il suffirait de retirer le module du cache "require" et de faire le travail. Comme je ne suis pas désireux de changer directement le code source du noeud, j’ai proposé un très hacky-hack: recherche dans la pile, trace le dernier appel à la commande "function, saisit une référence à son champ" cache "et..bien, supprime la référence au noeud:
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 ] )
Encore plus facile, en réalité:
var deleteCache = function(moduleFullpathAndExt) {
delete( require.cache[ moduleFullpathAndExt ] )
}
Apparemment, cela fonctionne très bien. Je n'ai absolument aucune idée de ce que ces arguments ["1"] signifient, mais il fait son travail. Je pense que les responsables des nœuds mettront en place un système de rechargement un jour, alors je suppose que pour le moment, cette solution est également acceptable. (d'ailleurs, mon "truc" sera ici: https://github.com/cheng81/wirez , allez-y dans quelques semaines et vous devriez voir de quoi je parle)
Ici est un article de blog sur Hot Reloading for Node. Il fournit une branche github Node que vous pouvez utiliser pour remplacer votre installation de Node afin de permettre le rechargement à chaud.
Du 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);
Désormais, chaque fois que vous modifiez myRequestHandler.js, le code ci-dessus remarquera et remplacera le gestionnaire de demandes local par le nouveau code. Toute demande existante continuera à utiliser l'ancien code, tandis que toute nouvelle demande entrante utilisera le nouveau code. Tout cela sans arrêter le serveur, ni faire rebondir les demandes, ni tuer prématurément les demandes, ni même s’appuyer sur un équilibreur de charge intelligent.
node-dev fonctionne très bien. npm install node-dev
Il donne même une notification au bureau lorsque le serveur est rechargé et donnera le succès ou des erreurs au message.
démarrez votre application en ligne de commande avec:
node-dev app.js
Vous pouvez utiliser nodemon fromNPM. Et si vous utilisez le générateur Express, vous pouvez utiliser cette commande dans le dossier de votre projet:
nodemon npm start
ou en utilisant le mode Debug
DEBUG=yourapp:* nodemon npm start
vous pouvez aussi courir directement
nodemon your-app-file.js
J'espère que cette aide.
nodemon
est super. Je viens d'ajouter plus de paramètres pour les options de débogage et de surveillance.
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
Tandis que:
--watch server/**/*.js
ne redémarre le serveur que lors de la modification de fichiers .js dans le dossier server
.
--inspect
Activer le débogage distant.
./server/server.js
Le point d'entrée.
Ajoutez ensuite la configuration suivante à launch.json
(Code VS) et démarrez le débogage à tout moment.
{
"type": "node",
"request": "attach",
"name": "Attach",
"protocol": "inspector",
"port": 9229
}
Notez qu'il est préférable d'installer nodemon
en tant que dépendance de dev du projet. Ainsi, les membres de votre équipe n'ont pas besoin de l'installer ni de se souvenir des arguments de la commande, ils ne font que npm run dev
et commencent à pirater.
solution à: http://github.com/shimondoodkin/node-hot-reload
remarquez que vous devez vous occuper vous-même des références utilisées.
cela signifie que si vous avez fait: var x = require ('foo'); y = x; z = x.bar; et rechargé à chaudit.
cela signifie que vous devez remplacer les références stockées dans x, y et z. dans la fonction de rappel hot reaload.
certaines personnes confondent le rechargement à chaud avec le redémarrage automatiquemy le module nodejs-autorestart a également une intégration upstart permettant le démarrage automatique au démarrage . est plus approprié. tout simplement parce que le rechargement à chaud est plus rapide.
J'aime aussi mon module d'afflux de nœuds.
Il n'est pas nécessaire d'utiliser nodemon ou d'autres outils de ce type. Utilisez simplement les capacités de votre IDE.
Le meilleur est probablement/ IntelliJ WebStorm avec fonction de rechargement à chaud (recharge automatique du serveur et du navigateur) pour node.js .
une autre solution simple consiste à utiliser fs.readFile au lieu de require Vous pouvez enregistrer un fichier texte contenant un objet JSON et créer un intervalle sur le serveur pour recharger cet objet.
avantages:
les inconvénients:
ma structure d'application:
NodeAPP (folder)
|-- app (folder)
|-- all other file is here
|-- node_modules (folder)
|-- package.json
|-- server.js (my server file)
installez d'abord reload avec cette commande:
npm install [-g] [--save-dev] reload
puis changez package.json :
"scripts": {
"start": "nodemon -e css,ejs,js,json --watch app"
}
maintenant vous devez utiliser reload dans votre fichier server :
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);
et pour le dernier changement, fin de votre réponse envoyer ce script :
<script src="/reload/reload.js"></script>
maintenant, démarrez votre application avec ce code:
npm start
Voici une méthode low tech à utiliser sous Windows. Placez ceci dans un fichier batch appelé serve.bat
:
@echo off
:serve
start /wait node.exe %*
goto :serve
Maintenant, au lieu d'exécuter node app.js
à partir de votre shell cmd, exécutez serve app.js
.
Cela ouvrira une nouvelle fenêtre Shell exécutant le serveur. Le fichier de commandes bloquera (à cause du /wait
) jusqu'à ce que vous fermiez la fenêtre du shell. À ce stade, le cmd Shell d'origine demandera "Mettre fin au travail par lots (O/N)?" Si vous répondez "N", le serveur sera relancé.
À chaque fois que vous souhaitez redémarrer le serveur, fermez la fenêtre du serveur et répondez "N" dans le shell de commandes.
Pour les personnes utilisant Vagrant et PHPStorm, l'observateur de fichiers est une approche plus rapide
désactive la synchronisation immédiate des fichiers afin que vous n'exécutiez la commande que lors de l'enregistrement, puis créez une étendue pour les fichiers * .js et les répertoires de travail, puis ajoutez cette commande
vagrant ssh -c "/var/www/gadelkareem.com/forever.sh restart"
où forever.sh est comme
#!/bin/bash
cd /var/www/gadelkareem.com/ && forever $1 -l /var/www/gadelkareem.com/.tmp/log/forever.log -a app.js
Je suis récemment venu à cette question parce que les suspects habituels ne travaillaient pas avec des paquets liés. Si vous êtes comme moi et que vous profitez de npm link
pendant le développement pour travailler efficacement sur un projet composé de nombreux packages, il est important que les changements apportés dans les dépendances déclenchent également un rechargement.
Après avoir essayé node-mon et pm2, même en suivant leurs instructions pour surveiller en plus le dossier node_modules, ils n'ont toujours pas pris en compte les modifications. Bien qu’il y ait des solutions personnalisées dans les réponses ici, pour quelque chose comme cela, un paquet séparé est plus propre. Je suis tombé sur node-dev aujourd'hui et cela fonctionne parfaitement sans options ni configuration.
Du Readme:
Contrairement à des outils tels que supervisor ou nodemon, il n’analyse pas le système de fichiers à la recherche de fichiers à regarder. Au lieu de cela, il se connecte à la fonction require () de Node pour ne regarder que les fichiers réellement requis.
Utilisez ceci:
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));
}
Tout ce que vous avez à faire maintenant est:
var config = reload_config("./config");
Et la configuration sera automatiquement rechargée :)
loaddir est ma solution pour le chargement rapide d'un répertoire, de manière récursive.
peut revenir
{ 'path/to/file': 'fileContents...' }
ou { path: { to: { file: 'fileContents'} } }
Il a callback
qui sera appelé lors de la modification du fichier.
Il gère les situations dans lesquelles les fichiers sont suffisamment volumineux pour que watch
soit appelé avant la fin de l'écriture.
Je l'utilise dans des projets depuis environ un an et j'ai récemment ajouté des promesses.
Aidez-moi à le tester!
Vous pouvez utiliser le rechargement automatique pour recharger le module sans arrêter le serveur.
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);
Résultat:
{ 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;
};
De nos jours, le serveur de développement WebPack avec option dynamique est utilisé. vous pouvez ajouter un script comme celui-ci dans votre package.json: "hot": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --watch-poll",
et chaque changement dans vos fichiers déclenchera automatiquement une recompilation