모듈 : 특정한 기능을 하는 함수나 변수들의 집함
파일하나 모듈하나로 설정하는게 관리에 용이
module.exports 객체에 저장하면 다른 파일에서 require()를 통해 임포트 할 수 있음
모듈화를 통해 독립적인 실행파일을 작성하고, 재사용 높은 프로그래밍이 가능해진다.
// 1. var.jsconstodd='홀수 입니다';consteven='짝수 입니다';module.exports= { odd, even}; // 변수내보내기// 2. func.jsconst {odd,even} =require('./3.노드기능알아보기'); // 다른 파일에서 재사용중functioncheckOdddOrEven(num) {return num %2? odd : even;}module.exports= checkOdddOrEven; // 함수 내보내기// 3. index.jsconst {odd,even} =require('./3.노드기능알아보기'); // 다른 파일에서 재사용중constcheckNumber=require('./3.노드기능알아보기2');functioncheckStringOddEven(str) {returnstr.length%2? odd : even;}console.log(checkNumber(10));console.log(checkStringOddEven('hello'));
3.4 노드 내장 객체 알아보기
Dom의 window location 같은 내장 객체처럼, Node에도 내장객체가 존재.
내장객체란 이미 만들어져 있는 객체로 그냥 전역적으로 사용이 가능한 객체들을 말함
책에서는 자주 사용되는 객체만 다룸. 궁금한건 문서 참조
global 전역객체로.. 데이터를 공유하여 사용할 수도 있으나 권장 x, 변경 되는 정보를 나중에 찾는데 어려움 발생..
실행 순서의차이. 파일시스템 접근, 네트워킹 같은 I/Odml 특수한 경우, setImmediate 우선권 높음. 그러나 항상 먼저실행되는건 아님.. 점유에 따라 달라지는것 같음.
헷갈리지 않도록 setTimeout(callback, 0) 사용하지 않는 것을 권장
filename, dirname
해당 내용은 path 모듈에서 자세히 다룸
__filename : 현재 파일의 절대 경로
__dirname : 현재 파일의 디렉토리 절대 경로
module, exports module.exports === exports -> true 즉 같은 객체.
exports로 사용해도 되나 통일성을 위해 그냥 module. 을 붙여 사용하자
exports를 재정의 할 경우 모듈과 연결이 끊어지므로 주의 필요
process 현재 실행 중인 node 프로세스의 정보를 알 수 있음
console.log(process.version); // 설치된 노드 버전console.log(process.arch); // 프로세서 아키텍처 정보, ex) x64, ia32 ...console.log(process.platform); // os 플랫폼, linux, darwin, ...console.log(process.pid); // 현재 프로세스 아이디console.log(process.uptime()); // 프로세스가 시작된 후 흐른 시간console.log(process.execPath); // 노드의 경로console.log(process.cwd()); // 현재 프로세스가 실행되는 위치, console.log(process.cpuUsage()); // cpu 사용량
process.env
나중에 dotenv 모듈 사용
서버의 중요한 키 정보를 저장함
process.nextTick(callback)
이벤트루프가 다른 콜백함수보다 nextTick 함수의 우선순위를 높게 잡아 우선 처리
setImmediate(() => {console.log('immediate');});process.nextTick(() => {console.log('nextTick');});setTimeout(() => {console.log('timeout');},0);Promise.resolve().then(() =>console.log('promise'));// 출력 예상 // 1. nextTick 2. promise 3. timeout 4. immediate
process.nextTick, Promise를 마이크로태스트라고 따로 구분지음 -> 쌓이는 큐 영역이 다름
마이크로태스크 > 태스트 이므로, 남발하는 경우 이벤트루프에서 다른 콜백함수를 실행하지 못하는 경우가 발생할 수 있음
process.exit(코드)
정상종료 : 0, 비정상종료 : 1 / 프로그램을 수동적으로 강제 종료 시킴
3.5 노드 내장 모듈 사용하기
노드에서 제공하는 모듈, 많은 것이 있지만 주로사용하는 것 위주로
OS 운영체제 정보를 가져올 수 있음. 웹 브라우저에서는 가져올 수 없지만..
constos=require('os');console.log('OS 정보 ------------------');console.log(os.arch());console.log(os.platform());console.log(os.type());console.log(os.uptime());console.log(os.hostname());console.log(os.release());console.log('경로 ------------------');console.log(os.homedir());console.log(os.tmpdir());console.log('cpu info ------------------');console.log(os.cpus());console.log(os.cpus().length);console.log('memory info ------------------');console.log(os.freemem());console.log(os.totalmem());
node의 경우 싱글스레드이므로 코어수가 몇개든 간에 하나밖에 사용을 할 수 밖에 없다. 그러나 cluster모듈을 사용하면 코어 개수에 맞춰 프로세스를 늘릴 수 있다.
path 파일, 폴더경로 관련한 모듈. Windows타입과 POSIX(유닉스 기반 OS)로 나뉨
constpath=require('path');conststring= __filename;console.log(path.sep); // 경로 구분자console.log(path.delimiter); // 환경변수 구분자console.log('-------------------------------');console.log(path.dirname(string)); // 파일이 위치한 폴더 경로console.log(path.extname(string)); // 파일의 확장자console.log(path.basename(string)); // 파일명 + 확장자 console.log(path.basename(string,path.extname(string))); // 파일명만console.log('-------------------------------');console.log(path.parse(string)); // 파일경로를 -> root, dir, base, ext, name 으로 분리해줌console.log(path.format({ // path.parse 한 객체를 파일 경로로 합침 dir:'/Users/users/zerocho', name:'path', ext:'.js'})); // /Users/users/zerocho/path.jsconsole.log(path.normalize('/Users//users\\\\zerocho\\\path.js')); // 정상경로로 변경. ..? 잘안되는거같은데.. (/Users/users\\zerocho\path.js)console.log('-------------------------------');console.log(path.isAbsolute("/Users")); // 절대 경로 확인console.log(path.isAbsolute("./home"));console.log('-------------------------------');console.log(path.relative('/Users/users/zerocho/path.js','/Users')); // 첫번째 경로 -> 두번째 경로로 가는 방법 (../../..)console.log(path.join(__dirname,"..","..","/users",".","/zerocho")); // 하나의 경로로 합침console.log(path.resolve(__dirname,"..","/users",".","/zerocho")); // join과 비슷하나 차이는 / 만나면 절대 경로로 인식 -> 앞의 경로를 무시하고 path.join은 상대경로로 처리
노드의 경우 싱글스레드이기 때문에 에러가나면 서버가 그대로 죽는다.
멀티스레드 환경인 경우 스레드가 하나 죽더라도, 서버가 죽지는 않기 때문에, 노드의 경우 예외처리에 각별히 신경을 써야함
에러가 발생 할 것 같은 부분에try~catch문을 사용하여 예외처리를 하면 서버가 멈추지 않는다!throw를 하는 경우 반드시 try~catch로 잡아줘야 한다
setInterval(() => {console.log('시작');try {thrownewError('서버 고장!'); } catch (e) {console.log(e); }},1000);/*시작Error: 서버 고장! at Timeout.setInterval [as _onTimeout] (/Users/myungsubso/Desktop/DEV/WebStorm/node_test/routes/3장.노드알아보기/3.8예외처리.js:4:11) at ontimeout (timers.js:436:11) at tryOnTimeout (timers.js:300:5) at listOnTimeout (timers.js:263:5) at Timer.processTimers (timers.js:223:10)시작Error: 서버 고장! at Timeout.setInterval [as _onTimeout] (/Users/myungsubso/Desktop/DEV/WebStorm/node_test/routes/3장.노드알아보기/3.8예외처리.js:4:11) at ontimeout (timers.js:436:11) at tryOnTimeout (timers.js:300:5) at listOnTimeout (timers.js:263:5) at Timer.processTimers (timers.js:223:10)...*/
process.on('uncaughtException', error => {console.error('예기치 못한 에러', error);});setInterval(() => {thrownewError('서버 고장');},1000);setInterval(() => {console.log('실행됩니다');},2000);/*예기치 못한 에러 Error: 서버 고장 at Timeout.setInterval [as _onTimeout] (/Users/myungsubso/Desktop/DEV/WebStorm/node_test/routes/3장.노드알아보기/3.8예외처리.js:26:9) at ontimeout (timers.js:436:11) at tryOnTimeout (timers.js:300:5) at listOnTimeout (timers.js:263:5) at Timer.processTimers (timers.js:223:10)실행됩니다실행됩니다실행됩니다실행됩니다실행됩니다*/
uncaughtException 는 최후의 보류 수단으로.. 복구작업을 넣어둬도 완벽히 복구된다는 보장이 없다. 서버 운영은 에러와 싸움이다...