web-dev-qa-db-fra.com

Comment recharger automatiquement les fichiers dans Node.js?

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.

363
disc0dancer

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
418
Marius Butuc

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

304
Anup Bishnoi

j'ai trouvé un moyen simple:

delete require.cache['/home/shimin/test2.js']
79
Inshua

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
18
JnBrymn

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

16
micnic

Il y a Node-Supervisor que vous pouvez installer par

npm install supervisor

voir http://github.com/isaacs/node-supervisor

8
Richard Metzler

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.

7
nalply

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
5
Teoman shipahi

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

5
Xavi

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)

3
cheng81

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.

3
Chetan

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

2
l3o

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.

1
azwar_akbar

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.

1
Ninh Pham

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.

1
Shimon Doodkin

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 .

1
lukyer

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:

  • pas besoin d'utiliser des librairies externes
  • pertinent pour la production (rechargement du fichier de configuration en cas de modification)
  • facile à mettre en œuvre

les inconvénients:

  • vous ne pouvez pas recharger un module - juste un JSON contenant des données de valeur-clé
0
Imri

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
0

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.

0
yoyo

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
0
gadelkareem

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.

0
Aaron Storck

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 :)

0
offlinehacker

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!

https://github.com/danschumann/loaddir

0
Funkodebat

Vous pouvez utiliser le rechargement automatique pour recharger le module sans arrêter le serveur.

installer

npm install auto-reload

exemple

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' }
0
Lellansin
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;
};
0
BottleLiu

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

0
eKelvin