Programming

Node.js에서 파일을 자동으로 다시로드하는 방법?

procodes 2020. 2. 21. 22:32
반응형

Node.js에서 파일을 자동으로 다시로드하는 방법?


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

그리고 app.js 파일에는 다음이 있습니다.

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

그러나 이것은 작동하지 않습니다 process.compile().'require '가 정의되어 있지 않다는 문장 에서 오류가 발생합니다 . process.compileapp.js를 회피 하고 있지만 node.js 전역에 대한 실마리는 없습니다.


최신의 대안 supervisornodemon다음과 같습니다.

node.js 애플리케이션의 변경 사항을 모니터링하고 서버를 자동으로 다시 시작하십시오. 개발에 적합합니다.

사용하려면 nodemon:

$ npm install nodemon -g
$ nodemon app.js

노드 감독자는 굉장하다

저장시 다시 시작하는 사용법 :

npm 설치 관리자 -g
감독자 app.js

이삭에 의해 - http://github.com/isaacs/node-supervisor


나는 간단한 방법을 찾았다.

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

nodemon 은 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');    
})

이 코드는 Node.js 0.8 API 용으로 만들어졌으며 특정 요구 사항에 적합하지 않지만 간단한 앱에서는 작동합니다.

업데이트 :이 기능은 내 모듈 simpleR , GitHub repo 에서 구현됩니다.


설치할 수있는 Node-Supervisor가 있습니다

npm install supervisor

참조 http://github.com/isaacs/node-supervisor를


편집 : 내 대답은 더 이상 사용되지 않습니다. Node.js는 매우 빠르게 변화하는 기술입니다.

또한 모듈을 다시로드하는 것에 대해 궁금했습니다 . node.js를 수정하고 nalply / node의 Github에 소스를 게시했습니다 . 유일한 차이점은 기능 require입니다. 선택적인 두 번째 인수가 reload있습니다.

require(url, reload)

app.js현재 디렉토리에서 다시로드하려면

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

다음과 같이 작성하면 자동 다시로드됩니다 .

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

내가 볼 수있는 유일한 문제는 variable module이지만 지금 작업 중입니다.


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변경시 응용 프로그램을 다시 시작 .js, .mjs, .coffee, .litcoffee, 및 .json의 파일 server폴더 (하위 폴더 포함).

--inspect 원격 디버그를 활성화하십시오.

./server/server.js 진입 점.

그런 다음 launch.json(VS 코드)에 다음 구성을 추가하고 언제든지 디버깅을 시작하십시오.

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

nodemon프로젝트의 개발자 의존성으로 설치하는 것이 좋습니다 . 따라서 팀 구성원은 설치하거나 명령 인수를 기억할 필요가 없으며 단지 npm run dev해킹을 시작합니다.

nodemon문서 에 대한 자세한 내용은 https://github.com/remy/nodemon#monitoring-multiple-directories를 참조하십시오.


node.js 메일 링리스트에서이 주제에 관한 최근 스레드 가있었습니다 . 짧은 대답은 아니요, 현재 자동 재로드가 필요한 파일은 아니지만 여러 사람들이이 기능을 추가하는 패치를 개발 한 것입니다.


이 문제에 대한 또 다른 해결책은 영원히 사용하는 것입니다.

Forever의 또 다른 유용한 기능은 소스 파일이 변경된 경우 응용 프로그램을 선택적으로 다시 시작할 수 있다는 것입니다. 그러면 기능을 추가하거나 버그를 수정할 때마다 수동으로 다시 시작하지 않아도됩니다. 이 모드에서 Forever를 시작하려면 -w 플래그를 사용하십시오.

forever -w start server.js

node-dev는 훌륭하게 작동합니다. npminstall node-dev

서버를 다시로드 할 때 바탕 화면 알림을 제공하고 메시지에 성공 또는 오류를 표시합니다.

다음을 사용하여 명령 줄에서 앱을 시작하십시오.

node-dev app.js


다음 은 노드에 대한 핫 리로드에 대한 블로그 게시물입니다. 핫 리로드를 활성화하기 위해 노드 설치를 교체하는 데 사용할 수 있는 github 노드 분기제공합니다 .

블로그에서 :

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"]이 무엇을 의미하는지 전혀 모른다. 그러나 그것은 그 일을하고있다. 나는 노드 사람들이 언젠가 리로드 기능을 구현할 것이라고 믿기 때문에 지금은이 솔루션도 수용 가능하다고 생각합니다. (btw. 내 "것"은 여기에 있습니다 : https://github.com/cheng81/wirez , 몇 주 후에 거기에 가면 내가 말하는 것을 볼 수 있습니다)


NPM 에서 nodemon사용할 수 있습니다 . Express 생성기를 사용하는 경우 프로젝트 폴더 내에서이 명령을 사용할 수 있습니다.

nodemon npm start

또는 디버그 모드 사용

DEBUG=yourapp:* nodemon npm start

당신은 또한 직접 실행할 수 있습니다

nodemon your-app-file.js

이 도움을 바랍니다.


솔루션 : http://github.com/shimondoodkin/node-hot-reload

사용 된 참고 문헌을 직접 관리해야합니다.

즉, 수행 한 경우 다음을 의미합니다. var x = require ( 'foo'); y = x; z = x.bar; 그리고 그것을 다시 장전했다.

즉, x, y 및 z에 저장된 참조를 교체해야합니다. 핫 리로드 콜백 함수에서.

어떤 사람들은 자동 재시작과 핫 리로드를 혼동합니다. nodejs-autorestart 모듈에는 부팅시 자동 시작을 활성화하기 위해 시동 통합 기능이 있습니다. 작은 응용 프로그램을 사용하는 경우 자동 다시 시작은 좋지만 큰 응용 프로그램을 사용하는 경우 핫 리로드가 더 적합합니다. 핫 리로드가 더 빠르기 때문입니다.

또한 노드 유입 모듈을 좋아합니다.


nodemon 또는 다른 도구 를 사용할 필요는 없습니다 . IDE의 기능 만 사용하십시오.

아마도 가장 좋은 방법은 node.js에 대한 핫 리로드 기능 (자동 서버 및 브라우저 리로드)을 갖춘 IntelliJ WebStorm 입니다 .


Windows에서 사용하기위한 기술이 낮은 방법은 다음과 같습니다. 이것을 배치 파일에 넣으십시오 serve.bat.

@echo off

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

이제 node app.jscmd 쉘에서 실행 하는 대신을 실행 하십시오 serve app.js.

서버를 실행하는 새로운 쉘 창이 열립니다. /wait셸 창을 닫을 때까지 배치 파일이 (때문에 ) 차단 됩니다.이 시점에서 원래 cmd 쉘은 "일괄 처리 종료 (Y / N)?"를 묻습니다. "N"으로 대답하면 서버가 다시 시작됩니다.

서버를 다시 시작할 때마다 서버 창을 닫고 cmd 쉘에서 "N"으로 응답하십시오.


내 앱 구조 :

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

그런 다음 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

이것을 사용하십시오 :

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작성이 완료되기 전에 파일이 충분히 커지는 상황을 처리합니다 .

나는 1 년 정도 동안 프로젝트에서 사용했으며 최근에 약속을 추가했습니다.

https://github.com/danschumann/loaddir


자동 재로드를 사용하여 서버를 종료하지 않고 모듈을 재로드 할 수 있습니다.

설치

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

또 다른 간단한 해결책은 json 객체를 포함하는 텍스트 파일을 저장하고 서버에서 간격을 만들어이 객체를 다시로드 할 수 있도록하는 대신 fs.readFile을 사용하는 것입니다.

찬성 :

  • 외부 라이브러리를 사용할 필요가 없습니다
  • 프로덕션 관련 (변경시 구성 파일 다시로드)
  • 구현하기 쉬운

단점 :

  • 키-값 데이터를 포함하는 json 만 모듈을 다시로드 할 수 없습니다.

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

나는 일반적인 용의자가 링크 된 패키지로 작업하지 않았기 때문에 최근 에이 질문에 왔습니다. 저와 같이 npm link많은 패키지로 구성된 프로젝트에서 효과적으로 작업하기 위해 개발 중 을 활용하는 경우 종속성에서 발생하는 변경 사항도 다시로드를 시작하는 것이 중요합니다.

node-mon 및 pm2를 시도한 후에도 node_modules 폴더를 추가로 감시하기위한 지침을 따르더라도 여전히 변경 사항을 선택하지 않았습니다. 여기에 답변에 몇 가지 사용자 정의 솔루션이 있지만 이와 같은 경우 별도의 패키지가 더 깨끗합니다. 나는 오늘 node-dev를 발견 했으며 옵션이나 구성없이 완벽하게 작동합니다.

읽어보기에서 :

감독자 또는 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 dev 서버가 사용됩니다. package.json에서 다음과 같은 스크립트를 추가 할 수 있습니다."hot": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --watch-poll",

파일이 변경 될 때마다 자동으로 재 컴파일이 시작됩니다

참고 URL : https://stackoverflow.com/questions/1972242/how-to-auto-reload-files-in-node-js



반응형