javascript node.js

javascript - ¿Cómo auto-recargar archivos en Node.js?



(23)

Encontré una manera simple:

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

¿Alguna idea sobre cómo podría implementar una recarga automática de archivos en Node.js? Estoy cansado de reiniciar el servidor cada vez que cambio un archivo. Al parecer, la función Node.js '' require() no vuelve a cargar los archivos si ya se han requerido, por lo que debo hacer algo como esto:

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

Y en el archivo app.js tengo:

var file = require(''./file''); this.app = function(req, res) { file.serveFile( req, res, ''file.js''); }

Pero esto tampoco funciona, recibo un error en la declaración process.compile() que dice que ''require'' no está definido. process.compile está evaluando app.js , pero no tiene ni idea de los globales de node.js.


Estoy trabajando para hacer una "cosa" de nodo bastante pequeña que sea capaz de cargar / descargar módulos a voluntad (por lo tanto, es posible que pueda reiniciar parte de su aplicación sin desactivar toda la aplicación). Estoy incorporando una administración de dependencias (muy estúpida), de modo que si desea detener un módulo, todos los módulos que dependen de eso también se detendrán.

Hasta ahora todo bien, pero luego me topé con la cuestión de cómo recargar un módulo. Aparentemente, uno podría simplemente quitar el módulo de la caché de "requerimiento" y hacer el trabajo. Ya que no estoy dispuesto a cambiar directamente el código fuente del nodo, se me ocurrió un hack-hacky que es: buscar en la pila rastrear la última llamada a la función "requerir", obtener una referencia a su campo "caché" y ... bueno, elimine la referencia al nodo:

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

Incluso más fácil, en realidad:

var deleteCache = function(moduleFullpathAndExt) { delete( require.cache[ moduleFullpathAndExt ] ) }

Al parecer, esto funciona bien. No tengo la menor idea de lo que significan esos argumentos ["1"], pero está haciendo su trabajo. Creo que los chicos del nodo implementarán un servicio de recarga algún día, así que supongo que por ahora esta solución también es aceptable. (por cierto, mi "cosa" estará aquí: https://github.com/cheng81/wirez , irá en un par de semanas y debería ver de lo que estoy hablando)


Hace poco llegué a esta pregunta porque los sospechosos habituales no trabajaban con paquetes vinculados. Si es como yo y está aprovechando el npm link durante el desarrollo para trabajar efectivamente en un proyecto que está compuesto de muchos paquetes, es importante que los cambios que se producen en las dependencias desencadenen también una recarga.

Después de haber probado node-mon y pm2, incluso siguiendo sus instrucciones para ver adicionalmente la carpeta node_modules, todavía no detectaron los cambios. Aunque hay algunas soluciones personalizadas en las respuestas aquí, para algo como esto, un paquete separado es más limpio. Me encontré con node-dev hoy y funciona perfectamente sin ninguna opción o configuración.

Desde el Readme:

En contraste con herramientas como supervisor o nodemon, no escanea el sistema de archivos para ver los archivos que se van a ver. En su lugar, se engancha a la función require () de Node para ver solo los archivos que realmente fueron necesarios.



Hoy en día se usa el servidor webPack dev con opción en caliente. puede agregar un script como este en su package.json: "hot": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --watch-poll",

y cada cambio en tus archivos activará una recompilación automáticamente


Hubo un thread reciente sobre este tema en la lista de correo de node.js. La respuesta corta es no, actualmente no es posible recargar automáticamente los archivos requeridos, pero varias personas han desarrollado parches que agregan esta función.


No es necesario usar nodemon u otras herramientas como esa. Solo usa las capacidades de tu IDE.

Probablemente el mejor es IntelliJ WebStorm con función de recarga en caliente (servidor automático y recarga del navegador) para node.js.


Otra solución para este problema es usar forever

Otra capacidad útil de Forever es que, opcionalmente, puede reiniciar su aplicación cuando cualquier archivo de origen haya cambiado. Esto le libera de tener que reiniciar manualmente cada vez que agregue una característica o arregle un error. Para iniciar Forever en este modo, use la marca -w:

forever -w start server.js


Para las personas que usan Vagrant y PHPStorm, el observador de archivos es un enfoque más rápido

  • deshabilite la sincronización inmediata de los archivos para que ejecute el comando solo en guardar, luego cree un ámbito para los archivos * .js y los directorios de trabajo y agregue este comando

    vagrant ssh -c "/var/www/gadelkareem.com/forever.sh restart"

donde para siempre.sh es como

#!/bin/bash cd /var/www/gadelkareem.com/ && forever $1 -l /var/www/gadelkareem.com/.tmp/log/forever.log -a app.js


Puede usar la recarga automática para recargar el módulo sin apagar el servidor.

instalar

npm install auto-reload

ejemplo

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

Resultado:

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


Puedes usar nodemon desde NPM . Y si está utilizando el generador Express, puede usar este comando dentro de la carpeta de su proyecto:

nodemon npm start

o usando el modo de depuración

DEBUG=yourapp:* nodemon npm start

Espero que esto ayude.


Si alguien sigue con esta pregunta y quiere resolverla usando solo los módulos estándar, hice un ejemplo 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(); });

Este ejemplo es solo para un archivo (server.js), pero se puede adaptar a múltiples archivos usando una matriz de archivos, un bucle for para obtener todos los nombres de archivos o viendo un directorio:

fs.watch(''./'', function (event, filename) { // sub directory changes are not seen console.log(`restart server`); server.kill(); server = cp.fork(''server.js''); })

Este código fue creado para Node.js 0.8 API, no está adaptado para algunas necesidades específicas, pero funcionará en algunas aplicaciones simples.

ACTUALIZACIÓN: Esta función se implementa en mi módulo simpleR , repo de GitHub


Una buena alternativa actualizada al supervisor es nodemon :

Supervise cualquier cambio en su aplicación node.js y reinicie automáticamente el servidor, perfecto para el desarrollo

Para utilizar nodemon :

$ npm install nodemon -g $ nodemon app.js


Utilizar esta:

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)); }

Todo lo que tienes que hacer ahora es:

var config = reload_config("./config");

Y la configuración se recargará automáticamente :)


loaddir es mi solución para la carga rápida de un directorio, recursivamente.

puede regresar

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

Tiene callback que se llamará cuando se cambie el archivo.

Maneja situaciones en las que los archivos son lo suficientemente grandes para que se pueda watch el watch antes de terminar de escribir.

Lo he estado usando en proyectos durante un año más o menos, y recientemente le agregué promesas.

¡Ayúdame a la batalla a probarlo!

https://github.com/danschumann/loaddir


node-dev funciona muy bien. npm install node-dev

Incluso da una notificación de escritorio cuando se recarga el servidor y dará éxito o errores en el mensaje.

inicia tu aplicación en la línea de comandos con:

node-dev app.js


otra solución simple es usar fs.readFile en lugar de usar require , puede guardar un archivo de texto que contenga un objeto json y crear un intervalo en el servidor para volver a cargar este objeto.

pros:

  • no hay necesidad de usar librerías externas
  • relevante para la producción (volver a cargar el archivo de configuración en el cambio)
  • fácil de implementar

contras:

  • no puede volver a cargar un módulo, solo un json que contiene datos de valor clave

solución en: http://github.com/shimondoodkin/node-hot-reload

Tenga en cuenta que debe cuidar usted mismo de las referencias utilizadas.

eso significa que si lo hiciste: var x = require (''foo''); y = x; z = x.bar; Y lo recargué en caliente.

significa que tienes que reemplazar las referencias almacenadas en x, y y z. en la función de devolución de llamada de recarga en caliente.

algunas personas confunden la recarga en caliente con el reinicio automático de mi módulo nodejs-autorestart que también tiene la integración inicial para permitir el inicio automático en el arranque. Si tienes una aplicación pequeña, el reinicio automático está bien, pero cuando tienes una aplicación grande, la recarga en caliente es más adecuada. simplemente porque la recarga en caliente es más rápida.

También me gusta mi módulo de entrada de nodo.



Here hay una entrada de blog sobre la recarga en caliente para el nodo. Proporciona una rama de Github Node que puede usar para reemplazar su instalación de Node para habilitar la recarga en caliente.

Desde el 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);

Ahora, cada vez que modifique myRequestHandler.js, el código anterior notará y reemplazará el requestHandler local con el nuevo código. Cualquier solicitud existente continuará usando el código anterior, mientras que cualquier solicitud nueva entrará al código nuevo. Todo sin apagar el servidor, rebotar cualquier solicitud, matar prematuramente cualquier solicitud, o incluso confiar en un equilibrador de carga inteligente.


nodemon es genial Acabo de añadir más parámetros para depurar y ver opciones.

paquete.json

"scripts": { "dev": "cross-env NODE_ENV=development nodemon --watch server/**/*.js --inspect ./server/server.js" }

nodemon --watch server/**/*.js --inspect ./server/server.js

Mientras:

--watch server/**/*.js solo reinicia el servidor al cambiar los archivos .js en la carpeta del server .

--inspect Habilitar depuración remota.

./server/server.js El punto de entrada.

Luego agregue la siguiente configuración a launch.json (Código VS) y comience a depurar en cualquier momento.

{ "type": "node", "request": "attach", "name": "Attach", "protocol": "inspector", "port": 9229 }

Tenga en cuenta que es mejor instalar nodemon como la dependencia dev del proyecto. Así que los miembros de su equipo no necesitan instalarlo o recordar los argumentos del comando, simplemente npm run dev y comienzan a piratear.


nodemon apareció primero en una búsqueda de google, y parece hacer el truco:

npm install nodemon -g cd whatever_dir_holds_my_app nodemon app.js


Edit: Mi respuesta es obsoleta. Node.js es una tecnología que cambia muy rápido.

También me preguntaba sobre la recarga de módulos. Modifiqué node.js y publiqué la fuente en Github en nalply/node . La única diferencia es la función que require . Tiene una segunda reload opcional de argumentos.

require(url, reload)

Para recargar app.js en el directorio actual use

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

Escribe algo como esto, y tienes auto- recarga:

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

El único problema que veo es el module variable, pero ahora estoy trabajando en ello.