Node.js
Node.js는 V8 (자바스크립트 엔진) 위에서 동작하는 이벤트 처리 I/O 프레임워크이다. 웹 서버와 같이 확장성 있는 네트워크 프로그램 제작을 위해 고안되었다.
Node.js는 파이썬으로 만든 Twisted, 펄로 만든 펄 객체 환경, 루비로 만든 이벤트머신과 그 용도가 비슷하다. 대부분의 자바스크립트가 웹 브라우저에서 실행되는 것과는 달리, Node.js는 서버 측에서 실행된다. Node.js는 일부 CommonJS 명세를 구현하고 있으며, 쌍방향 테스트를 위해 REPL 환경을 포함하고 있다.
Categories
- Node.js:Libraries
- Node.js:Addons
- Node.js:HTTP: HTTP Module
- Node.js:Example:Startup
- Npm:Module - npm 모듈 만드는 방법 포함
- Web Programming
- JavaScript
- TypeScript
- package.json
- browserslist
- Javet - V8 과 Node.js를 Java에 임베딩
- TracePerf - Node.js용 성능 추적/실행 모니터링 도구
How to install
Ubuntu
Alternatively, for Node.js v4:
Alternatively, for Node.js v6:
Optional: install build tools
## To compile and install native addons from npm you may also need to install build tools:
sudo apt-get install -y build-essential
CentOS EPEL
Arch Linux
Bootstrap script
#!/usr/bin/env bash
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" || exit; pwd)
N_PREFIX="$ROOT_DIR/.node"
N_DIR="$ROOT_DIR/.n"
N_EXE="$N_DIR/n"
NODE_EXE="$N_PREFIX/bin/node"
NODE_VERSION=18.12.0
if [[ ! -d "$N_DIR" ]]; then
mkdir -vp "$N_DIR"
fi
if [[ ! -x "$N_EXE" ]]; then
curl -L "https://raw.githubusercontent.com/tj/n/master/bin/n" -o "$N_EXE"
chmod +x "$N_EXE"
fi
if [[ ! -x "$N_EXE" ]]; then
echo "Could not find executable n command on path '$N_EXE'"
exit 1
fi
if [[ ! -x "$NODE_EXE" ]]; then
echo "Could not find executable node command on path '$NODE_EXE'"
echo "Install node $NODE_VERSION ..."
N_PREFIX="$N_PREFIX" "$N_EXE" install "$NODE_VERSION"
CODE=$?
if [[ $CODE -ne 0 ]]; then
echo "Node $NODE_VERSION installation failed: $CODE"
exit $CODE
fi
echo "Install yarn ..."
N_PREFIX="$N_PREFIX" "$N_EXE" exec "$NODE_VERSION" npm install --global "yarn"
fi
# Read `.env` variables
if [[ -f "$ROOT_DIR/.env" ]]; then
while read line; do
if [[ $(echo "$line" | grep -E '^[ \t]*export[ \t]*[_a-zA-Z0-9]+=.*$') ]]; then
eval "$line"
else
eval "export $line"
fi
done < "$ROOT_DIR/.env"
fi
export PATH="$N_PREFIX/bin:$PATH"
N_PREFIX="$N_PREFIX" "$N_EXE" exec "$NODE_VERSION" yarn "$@"
Example
Node.js로 작성한 hello world HTTP 서버:
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(8000);
console.log('Server running at http://localhost:8000/');
다른 예제, 7000번 포트를 여는 간단한 TCP Echo 서버:
var net = require('net');
net.createServer(function (stream) {
stream.write('hello\r\n');
stream.on('end', function () {
stream.end('goodbye\r\n');
});
stream.pipe(stream);
}).listen(7000);
GET / POST Parameter In Node.js
var sys = require ('sys'),
url = require('url'),
http = require('http'),
qs = require('querystring');
http.createServer(function (req, res) {
if(req.method=='POST') {
var body='';
req.on('data', function (data) {
body +=data;
});
req.on('end',function(){
var POST = qs.parse(body);
console.log(POST);
});
} else if(req.method=='GET') {
var url_parts = url.parse(req.url,true);
console.log(url_parts.query);
}
}).listen(1337, "127.0.0.1");
시스템 명령어 전송방법:
var exec = require('child_process').exec;
var cmd = 'prince -v builds/pdf/book.html -o builds/pdf/book.pdf';
exec(cmd, function(error, stdout, stderr) {
// command output is in stdout
});
Obtain envronment variables
Executable path
실행 파일 경로를 확인하는 방법:
-
process.execPathshould be what you require. -
process.argv0is not alway pointed to node binary.
명령행으로 HTTP 접속 테스트
보기 편한 코드:
const http = require('http');
http.get('http://localhost:8080', res => {
if (res.statusCode === 200) {
process.exit(0);
} else {
console.error(`status error: ${res.statusCode}`);
process.exit(1);
}
});
bash 스크립트 한줄 코드:
node -e 'require("http").get("http://localhost:8080", res => res.statusCode === 200 ? process.exit(0) : process.exit(1));'
Filesystem
- node.js - File system(파일 시스템)
- Stackoverflow: Check synchronously if file/directory exists in Node.js
-
__filename - 현재 파일 경로 확인
-
__dirname - 현재 디렉터리 경로 확인 방법
File Logging
__defineGetter__ 사용하기
MDN에 따르면 __defineGetter__는 표준도 아니고 폐기된 API이지만 현재 Node.js에서 사용할 수 있다.(즉, 아직 V8이 지원한다.) 이 특이한 이름의 __defineGetter__는 객체의 프로퍼티를 함수에 바인딩해서 해당 프로퍼티가 조회될 때 바인딩된 함수가 호출되도록 하는데 stdout, stderr를 가로채는 방법을 검색하다 보면 이 방법이 많이 나온다.
fs = require('fs');
console.log('first log message');
console.error('first error message');
var oldStdout = process.stdout,
oldStderr = process.stderr,
newStdout = fs.createWriteStream('log.log', {flags: 'a'}),
newStderr = fs.createWriteStream('err.log', {flags: 'a'});
// stdout, stderr 가로챔
process.__defineGetter__('stdout', function() {
return newStdout;
});
process.__defineGetter__('stderr', function() {
return newStderr;
});
console.log('second log message');
console.error('second error message');
// stdout, stderr 복구
process.__defineGetter__('stdout', function() {
return oldStdout;
});
process.__defineGetter__('stderr', function() {
return oldStderr;
});
console.log('third log message');
console.error('third error message');
write 함수 오버라이드하기
__defineGetter__를 이용한 방법도 잘 동작하지만 표준이 아닌 __defineGetter__를 사용하는 부분이 약간 찝찝하다. stdout과 stderr 에는 실제 메시지를 출력하는 write 함수가 있는데 이 함수가 실제로 메시지를 출력하는 함수이므로 이 함수를 통째로 가로챌 수 있다.
var fs = require('fs');
console.log('first log message');
console.error('first error message');
var oldStdoutWrite = process.stdout.write,
oldStderrWrite = process.stderr.write;
// stdout, stderr 가로챔
process.stdout.write = function(str, encoding, fg) {
fs.appendFile('log.log', str, function(err) {});
}
process.stderr.write = function(str, encoding, fg) {
fs.appendFile('err.log', str, function(err) {});
}
console.log('second log message');
console.error('second error message');
// stdout, stderr 복구
process.stdout.write = oldStdoutWrite;
process.stderr.write = oldStderrWrite;
console.log('third log message');
console.error('third error message');
TDD
- [추천] Node.js 로 TDD 를 도전해보자 1
- [추천] Node.js Express 테스트 하기
Server And Client App Test
When testing with Node.js, you’ll typically use the following:
Debugging
- Node:Docker: Node와 Docker의 디버깅 방법.
Corepack
Node.js 기술운영위원회(TSC)가 Corepack을 더 이상 Node.js에 포함해 배포하지 않기로 공식 투표로 결정함. Node.js 25버전부터 적용되며, Node.js 24 이하에서는 실험적 기능으로 계속 제공됨.
Corepack의 역할과 한계
- Corepack은 Node.js 16.9.0에서 도입된 실험적 도구로, Yarn, pnpm 같은 패키지 매니저를 별도 설치 없이 사용할 수 있게 해줌
- 프로젝트에서 특정 패키지 매니저 버전을 강제할 수 있도록 도와주는 역할을 수행함
- 하지만 사용자 인식 부족과 목적에 대한 오해로 인해 널리 사용되지 않음
- 런타임과 독립적으로 동작해야 할 패키지 매니저를 Node.js에 포함시키는 것에 대한 회의론 존재
단점
- Continuation-passing style (CPS): 프로그램이 다음 할 일을 콜백으로 계속 넘기는...
- bluebird: 콜백 지옥 벗어나기...
ENOSPC: System limit for number of file watchers reached
- Error: ENOSPC: System limit for number of file watchers reached,
- 브라우저싱크 Error: ENOSPC: System limit for number of file watchers reached 에러 대처
[Browsersync] Proxying: http://localhost
[Browsersync] Access URLs:
-------------------------------------
Local: http://localhost:3000
External: http://192.168.1.16:3000
-------------------------------------
UI: http://localhost:3001
UI External: http://localhost:3001
-------------------------------------
[Browsersync] Watching files...
node:internal/errors:464
ErrorCaptureStackTrace(err);
^
Error: ENOSPC: System limit for number of file watchers reached, watch '/my-project-folder/vendor/myclabs/deep-copy/.github'
at FSWatcher.<computed> (node:internal/fs/watchers:244:19)
at Object.watch (node:fs:2247:34)
at createFsWatchInstance (/my-project-folder/node_modules/chokidar/lib/nodefs-handler.js:119:15)
at setFsWatchListener (/my-project-folder/node_modules/chokidar/lib/nodefs-handler.js:166:15)
at NodeFsHandler._watchWithNodeFs (/my-project-folder/node_modules/chokidar/lib/nodefs-handler.js:331:14)
at NodeFsHandler._handleDir (/my-project-folder/node_modules/chokidar/lib/nodefs-handler.js:559:19)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async NodeFsHandler._addToNodeFs (/my-project-folder/node_modules/chokidar/lib/nodefs-handler.js:609:16)
Emitted 'error' event on FSWatcher instance at:
at FSWatcher._handleError (/my-project-folder/node_modules/chokidar/index.js:647:10)
at NodeFsHandler._addToNodeFs (/my-project-folder/node_modules/chokidar/lib/nodefs-handler.js:637:18)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
errno: -28,
syscall: 'watch',
code: 'ENOSPC',
path: '/my-project-folder/vendor/myclabs/deep-copy/.github',
filename: '/my-project-folder/vendor/myclabs/deep-copy/.github'
}
... 와 비슷한 에러를 내뱉는 경우를 볼 수 있다.
원인은 시스템의 파일 와쳐(Watcher)가 limit 에 달해서 그렇다고 한다.
단순한 해결책
참고로 max_user_watches를 늘리는 게 능사는 아니다. 감시 파일 개수를 줄일 수도 있다.
감시 대상을 제한
node_modules같은 디렉토리는 감시 대상에서 제거하라.
mix.browserSync({
proxy: 'ws-dev.localhost',
files: [
'wp-content/themes/ws/**/*.php',
'wp-content/themes/ws/build/*.js',
'wp-content/themes/ws/js/*.js',
'wp-content/themes/ws/build/*.css',
]
});
메모리 사용량, 프로세서 확인
find /proc/*/fd -lname anon_inode:inotify | cut -d/ -f3 | xargs -I '{}' -- ps --no-headers -o '%p %U %c' -p '{}' | uniq -c | sort -nr
Troubleshooting
ENOSPC: System limit for number of file watchers reached
#ENOSPC: System limit for number of file watchers reached 항목 참조.
caniuse-lite is outdated
경고 메시지 출력:
나온 대로 그냥 돌려주자:
See also
- Event driven architecture
- left-pad (NPM, left-pad 사건)
- deno
- Bun - JavaScriptCore 기반의 빠른 JavaScript 런타임/트랜스파일러/NPM 클라이언트
- Bare - 빠르고 경량화된 모듈형 JavaScript 런타임
- php-node - Node.js내에서 PHP HTTP 요청을 처리하는 핸들러
- qnm - node_modules 폴더를 들여다 보는 CLI 도구
Favorite site
- Node.js website
- Wikipedia (en) Node.js에 대한 설명
- Using Eclipse as Node Applications Debugger
- Node.js 이클립스 개발환경 구축
- Node.js Vim Plugins
- Nodeclipse & Enide
Article
- Node.js 타입스크립트를 기본으로 지원하기 시작 | GeekNews - Node.js 23부터 TypeScript 지원
Tutorial
- Pyrasis.com Node.js 기본 사용법
- The Node Beginner Book 2
- Felix's node.js Beginners Guide 3
- [추천] One page navigation guide for node.js study
- [추천] Node v0.2.6 한글번역 4
- nodeJS 활용 채팅방 만들기
- node.js 따라배우기 01: Webapp을 만들어 봅시다!
- [추천] 빠르게 훝어보는 node.js #1 - node.js 소개 및 내부구조 5
- The Node Beginner Book
Guide
- node.js개발 환경 만들기 (Eclipse IDE)
- [추천] node.js는 무엇인가? #2 : Hello World 실행하기
- Node.js http module
- [추천] Node.js를 이용한 단일언어 기반 웹 애플리케이션 개발
- Node.js File system(파일 시스템) 6
- NODE.JS AND SQLITE
- Beer Locker: Building a RESTful API With Node - OAuth2 Server
- [추천] Database integration
- How do I get code completion for Node.js in Eclipse?
- Node.js의 이벤트
- Node.js 기본 - 전역객체 (console, process, exports)
- [추천] 약 18가지의 Node.js Runtime 에서 지켜야할 필수 조건들
- [추천] MEAN Stack: 무엇을 쓸것인가? 목차에 대하여
- Stackoverflow: In Node.js, how do I "include" functions from my other files?
- node with threads
- 노드JS로 P2P 클라이언트 구축하기
Packages
Deploy
- Auto deploy node.js repos - git hooks
- Push to deploy a nodejs application using git hooks
- Node.js 웹 앱의 도커라이징 7
Stack
- [추천] NAVER D2 - 빠르게 서비스를 개발할 수 있는 Node.js 8 (여러 가지 Node.js 관련 기술 스택 소개)
References
-
Seokjun.kim_-_node-js-tdd.pdf ↩
-
The_Node_Beginner_Book_(Korean_version)_A_comprehensive_Node.pdf ↩
-
Felix's_node.js_Beginners_Guide.pdf ↩
-
Node_v0.2.6-ko.pdf ↩
-
Bcho.tistory.com_-node.js-_Introduction_and_internal_structure.pdf ↩
-
Node.js_File_System.pdf ↩
-
Dockerizing_a_NodeJS_web_app_-_Node.pdf ↩
-
Naver_D2_-Nodejs-_Quickly_develop_services.pdf ↩