Как автоматически перезагрузить файлы в Node.js?

StackOverflow https://stackoverflow.com/questions/1972242

  •  21-09-2019
  •  | 
  •  

Вопрос

Есть идеи, как реализовать автоматическую перезагрузку файлов в Node.js?Я устал перезапускать сервер каждый раз, когда меняю файл.Судя по всему Node.js' require() функция не перезагружает файлы, если они уже были необходимы, поэтому мне нужно сделать что-то вроде этого:

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

И в приложение.js файл у меня есть:

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

Но это тоже не работает - получаю ошибку в process.compile() заявление о том, что «требование» не определено. process.compile оценивает приложение.js, но понятия не имеет о глобальных параметрах node.js.

Это было полезно?

Решение

Хорошая и актуальная альтернатива supervisor является nodemon:

Отслеживайте любые изменения в вашем приложении node.js и автоматически перезапускайте сервер — идеально подходит для разработки.

Использовать nodemon:

$ npm install nodemon -g
$ nodemon app.js

Другие советы

Node-Supervisor потрясающий

использование для перезапуска при сохранении:

npm install supervisor -g
supervisor app.js

от Айзекса - http://github.com/isaacs/node-supervisor

я нашел простой способ:

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

нодмон появилось первым в поиске Google, и, похоже, это помогло:

npm install nodemon -g
cd whatever_dir_holds_my_app
nodemon app.js

Если кто-то все еще задается этим вопросом и хочет решить его, используя только стандартные модули, я привел простой пример:

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

Этот пример предназначен только для одного файла (server.js), но его можно адаптировать для нескольких файлов, используя массив файлов, цикл for для получения всех имен файлов или просмотр каталога:

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

Этот код был создан для API Node.js 0.8, он не адаптирован для каких-то конкретных нужд, но будет работать в некоторых простых приложениях.

ОБНОВЛЯТЬ:Этот функционал реализован в моем модуле простойR, Репозиторий GitHub

Существует Node-Supervisor, который вы можете установить с помощью

npm install supervisor

видеть http://github.com/isaacs/node-supervisor

Редактировать: Мой ответ устарел.Node.js — очень быстро меняющаяся технология.

Я также задавался вопросом о перезарядка модули.Я изменил node.js и опубликовал исходный код на Github по адресу налпли/узел.Единственное отличие – это функция require.Имеет необязательный второй аргумент reload.

require(url, reload)

Чтобы перезагрузить app.js в текущем каталоге использовать

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

Напишите что-то вроде этого, и у вас есть авто-перезагрузить:

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

Единственная проблема, которую я вижу, это переменная module, но я сейчас над этим работаю.

Был недавний нить об этой теме в списке рассылки node.js.Короткий ответ: нет, в настоящее время автоматическая перезагрузка необходимых файлов невозможна, но несколько человек разработали патчи, добавляющие эту функцию.

еще одно решение этой проблемы — использование навсегда

Еще одна полезная возможность навсегда заключается в том, что он может при желании перезагрузить ваше приложение при изменении каких -либо исходных файлов.Это освобождает вас от необходимости перезапуска вручную каждый раз, когда вы добавляете функцию или исправляете ошибку.Чтобы запустить Forever в этом режиме, используйте флаг -w:

forever -w start server.js

nodemon отличный.Я просто добавляю больше параметров для отладки и просмотра опций.

пакет.json

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

Команда: nodemon --watch server --inspect ./server/server.js

Тогда как:

--watch server Перезапустите приложение при изменении .js, .mjs, .coffee, .litcoffee, и .json файлы в server папка (включая подпапки).

--inspect Включите удаленную отладку.

./server/server.js Точка входа.

Затем добавьте следующую конфигурацию в launch.json (VS Code) и начните отладку в любое время.

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

Обратите внимание, что лучше установить nodemon как зависимость проекта от разработчиков.Таким образом, членам вашей команды не нужно устанавливать его или запоминать аргументы команды, им просто npm run dev и начать взлом.

Смотрите больше на nodemon документы: https://github.com/remy/nodemon#monitoring-multiple-directories

node-dev работает отлично.НПМ install node-dev

Он даже выдает уведомление на рабочем столе, когда сервер перезагружается, и сообщает об успехе или ошибке сообщения.

запустите свое приложение в командной строке с помощью:

node-dev app.js

Здесь — это сообщение в блоге о горячей перезагрузке для Node.Это обеспечивает ветка узла github который вы можете использовать для замены установки Node, чтобы включить горячую перезагрузку.

Из блога:

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

Теперь каждый раз, когда вы изменяете myRequestHandler.js, приведенный выше код заметит и заменит локальный requestHandler новым кодом.Все существующие запросы будут продолжать использовать старый код, а все новые входящие запросы будут использовать новый код.И все это без выключения сервера, отклонения каких-либо запросов, преждевременного прекращения любых запросов и даже без использования интеллектуального балансировщика нагрузки.

Я работаю над созданием довольно крошечного узла, который может загружать/выгружать модули по своему желанию (т.е.вы можете перезапустить часть своего приложения, не отключая все приложение).Я включаю (очень глупое) управление зависимостями, так что если вы захотите остановить модуль, все модули, которые от него зависят, также будут остановлены.

Пока всё хорошо, но тут я наткнулся на вопрос, как перезагрузить модуль.По-видимому, можно было бы просто удалить модуль из «требуемого» кеша и завершить работу.Поскольку я не хочу напрямую менять исходный код узла, я придумал очень хаки-хак это:найдите в стеке трассировку последнего вызова функции "require", возьмите ссылку на ее поле "cache" и... ну, удалите ссылку на узел:

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

На самом деле даже проще:

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

Судя по всему, это прекрасно работает.Я понятия не имею, что означают эти аргументы["1"], но они делают свою работу.Я верю, что ребята из узла когда-нибудь реализуют возможность перезагрузки, поэтому я думаю, что на данный момент это решение тоже приемлемо.(кстати.моя «штука» будет здесь: https://github.com/cheng81/wirez , съезди туда через пару недель и поймешь, о чем я говорю)

Вы можете использовать нодмон от НПМ.А если вы используете экспресс-генератор, вы можете использовать эту команду в папке вашего проекта:

nodemon npm start

или используя режим отладки

DEBUG=yourapp:* nodemon npm start

вы также можете запустить напрямую

nodemon your-app-file.js

Надеюсь, это поможет.

решение по адресу:http://github.com/shimondoodkin/node-hot-reload

обратите внимание, что вы должны сами позаботиться об используемых ссылках.

это означает, что если вы это сделали:вар x=require('foo');y=x;z=x.bar;и горячий перезарядил его.

это означает, что вам нужно заменить ссылки, хранящиеся в x, y и z.в функции обратного вызова горячей перезагрузки.

Некоторые люди путают горячую перезагрузку с автоматическим перезапуском моего модуля Nodejs-AutoRestart также имеют интеграцию Upstart, чтобы включить автоматическое запуск на загрузке.если у вас есть небольшой автоматический перезапуск приложения, это нормально, но если у вас есть большое приложение, более подходящей является горячая перезагрузка.просто потому, что горячая перезагрузка происходит быстрее.

Также мне нравится мой модуль node-inflow.

Не обязательно использовать нодмон или другие подобные инструменты.Просто используйте возможности вашей IDE.

Наверное, лучший из них IntelliJ WebStorm с функцией горячей перезагрузки (автоматическая перезагрузка сервера и браузера) для узел.js.

Вот простой метод для использования в Windows.Поместите это в пакетный файл с именем serve.bat:

@echo off

:serve
start /wait node.exe %*
goto :serve

Теперь вместо бега node app.js из вашей оболочки cmd запустите serve app.js.

Откроется новое окно оболочки, на котором работает сервер.Пакетный файл будет заблокирован (из-за /wait) до тех пор, пока вы не закроете окно оболочки, в этот момент исходная оболочка CMD спросит «Завершение партийного задания (y/n)?» Если вы ответите «n», то сервер будет перезапущен.

Каждый раз, когда вы хотите перезапустить сервер, закройте окно сервера и ответьте «N» в оболочке cmd.

структура моего приложения:

NodeAPP (folder)
   |-- app (folder)
      |-- all other file is here
   |-- node_modules (folder)
   |-- package.json
   |-- server.js (my server file)

первая установка перезагрузить с помощью этой команды:

npm install [-g] [--save-dev] reload

тогда измени пакет.json:

"scripts": {
    "start": "nodemon -e css,ejs,js,json --watch app"
}

теперь вы должны использовать перезагрузку в своем файл сервера:

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

и в качестве последнего изменения в конце ответа отправьте это сценарий:

<script src="/reload/reload.js"></script>

теперь запустите свое приложение с помощью этого кода:

npm start

Использовать это:

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

Все, что вам нужно сделать сейчас, это:

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

И конфиг автоматически обновится :)

loaddir — мое решение для быстрой рекурсивной загрузки каталога.

могу вернуться

{ 'path/to/file': 'fileContents...' }или{ path: { to: { file: 'fileContents'} } }

В нем есть callback который будет вызываться при изменении файла.

Он обрабатывает ситуации, когда файлы достаточно велики, watch им звонят до того, как они закончат писать.

Я использую его в проектах около года и совсем недавно добавил к нему обещания.

Помогите мне проверить это в бою!

https://github.com/danschumann/loaddir

Вы можете использовать автоматическую перезагрузку, чтобы перезагрузить модуль без выключения сервера.

установить

npm install auto-reload

пример

данные.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);

Результат:

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

еще одно простое решение — используйте fs.readFile вместо использования requireвы можете сохранить текстовый файл, содержащий объект JSON, и создать интервал на сервере для перезагрузки этого объекта.

плюсы:

  • нет необходимости использовать внешние библиотеки
  • актуально для производства (перезагрузка файла конфигурации при изменении)
  • легко реализовать

минусы:

  • вы не можете перезагрузить модуль - только json, содержащий данные значения ключа

Для людей, использующих Vagrant и PHPStorm, наблюдатель за файлами это более быстрый подход

  • отключите немедленную синхронизацию файлов, чтобы запускать команду только при сохранении, затем создайте область для файлов *.js и рабочих каталогов и добавьте эту команду

    vagrant ssh -c "/var/www/gadelkareem.com/forever.sh перезапустить"

где forever.sh такой

#!/bin/bash

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

Недавно я задался этим вопросом, потому что обычные подозреваемые не работали со связанными пакетами.Если вы похожи на меня и пользуетесь npm link Во время разработки для эффективной работы над проектом, состоящим из множества пакетов, важно, чтобы изменения, происходящие в зависимостях, также вызывали перезагрузку.

Попробовав node-mon и pm2, даже следуя их инструкциям по дополнительному просмотру папки node_modules, они все равно не подхватили изменения.Хотя в ответах здесь есть некоторые специальные решения, для чего-то подобного лучше использовать отдельный пакет.я наткнулся узел-разработчик сегодня и он отлично работает без каких-либо опций или настроек.

Из Readme:

В отличие от таких инструментов, как Supervisor или Nodemon, он не сканирует файловую систему на наличие файлов, которые нужно просмотреть.Вместо этого он подключается к функции Node require(), чтобы просматривать только те файлы, которые действительно необходимы.

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

В настоящее время используется сервер разработки WebPack с горячей опцией.вы можете добавить такой скрипт в свой package.json: "hot": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --watch-poll",

и каждое изменение в ваших файлах автоматически вызовет перекомпиляцию

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top