[Node.js] nodemon 사용법

zxcev·2023년 1월 19일
0

Node.js

목록 보기
11/17
post-thumbnail

node main.js

Node.jsmain.js JS 파일을 실행하는 명령어다.
Java나 C처럼 여러 옵션을 넣어 컴파일한 뒤 실행하는 번거로운 과정은 없지만, 코드가 변경될 때마다 재실행 해야 한다는 단점이 있다.

const express = require('express');

const app = express();

app.get('/', (req, res) => {
    res.status(200).send('OK');
});

app.listen(3000, () => {
    console.log('server is running at 3000');
});

GET /로 접속하면 'OK'라는 응답을 받을 수 있는 코드다.
node main.js로 코드를 실행한 뒤, 'NOT OK'로 응답을 변경하고 싶다면, 코드를 수정하고 다시 한 번 node main.js를 재실행 할 필요가 있다.

nodemon을 사용하면 코드에 변경 사항이 생길 때마다 자동으로 이를 감지하여 코드를 재실행 해준다.

역시 외부 모듈이기 때문에 설치가 필요하다.

$npm i -D nodemon

-D 옵션을 주면 package.jsondependencieis가 아닌, devDependencies에 모듈이 추가된다.
말 그대로 개발용 모듈만 모아 놓은 것으로, 개발이 완료되면 코드를 실시간으로 변경하고 재실행 할 필요가 없기 때문에 그 때는 제거될 것이라는 의미다.

$nodemon main.js
bash: nodemon: command not found

대충 사용해보기 위해 터미널에 위와 같이 입력했더니 명령어를 찾을 수 없다고 나온다.

nodemon이라는 명령어의 path가 환경 변수로 등록되지 않았기 때문에, 아래와 같이 직접 nodemon이 설치된 path를 지정해야 정상적으로 동작한다.

$./node_modules/nodemon/bin/nodemon.js main.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enter rs
[nodemon] watching path(s): .
[nodemon] watching extensions: js,mjs,json
[nodemon] starting node main.js
server is running at 3000

이렇게 사용하기는 매우 불편해보인다.

$npm i -g nodemon

그래서 일반적으로 위와 같이 전역으로 설치한다.

$nodemon main.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enter rs
[nodemon] watching path(s): .
[nodemon] watching extensions: js,mjs,json
[nodemon] starting node main.js
server is running at 3000

이제 정상적으로 동작하게 되었다.


원리가 궁금한 사람들을 위해 추가적으로 설명하자면, OS에는 환경 변수라는 것이 존재한다.
macOS에서는 echo $PATH 명령어로 환경 변수 목록을 출력할 수 있는데, :로 각 path가 구분된다고 보면 되며, 여기에 나타난 경로들은 현재 사용자가 어떤 path에 있더라도 접근할 수 있다.

예를 들어 /Documents/workspace 경로에서 nodemon main.js 명령어를 사용했는데, /Documents/workspace/nodemon이라는 파일이 존재하지 않는다면 실행이 불가능할 것이다.

그럼 환경변수에 등록된 경로에 nodemon이라는 파일이 존재하는지 탐색할 것이다.
내 컴퓨터의 경우 npm i -g nodemon으로 설치하면 /opt/homebrew/binnodemon 명령어가 설치되는데, 이 경로가 환경 변수에 등록되어 있기 때문에 현재 디렉토리에 nodemon이 없을 경우 환경 변수에 등록된 변수들을 쭉 탐색하다가 /opt/homebrew/bin도 찾아볼 것이고, 이 디렉토리 내부에 nodemon이라는 파일이 존재하면 해당 파일이 정상적으로 실행될 것이다.

/opt/homebrew/bin/nodemon main을 직접 실행해도 정상적으로 작동하는 것을 확인할 수 있으며,
이는 nodemon main을 사용하는 것과 같다.

물론 OS나 버전, 어떤 패키지 매니저의 종류와 사용 여부에 따라 npm 전역으로 설치된 명령어들의 위치가 전혀 달라질 수 있기 때문에 npm -g doctor 명령어를 통해 전역으로 설치된 명령어가 어디에 위치하는지 궁금하다면 경로를 직접 확인하도록 하자.

global bin folder in PATHnpm에 의해 전역으로 설치된 명령어가 존재하는 디렉토리의 위치다.

주의할 점은, npm으로 설치된 전역 모듈과 전역 명령어의 위치가 다르다는 것이다.
nodemon을 전역으로 설치했을 때, /opt/homebrew/lib/node_modules에 모듈이 설치되고, 명령어는 /opt/homebrew/bin에 따로 설치된다.

근데 /opt/homebrew/bin에 설치된 명령어는 그냥 /opt/homebrew/lib/node_modules/bin/nodemon.js의 42bytes 짜리 alias(윈도우에서는 바로가기 파일) 파일일 뿐이라 본체는 /opt/homebrew/lib/node_modules/bin/nodemon.js가 맞다.

단지 /opt/homebrew/bin 경로가 환경 변수로 등록되어 전역으로 실행 가능한 명령어들을 모아 놓는 곳이기 때문에 이런 구조를 띄는 것으로 보인다.

결국 /opt/homebrew/bin/nodemon으로 접근하면 연결된 원본 파일인 /opt/homebrew/lib/node_modules/bin/nodemon.js가 실행되는 것이다.

#!/usr/bin/env node

const cli = require('../lib/cli');
const nodemon = require('../lib/');
const options = cli.parse(process.argv);

nodemon(options);

const fs = require('fs');

// checks for available update and returns an instance
const pkg = JSON.parse(fs.readFileSync(__dirname + '/../package.json'));

if (pkg.version.indexOf('0.0.0') !== 0 && options.noUpdateNotifier !== true) {
  require('simple-update-notifier')({ pkg });
}

위의 짧은 코드가 /opt/homebrew/lib/node_modules/bin/nodemon.js에 위치한 원본 명령어 파일이다.

길었지만 npm의 전역 모듈과 명령어가 설치되는 위치와 환경 변수에 대해서 좀 더 알아보는 유익한 시간을 가졌다.

게다가 nodemon이라는 유용한 툴을 알게 되었다.
이제 nodemon main.js를 통해 코드를 실행하면, 수정할 때마다 nodemon에 의해 자동으로 변경 사항이 반영될 것이다.

0개의 댓글