node main.js
Node.js로 main.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.json
의 dependencieis
가 아닌, 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, enterrs
[nodemon] watching path(s): .
[nodemon] watching extensions: js,mjs,json
[nodemon] startingnode main.js
server is running at 3000
이렇게 사용하기는 매우 불편해보인다.
$npm i -g nodemon
그래서 일반적으로 위와 같이 전역으로 설치한다.
$nodemon main.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enterrs
[nodemon] watching path(s): .
[nodemon] watching extensions: js,mjs,json
[nodemon] startingnode 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/bin
에 nodemon
명령어가 설치되는데, 이 경로가 환경 변수에 등록되어 있기 때문에 현재 디렉토리에 nodemon
이 없을 경우 환경 변수에 등록된 변수들을 쭉 탐색하다가 /opt/homebrew/bin
도 찾아볼 것이고, 이 디렉토리 내부에 nodemon
이라는 파일이 존재하면 해당 파일이 정상적으로 실행될 것이다.
/opt/homebrew/bin/nodemon main
을 직접 실행해도 정상적으로 작동하는 것을 확인할 수 있으며,
이는 nodemon main
을 사용하는 것과 같다.
물론 OS나 버전, 어떤 패키지 매니저의 종류와 사용 여부에 따라 npm
전역으로 설치된 명령어들의 위치가 전혀 달라질 수 있기 때문에 npm -g doctor
명령어를 통해 전역으로 설치된 명령어가 어디에 위치하는지 궁금하다면 경로를 직접 확인하도록 하자.
global bin folder in PATH
가 npm
에 의해 전역으로 설치된 명령어가 존재하는 디렉토리의 위치다.
주의할 점은, 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에 의해 자동으로 변경 사항이 반영될 것이다.