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

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

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

И в файле app.js у меня есть:

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

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

Ответ 1

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

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

Чтобы использовать nodemon:

$ npm install nodemon -g
$ nodemon app.js

Ответ 2

node -supervisor является удивительным

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

npm install supervisor -g
supervisor app.js

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

Ответ 3

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

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

Ответ 4

nodemon появился первым в поиске Google, и, похоже, это трюк:

npm install nodemon -g
cd whatever_dir_holds_my_app
nodemon app.js

Ответ 5

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

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), но может быть адаптирован к нескольким файлам с использованием массива файлов, цикла для получения всех имен файлов или просмотра каталога:

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

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

UPDATE: этот функционал реализован в моем модуле simpleR, GitHub repo

Ответ 7

Изменить: Мой ответ устарел. Node.js - очень быстрая технология.

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

require(url, reload)

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

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

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

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

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

Ответ 8

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

Ответ 9

еще одно решение этой проблемы - forever

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

forever -w start server.js

Ответ 10

Посмотрите require.hot() патч от Felix Geisendörfer. Я использую его с модифицированной каркасом Нерва.

EDIT: ссылка больше не работает, node repo перемещен в nodejs/node, отбрасывая все очень старые коммиты. Кажется.

Ответ 11

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

package.json

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

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

В то время как:

--watch server Перезапустите приложение при изменении .mjs .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 как dev-зависимость проекта. Таким образом, членам вашей команды не нужно устанавливать его или запоминать аргументы команды, они просто npm run dev и начинают взламывать.

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

Ответ 12

Здесь - сообщение в блоге о Hot Reloading для Node. Он предоставляет ветку github Node, которую вы можете использовать для замены вашей установки Node, чтобы включить Hot Reloading.

Из блога:

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 новым кодом. Любые существующие запросы будут продолжать использовать старый код, в то время как любые новые входящие запросы будут использовать новый код. Все, не выключая сервер, отказываясь от любых запросов, преждевременно убивают любые запросы или даже полагаются на интеллектуальный балансировщик нагрузки.

Ответ 13

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

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

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

Забастовкa > На самом деле проще:

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

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

Ответ 14

node -dev отлично работает. npm install node-dev

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

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

node-dev app.js

Ответ 15

Вы можете использовать nodemon из NPM. И если вы используете генератор Express, то вы можете использовать эту команду в папке вашего проекта:

nodemon npm start

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

DEBUG=yourapp:* nodemon npm start

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

nodemon your-app-file.js

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

Ответ 16

в: http://github.com/shimondoodkin/node-hot-reload

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

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

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

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

Также мне нравится мой node -интерфейс.

Ответ 17

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

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

Ответ 18

Здесь низкотехнологичный метод для использования в 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.

Ответ 19

Используйте это:

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

И config автоматически перезагрузится:)

Ответ 20

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

может возвращать

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

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

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

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

Помогите мне сразиться с этим!

https://github.com/danschumann/loaddir

Ответ 21

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

установить

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

Результат:

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

Ответ 22

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

плюсы:

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

минусы:

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

Ответ 23

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

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

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

где forever.sh похоже на

#!/bin/bash

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

Ответ 24

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

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

Из Readme:

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

Ответ 25

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

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

Ответ 26

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

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

сначала установите reload с помощью этой команды:

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

затем измените package.json:

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

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

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

Ответ 27

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