javascript - Comment recharger automatiquement des fichiers dans Node.js?




(15)

De nos jours, le serveur de développement WebPack avec option chaude 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

EDIT: Utilisez http://github.com/isaacs/node-supervisor ; C'est une vieille question et l'exemple de code est fait avec une API Node.js obsolète.

Des idées sur la façon dont je pourrais implémenter un rechargement automatique de fichiers dans Node.js? Je suis fatigué de redémarrer le serveur chaque fois que je change un fichier. Apparemment, la fonction require() Node.js ne recharge pas les fichiers s'ils ont déjà été requis, donc je dois 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 - j'obtiens une erreur dans l'instruction process.compile() indiquant que 'require' n'est pas défini. process.compile évalue l' app.js , mais n'a aucune idée des globals node.js.



Je suis récemment arrivé à cette question parce que les suspects habituels ne travaillaient pas avec des paquets liés. Si vous êtes comme moi et que vous utilisez le npm link pendant le développement pour travailler efficacement sur un projet constitué de nombreux paquets, il est important que les changements qui surviennent dans les dépendances déclenchent également un rechargement.

Après avoir essayé node-mon et pm2, même en suivant leurs instructions pour regarder de plus le dossier node_modules, ils n'ont toujours pas détecté les changements. Bien qu'il y ait quelques solutions personnalisées dans les réponses ici, pour quelque chose comme ceci, un paquet séparé est plus propre. Je suis tombé sur node-dev aujourd'hui et cela fonctionne parfaitement sans aucune option ou configuration.

À partir du fichier Readme:

Contrairement aux outils tels que superviseur ou nodemon, il n'analyse pas le système de fichiers pour les fichiers à regarder. Au lieu de cela, il se connecte à la fonction require () de Node pour ne regarder que les fichiers réellement requis.


Je travaille sur la création d'un nœud "chose" plutôt minuscule capable de charger / décharger des modules à volonté (ainsi, vous pourriez être en mesure de redémarrer une partie de votre application sans avoir à supprimer toute l'application). J'incorpore une gestion des dépendances (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 tombé sur la question de savoir comment recharger un module. Apparemment, on pourrait simplement enlever le module du cache "require" et faire le travail. Comme je ne tiens pas à modifier directement le code source du nœud, j'ai créé un hacky-hack qui est: la recherche dans la pile trace le dernier appel à la fonction "require", saisit une référence à son champ "cache" et bien, supprimez 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 fait:

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 ils font leur travail. Je crois que les gars du noeud vont implémenter une facilité de rechargement un jour, donc je suppose que pour l'instant cette solution est également acceptable. (btw mon "truc" sera ici: https://github.com/cheng81/wirez , allez-y dans quelques semaines et vous devriez voir de quoi je parle)


Pour les utilisateurs de Vagrant et de PHPStorm, l' observateur de fichiers est une approche plus rapide

  • Désactivez la synchronisation immédiate des fichiers afin de ne lancer la commande que lors de la sauvegarde, puis créez une étendue pour les fichiers * .js et les répertoires de travail et ajoutez cette commande

    vagabond 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

Si quelqu'un vient encore à cette question et veut la résoudre en utilisant seulement les modules standard, j'ai fait 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 concerne seulement un fichier (server.js), mais peut être adapté à plusieurs fichiers en utilisant un tableau de fichiers, une boucle for pour obtenir tous les noms de fichiers ou en regardant 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é créé pour l'API Node.js 0.8, il n'est pas adapté pour certains besoins spécifiques mais fonctionnera dans certaines applications simples.

UPDATE: Cette fonctionnalité est implémentée dans mon module simpleR , GitHub repo


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 config sera automatiquement rechargée :)


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

j'ai trouvé un moyen simple:

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

loaddir est ma solution pour le chargement rapide d'un répertoire, récursivement.

peut retourner

{ 'path/to/file': 'fileContents...' } ou { path: { to: { file: 'fileContents'} } }

Il a callback qui sera appelé lorsque le fichier est modifié.

Il gère les situations où les fichiers sont suffisamment grands pour que la watch soit appelée avant d'avoir fini d'écrire.

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


node-dev fonctionne très bien. npm install node-dev

Il donne même une notification de bureau quand le serveur est rechargé et donnera le succès ou les erreurs sur le message.

démarrez votre application en ligne de commande avec:

node-dev app.js


solution à: http://github.com/shimondoodkin/node-hot-reload

remarquez que vous devez prendre soin des références utilisées.

cela signifie que si vous avez fait: var x = require ('foo'); y = x; z = x.bar; et chaud l'a rechargé.

cela signifie que vous devez remplacer les références stockées dans x, y et z. dans la fonction de rappel de chargement réel.

Certaines personnes confondent le rechargement à chaud avec le redémarrage automatique. Mon module nodejs-autorestart a aussi l'intégration par défaut pour activer le démarrage automatique au démarrage. Si vous avez une petite application redémarrage automatique est très bien, mais quand vous avez une grande application de rechargement à chaud est plus approprié. simplement parce que le rechargement à chaud est plus rapide.

J'aime aussi mon module d'entrée de nœud.


Here un article de blog à propos de Hot Reloading for Node. Il fournit une branche de nœud github que vous pouvez utiliser pour remplacer votre installation de nœud pour activer 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);

Maintenant, chaque fois que vous modifiez myRequestHandler.js, le code ci-dessus remarquera et remplacera le requestHandler local avec le nouveau code. Toutes les demandes existantes continueront à utiliser l'ancien code, tandis que les nouvelles demandes entrantes utiliseront le nouveau code. Tout cela sans arrêter le serveur, faire rebondir les demandes, tuer prématurément toutes les demandes, ou même se fier à un équilibreur de charge intelligent.


nodemon est génial. Je viens d'ajouter plus de paramètres pour le débogage et le visionnage des options.

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 que le serveur lors de la modification des fichiers .js dans le dossier du server .

--inspect Activer le débogage distant.

./server/server.js Le point d'entrée.

Ajoutez ensuite la configuration suivante à launch.json (VS Code) et commencez 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 tant que dépendance du projet. Ainsi, les membres de votre équipe n'ont pas besoin de l'installer ou de se souvenir des arguments de la commande, ils npm run dev simplement npm run dev et commencent à pirater.


Edit: Ma réponse est obsolète. Node.js est une technologie très changeante.

Je me suis également posé des questions sur le rechargement de modules. J'ai modifié node.js et j'ai publié la 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 l'utilisation actuelle du répertoire

app = require("./app", true);

Écrivez quelque chose comme ceci, et vous avez le chargement automatique :

process.watchFile(script_name, function(curr, prev) {
    module = reload(script_name, true);
});

Le seul problème que je vois est le module variable, mais je travaille dessus maintenant.







node.js