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


444

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 전역에 대한 실마리는 없습니다.


4
각 요청 Object.keys(require.cache).forEach(function(key) { delete require.cache[key]; });
Tower

답변:


562

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

node.js 응용 프로그램의 변경 사항을 모니터링하고 서버를 자동으로 다시 시작하여 개발에 적합

사용하려면 nodemon:

$ npm install nodemon -g
$ nodemon app.js

2
Nitrous.io 에서 사용하려면 - $ nodemon -L yourfile.js( coderwall.com/p/aqxl_q에 대한 전체 설명 )
drzaus

3
그러나이 경우 서버 프로세스도 다시 시작됩니다.
Filipe

@Filipe, 네 말이 맞아. 다시 로그인하도록 리디렉션됩니다. 특정 수정 된 모듈 만로드했으면합니다.
ar2015

8
automatically restart the server - perfect for development너무 과장된 것입니다. 서버를 다시로드하면 백엔드 서비스에 로그인하는 것이 시간이 오래 걸릴 수 있습니다. "개발에 대한 완벽한"은 소스 코드를 변경할 때 안드로이드 스튜디오가하는 일과의 상태를 잃지 않고 프로세스가 메모리에서 실행되는 동안 핫 리로드 클래스와 같은 것입니다.
nurettin

2
npm install [--save-dev | -D] nodemon설치를 프로젝트 범위로 제한하는 데 사용 합니다.
테마 필드

312

노드 감독자는 굉장하다

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

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

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


3
npm install -g 수퍼바이저 전세계에 설치해야합니다.
Kamal Reddy

OSx

2
Windows에서 다음과 같이 실행해야합니다."C:\Program Files\nodejs\node.exe" C:\Users\Mark\AppData\Roaming\npm\node_modules\supervisor\lib\cli-wrapper.js app.js
mpen

1
app root에서 -g 또는 sudo없이 : npm install supervisor, node node_modules/supervisor/lib/cli-wrapper.js app.js(노드의 비 루트 설치가 있습니다)
h-kippo

1
@Mark 이것은 노드가 없음을 의미합니다PATH
Blaise

88

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

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

7
앱을 다시 시작하지 않고 외부 라이브러리를 다시로드하려는 경우에 좋습니다. 필자의 경우 IRC 봇입니다.
Michelle Tilley

이것은 우수하다! 너무 간단하고 잘 작동합니다. 요청이 올 때마다 상태를 유지하지 않는 많은 파일을 캐시 해제합니다.
vaughan

16
delete require.cache[require.resolve('./mymodule.js')]; 실제 경로로 거래 해결
Eduardo

이것이 "나쁜 습관"또는 "개발 만"으로하는 것이 안전합니까?
jocull

2
@jocull 클래스와 함수 또는 모든 내보내기를 다시 생성 할 수 있기 때문에 안전하다고 생각하지 않습니다.===
Kroltan

20

누군가 여전히이 질문에 와서 표준 모듈 만 사용하여 해결하려는 경우 간단한 예를 들었습니다.

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 에서 구현됩니다.


1
이것은 훌륭하고 간단한 해결책입니다. 방금 중재자가 지시 할 때 git에서 자체적으로 업데이트 해야하는 봇에 사용했습니다. 문제는 앱 안에 들어가면 다시 시작할 수 없다는 것입니다. 그러나 귀하의 방법을 사용하여 봇 인스턴스를 생성하고 도트 파일을 볼 수 있습니다. 그런 다음 봇은 자체적으로 업데이트되고 도트 파일을 건 드리며 실행기에 의해 자동으로 다시 시작됩니다. 대박!
Fred

내가 듣고 기뻐 @Fred이 : 나는 곧 내가 어떻게 그 기능 확장하는 몇 가지 더 많은 아이디어를 가지고, 생각, 모듈에서이 솔루션을 구현합니다
micnic

파일 watch이 필요하지 않은 경우 fs다른 신호를 수신하여를 다시로드하지 않고도 재로드를 수행 할 수 있습니다 .
Vladimir Vukanac

18

nodemon 은 Google 검색에서 처음 나타 났으며 트릭을 수행하는 것 같습니다.

npm install nodemon -g
cd whatever_dir_holds_my_app
nodemon app.js

8

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

npm install supervisor

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


2
충돌이 발생하면 서버를 다시 시작하는 것에 대한 자세한 내용입니다. 감시 파일이 변경되면 node-supervisor도 전체 프로세스를 다시 시작합니다. 엄격한 의미에서 핫 리로드되지 않습니다.
nalply

실제로 핫 로딩은 아니지만이 도구는 개발하는 동안 코드를 자동으로 다시로드하기를 원할 때마다 유용합니다. 따라서 모든 변경 후에 명령 줄에서 노드를 다시 시작할 필요가 없습니다.
Derek Dahmer

7

편집 : 내 대답은 더 이상 사용되지 않습니다. 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이지만 지금 노력하고 있습니다.


7

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를 참조하십시오.


최신 버전의 nodemon (최소 1.19.0)에서는 글 로빙이 지원되지 않습니다. 대신 nodemon --watch server --inspect ./server/server.js를 사용하십시오.
Alex

귀하의 정보에 감사드립니다. 답변을 업데이트했습니다.
Ninh Pham

5

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


1
+1 예. 나는 토론에 참여했다. 내 솔루션이 너무 간단하다는 것을 인정했습니다. 핫 모듈 자체에 추가 모듈이 필요하지 않은 경우에만 작동합니다. 펠릭스의 솔루션은 더 잘 생각되지만 auto- reload가 실제로 핵심에 속 하는지 논쟁 중 입니다.
nalply

5

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

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

forever -w start server.js

이상하게도 -w 플래그를 사용하면 express.js 앱에서 CSS를 사용하지 않습니다.
Costa

5

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

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

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

node-dev app.js


3

다음 은 노드의 핫 리로드에 대한 블로그 게시물입니다. 핫 리로드를 활성화하기 위해 노드 설치를 교체하는 데 사용할 수 있는 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를 새 코드로 인식하고 바꿉니다. 기존 요청은 기존 코드를 계속 사용하지만 새로 들어오는 요청은 새 코드를 사용합니다. 서버를 종료하지 않고 요청을 수신 거부하거나 요청을 조기에 종료하거나 지능형로드 밸런서에 의존하지 않아도됩니다.


이 솔루션의 유일한 점은 이전 버전의 Node의 포크이므로 사용하기 전에 최신 버전으로 조정하고 병합해야합니다 (이전 버전의 Node를 사용하는 것이 마음에 들지 않는 한).
Chetan

3

모듈을 원하는대로로드 / 언로드 할 수있는 "작은"작은 노드를 만들기 위해 노력하고 있습니다 (즉, 전체 앱을 종료하지 않고 응용 프로그램의 일부를 다시 시작할 수 있음). (매우 어리석은) 종속성 관리를 통합하여 모듈을 중지하려는 경우 해당 모듈에 의존하는 모든 모듈도 중지됩니다.

지금까지는 좋지만 모듈을 다시로드하는 방법에 대한 문제가 발생했습니다. 분명히 "필수"캐시에서 모듈을 제거하고 작업을 완료했을 수 있습니다. 노드 소스 코드를 직접 바꾸고 싶지는 않았기 때문에 스택 추적에서 "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 , 몇 주 후에 거기에 가면 내가 말하는 것을 볼 수 있습니다)


.. 물론 그렇게 간단하지 않습니다. 호출 스택에 필요한 호출 있는 경우에만 작동합니다 . 음, 해킹 위에 쉽게 해킹하십시오 : 임시 스크립트로 해당 내용을 작성하고 런타임에 필요합니다. 그것을했다, 그것은 작동한다. 그리고 그것은 심지어 캐시에서 스스로를 청소한다
cheng81

그리고 실제로 더 쉬웠다 : delete (require.cache [moduleFullpathAndExt])
cheng81

Node.js 모듈은 실제로 모듈 캡슐화가 수행되는 방식 인 익명 함수로 래핑됩니다. 각 모듈은 실제로 다음과 같습니다 function (module, require) { /* your code */ }. 이것을 고려할 arguments[1]때을 가리 킵니다 require. while 루프는 모듈의 다른 함수 내에서 이것을 호출하는 상황에 있습니다 (단순히 함수 계층 구조를 올라가고 각각에 전달 된 인수 값을 확인합니다).
JK

3

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

nodemon npm start

또는 디버그 모드 사용

DEBUG=yourapp:* nodemon npm start

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

nodemon your-app-file.js

이 도움을 바랍니다.


1

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

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

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

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

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

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


1

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

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


1

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"으로 응답하십시오.


1

내 앱 구조 :

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

그러나이 방법은 효과가 없지만 npmjs.com/package/reload (Express 앱의 경우) 에서 나온 것입니다.
맥시 버크만

0

이것을 사용하십시오 :

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

그리고 구성은 자동으로 다시로드됩니다 :)


Node의 일부가 아닌 프레임 워크에 의존하지 않는 버전이 있습니까?
Adrian

0

loaddir은 재귀 적으로 디렉토리를 빠르게로드하는 솔루션입니다.

돌아올 수있다

{ 'path/to/file': 'fileContents...' } 또는 { path: { to: { file: 'fileContents'} } }

그것은이 callback파일이 변경 될 때 호출 될 것이다.

파일 watch작성이 완료되기 전에 파일이 충분히 커지는 상황을 처리합니다 .

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

전투 테스트를 도와주세요!

https://github.com/danschumann/loaddir


0

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

설치

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

0

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

찬성 :

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

단점 :

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

0

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

0

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

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

읽어보기에서 :

감독자 또는 nodemon과 같은 도구와 달리 파일을 감시 할 파일 시스템을 검사하지 않습니다. 대신 Node의 require () 함수에 연결하여 실제로 필요한 파일 만 감시합니다.


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

0

browser-refresh로 할 수 있습니다 . 노드 앱이 자동으로 다시 시작되고 브라우저의 결과 페이지도 자동으로 새로 고쳐집니다. 단점은 생성 된 페이지에 js 스 니펫을 넣어야한다는 것입니다. 다음 은 작업 예의 저장소 입니다.

const http = require('http');
const hostname = 'localhost';
const port = 3000;

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/html; charset=UTF-8');
    res.write('Simple refresh!');
    res.write(`<script src=${process.env.BROWSER_REFRESH_URL}></script>`);
    res.end();
})

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);

    if (process.send) {
        process.send({ event: 'online', url: `http://${hostname}:${port}/` })
    }

});

0

나는 pm2를 시도했다 : 설치도 쉽고 사용하기 쉽다. 결과는 만족 스럽습니다. 그러나 원하는 pm2 에디션을 관리해야합니다. pm2 런타임은 무료 버전이지만 pm2 plus 및 pm2 enterprise는 무료가 아닙니다.

에 관해서는 Strongloop , 내 설치에 실패하거나 내가 그것을 사용하지 수 있도록 완료되지 않았습니다.


-1

요즘에는 핫 옵션이있는 WebPack dev 서버가 사용됩니다. package.json에서 다음과 같은 스크립트를 추가 할 수 있습니다."hot": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --watch-poll",

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


2
이 대답은 질문으로 잘못되었습니다. Webpack은 프론트 엔드 응용 프로그램 용이며 dev 서버는 자체 웹 서버입니다. 이 질문은 Node에서 구현 된 서버 응용 프로그램에 관한 것입니다. 웹 서버가 필요하지 않습니다. 벌써 하나입니다.
DanielKhan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.