1. Console
- 콘솔 모듈은 웹 브라우저에서 제공했던 자바스크립트 console과 매우 유사하고, 일반적으로 디버깅을 위해 사용한다.
Console 클래스와 전역 객체로 사용할 수 있다.
1.1 Console 클래스
- Console 클래스를 생성하고 stdout.log 파일과 stderr.log 파일로 로그를 기록하는 예제
먼저 stdout.log 파일과 stderr.log 파일을 생성.
- console_class.js 파일을 생성한 후 코드 작성
1.2 전역 객체 console
- console 모듈은 전역 객체로 등록되기 때문에 require('conosle') 없이 바로 사용할 수 있다.
- console_global.js 파일을 생성한 후 코드 작성
* console.log(내용,... agrs): 일반적인 로그를 콘솔에 출력한다.
* console.error(내용, ...agrs): 에러를 콘솔에 출력한다.
* console.table(테이블형 데이터): 배열/오브젝터를 테이블 형태로 콘솔에 출력한다.
* console.time(레이블)/console.timeEnd(레이블): console.timeEnd에 전달한 인수값이 일치하는 코드 사이의 실행 시간을 측정해서
출력한다. 기본값은 'default'이다.
* console.dir(오브젝트, 옵션): 객체를 콘솔에 출력할 때 사용한다.
2 . Timers
- 타이머 모듈의 모든 함수는 전역 함수이기 때문에 require('timers') 없이 사용할 수 있다.
Node.js 에서 타이머 함수는 웹 브라우저의 타이머 API와 매우 유사하다.
- timer.js 파일 생성하고 코드 작성
* setTimeout(콜백 함수, 밀리초) : 설정한 밀리초(1초 = 1000미리초) 이후에 지정된 콜백 함수가 실행.
* setInterval(콜백 함수, 밀리초) : 설정한 밀리초마다 지정된 콜백 함수가 실행.
* setImmediate(콜백 함수) : 현재 이벤트 루프 주기 끝에 코드를 실행.
3. Process
- Process 객체는 현재 실행되고 있는 Node.js 프로세스에 대한 정보와 제어를 제공.
3.1 Process events
- 프로세스 객체는 EventEmitter 인스턴스로 다음과 같은 이벤트가 발생할 때마다 리스너로 등록할 수 있다.
- beforeExit: Node.js가 이벤트 루프를 비우고 예약할 추가 작업이 없을 때 발생되는 이벤트.
beforeExit 이벤트에 등록된 리스너가 비동기식 호출을 하여 Node.js 프로세스를 계속할 수 있다. - exit: process.exit()를 호출하거나 Node.js 이벤트 루프가 더 이상 수행할 추가 작업이 없을 때 발생.
- disconnect: Node.js 프로세스가 IPC채널(클러스터로 자식 프로세스를 생성했을 때)로 생성된 경우 채널이 닫힐 때 이벤트 발생.
- message: Node.js 프로세스가 IPC 채널로 생성된 경우 childprocess.send()를 사용해서 상위 프로세스가 보낸 메시지를
하위 프로세스에서 수신할 때마다 발생.
이외에도 multipleResolve, rejectHandled, uncaughtException, uncaughtExceceptionMonitor, unhandledRejection,
wanring 등의 이벤트가 있다.
3.2 process.nextTick
- Node.js의 이벤트 루프는 다른 콜백 함수보다 nextTick에 인수로 전달한 콜백 함수를 우선적으로 처리한다.
nextTick을 통해 추가한 콜백 함수는 'next tick queue'에 추가된다.
3.3 process.exit()
- process.exit() 함수를 호출하면 실행 중인 Node.js 프로세스를 종료한다. 만약 서버를 구동 중이라면, process.exit() 함수를
호출하는 순간 서버가 멈추게 된다. 그러므로 조심히 사용해야 한다.
- 상태 코드로 0과 1을 줄 수 있는데, 인수를 주지 않거나 0을 주면 '정상 종료' 인수로 1을 주면 '비정산 종료'를 뜻함
4. OS
- OS 모듈은 운영체제 관련 유틸리티 함수 및 속성 정보를 제공.
const os = require('os');
console.log(os.arch()); // CPU 아키텍처
console.log(os.cpus()); // 컴퓨터의 CPU 코어 정보를 배열로 리턴
console.log(os.hostname()); // 운영체제 호스트명
console.log(os.networkInterfaces()); // 네트워크 정보
console.log(os.type()); // 운영체제 타입
console.log(os.platform()); // darwin
console.log(os.release()); // 운영체제 버전
console.log(os.homedir()); // 홈 디렉터리 경로
console.log(os.tmpdir()); // 임시 파일 저장
console.log(os.totalmem()); // 전체 메모리 크기
console.log(os.freemem()); // 사용 가능한 메모리 크기
5. Path
- path 모듈은 파일과 디렉터리 경로 작업을 위한 유틸리티를 제공.
const path = require('path');
- path.basename(path [. ext]): 경로의 마지막 부분 반환
console.log(__filename); // 현재 파일의 절대 경로
console.log(path.basename(__filename)); // 경로의 마지막 부분
console.log(path.basename(__filename, '.js')) // 경로의 마지막 부분에서 확장자를 제거한 이름
- path.delimiter: 운영체제별로 환경 변수 구분자를 가져오는데 윈도우는 시메콜론(;), 맥과 리눅스 같은 POSIX는 콜론(:)을 사용
- path.dirname(path): 파일이 위치한 폴더 경로를 반환한다.
- path.extname(path): 파일의 확장자를 반환한다.
- path.format(pathObject): dir, root, base, name, ext 프로퍼티가 있고 주어진 프로퍼티를 사용해 경로 문자열로 반환.
path.format({
root: '/ignored', // dir 값이 있으므로 root는 무시됨
dir: '/home/user/dir',
base: 'file.txt'
});
// 'home/user/dir/file.txt'
path.format({
root: '/',
base: 'file.txt',
ext: 'ignoerd' // base 값이 있으므로 ext는 무시됨
});
// 'file.txt'
path.format({
root: '/',
name: 'file',
ext: '.txt'
});
// 'file.txt'
- path.isAbsolute(path): 주어진 파일의 경로가 절대 경로인지 상대 경로 인지 알 수 있다.(절대 경로: true 반환)
- path.join([... paths]) : 문자열로 주어진 경로들을 모두 합쳐서 하나의 경로로 만들어서 반환
path.join('/foo', 'bar', baz/asdf'); // '/foo/bar/baz/asdf'
- path.parser(path) : path.format() 함수와 반대로 문자열로 된 경로를 pathObject로 반환.
path.parse('/home/user/dir/file.txt');
// { root: '/',
// base: '/home/user/dir',
// ext: '.txt',
// name: 'file' }
- path.sep: 경로 구분자를 반환(원도우: 역슬래시('\'), POSIX 계열: 슬래시('/')) 반환
6. URL
- url 모듈은 인터넷 주소에 해당하는 url을 다루기 위한 모듈.
- 두 가지 API를 제공하는데 하나는 Node.js 전용 레거시 API, 다른 하나는 웹 브라우저에 사용하는 것과
동일한 WHATWG URL 표준을 구현하는 최신 API이다.
- WHATWG API: URL 클래스를 new 생성자를 사용해서 생성하면 WHATWG 방식을 사용해서 URL 객체를 생성
const myURL =
new URL('https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash');
console.log(myURL);
//URL {
// href: 'https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash',
// origin: 'https://sub.example.com:8080',
// protocol: 'https:',
// username: 'user',
// password: 'pass',
// host: 'sub.example.com:8080',
// hostname: 'sub.example.com',
// port: '8080',
// pathname: '/p/a/t/h',
// search: '?query=string',
// searchParams: URLSearchParams { 'query' => 'string' },
// hash: '#hash'
//}
- 각각의 속성은 클래스 프로토타입의 getter 및 setter로 구현되기 때문에 다음과 같이 각 속성 정보를 가져오거나 변경할 수 있다.
const myURL = new URL('https://example.org/foo#bar');
console.log(myURL.hash);
// #bar
myURL.hash = 'baz';
console.log(myURL.href);
// https://example.org/foo#baz
- url 모듈을 가장 많이 사용하게 되는 예는 주어진 url 정보에서 전달된 쿼리 데이터를 추출할 때이다.
searchParams은 URLSearchParams 클래스로 쿼리 데이터를 조작하기 위한 다양한 내장 함수를 제공한다.
const myURL = new URL('https://example.org/?user=abc&query=xyz');
console.log(myURL.searchParams.get('user')); //키에 해당하는 첫번째 값을 반환
console.log(myURL.searchParams.has('user')); //키가 존재하는지 체크하고 있으면 true,
//없으면 false
console.log(myURL.searchParams.keys()); //Iterator로 모든 키를 반환
console.log(myURL.searchParams.values()); //Iterator로 모든 값을 반환
myURL.searchParams.append('user','admin'); //주어진 키로 값을 추가. 동일한 키가 이미 있으면
//그대로 유지하고 하나 더 추가
console.log(myURL.searchParams.getAll('user')); //키에 해당하는 값을 모두를 배열로 반환
myURL.searchParams.set('user','admin'); //주어진 키로 값을 추가. 동일한 키가 이미 있으면 모두 삭제하고
//새로 추가
myURL.searchParams.delete('user'); //해당 키를 삭제
console.log(myURL.searchParams.toString()); //searchParams 객체를 문자열로 반환
- 레거시 API: Node.js 레거시 API는 requrie() 함수로 url 호출 후 parse() 함수를 사용한다.
다음 예제처럼, WHATWG 방식과 Node.js 레거시 방식은 반환되는 Object의 구조가 다르다.
7. Cypto
- crypto 모듈은 다양한 암호화 기능을 제공함.
- 암호화에는 단방향 암호화와 양방향 암호화가 있고, 양방향 암호화에는 비대칭형 암호화 대칭형 암호화가 있다.
const crypto = require("crypto");
crypto.createHash("sha512").update("pw1234").digest("base64");
// 9iSeOd1vv2qinR2UM5Aog5LmqBncF/oFeTTsPUjqwGoG3lG232280LqAScE7FR7HHe4K0gyedCN7iZDZl+NZaA==
crypto.createHash("sha512").update("pw1234").digest("hex");
// f6249e39dd6fbf6aa29d1d943390288392e6a819dc17fa057934ec3d48eac06a06de51b6df6dbcd0ba8049c13b151ec71dee0ad20c9e74237b8990d997e35968
- createHash() 함수는 파라미터로 암호화에 사용할 알고리즘을 전달. update() 함수는 파라미터로 암호화할 문자열을 전달
digest() 함수는 파라미터로 어떤 인코딩 방식으로 암호화된 문자열을 표시할지 전달한다.
* 실제로 해커는 레인보우 테이블(다양한 암호화 결과 값과 암호화 전 원본값의 테이블)을 사용하는데 시간은 좀 걸릴 수 있지만, 해킹의
노출을 피할 수 없다. 그래서 원본 값을 알기 어렵게 처리해야 하는데 가장 많이 사용하는 것이 salting 암호화이다.
salting 말 그대로 소금(salt)을 뿌리는 것이다.
const createSalt = () => {
return new Promise((resolve, reject) => {
crypto.randomBytes(64, (err, buf) => {
if (err) reject(err);
resolve(buf.toString("base64"));
});
})
};
- randomBytes() 함수를 사용해서 64바이트 길이의 salt를 생성.
const createCryptoPassword = async (plainPassword) => {
const salt = await createSalt(); // salt 생성
return new Promise((resolve, reject) => {
crypto.pbkdf2(plainPassword, salt, 100000, 64, "sha512", (err, key) => {
if (err) reject(err);
resolve({ password: key.toString("base64"), salt });
});
})
};
- salt를 이용해 비밀번호를 암호화하는 함수로 pbkdf2() 함수를 사용하며, 파라미터로 암호화할 문자열인 비밀번호, salt, 반복 횟수,
출력될 바이트 수, 해시 알고리즘을 사용. pdbdf2() 함수는 암호화된 값과 salt 값을 반환
const getCryptoPassword = (plainPassword, salt) => {
return new Promise((resolve, reject) => {
crypto.pbkdf2(plainPassword, salt, 9999, 64, "sha512", (err, key) => {
if (err) reject(err);
resolve({ password: key.toString("base64"), salt });
});
})
};
- 사용자로부터 입력받은 비밀번호화 데이터베이스에 저장된 salt 값을 파라미터로 전달해서 암호화된 비밀번호 값을 가져오는 함수
8. File system
- fs 모듈은 파일 읽기, 쓰기, 삭제 그리고 폴더 생성, 삭제 등과 같은 파일 처리와 관련된 작업을 위한 모듈.
- fs.readFile(path, [options], callback) : 파일(path)을 옵션으로 지정한 문자 인코딩(utf-8)을 사용해 읽은 후 결과를
callback() 함수로 전달하는 비동기 방식 함수.
const fs = require('fs');
// 비동기 파일 읽기
fs.readFile('./sample/text.txt', 'utf8', (err, data) => {
if(err) {
throw err;
}
console.log(data);
});
- fs.readFileSync(path, [options]): 파일을 옵션으로 지정한 문자 인코딩을 이용해서 utf-8 형식으로 읽은 후 결과를 반환하는
동기 방식 함수.
const fs = require('fs');
// 동기 파일 읽기
var text = fs.readFileSync('./sample/text.txt', 'utf8');
console.log(text);
- fs.writeFile(path, data, [options], callback): 파일을 옵션방식을 사용해서 data를 쓰고 callback() 함수로 결과를 전달하는
비동기 방식 함수.
const fs = require('fs');
let data = '파일 쓰기 테스트';
// 비동기 파일 쓰기
fs.writeFile('./sample/text_w.txt', data, 'utf8', (err) => {
if(err) {
throw err;
}
console.log('비동기적 파일 쓰기 완료');
});
- writeFoleSync(path, data, [options]): 파일을 옵션 방식을 사용해서 data를 쓰는 동기 방식 함수.
const fs = require('fs');
let data = '파일 쓰기 테스트';
// 동기 파일 쓰기
fs.writeFileSync('./sample/text_w2.txt', data, 'utf8');
console.log('동기적 파일 쓰기 완료');
- fs.watchFile(filename [, options], listner) : 대상이 되는 파일의 변경 사항 여부를 감시할 수 있으며,
변경 사항이 발생하면 지정항 콜백 리스너 함수를 실행시킬 수 있다.
let sql = require('./sql.js); // 데이터베이스 쿼리문이 작성되어 있는 파일
fs.watchFile(__dirname + '/sql.js', (curr, prev) => {
console.log('sql 변경 시 재시작 없이 반영되도록 함.');
delete require.cache[require.resolve('./sql.js')]; // 캐시에 저장되어 있는 파일 삭제
sql = require('/.sql.js'); // sql.js 파일에 변경이 일어날 때마다 sql.js 재할당
});
'Runtime > Node.js' 카테고리의 다른 글
6. Express(에러, 정적 파일) (2) | 2023.01.29 |
---|---|
05. 라우팅 처리 (2) | 2023.01.19 |
04. Express 웹 서버 환경설정 (0) | 2023.01.17 |
03. json-server 이용하기 (0) | 2023.01.17 |
01. Node.js 시작하기 (0) | 2023.01.07 |