Node.js
V8 runtime 엔진 사용
라이프사이클이 매우 짧기 때문에 의존성에 맞춰서 사용해야하기 때문에 업데이트를 막해서는 안된다.
NVM (node version manager)을 이용한 설치
NVM 다운로드
node는 하위종속성 때문에 버전관리를 잘해야하는데 NVM을 이용해서 버전을 관리할 수 있도록 해주는 툴이다.
버전 체크, 도움말
nvm --version => nvm -v
nvm --help => nvm -h
node.js 다운로드
nvm install 18.15.0
다운받은 node 버전 확인, node 버전 변경, node 버전 확인
nvm list => node ls
nvm use 18.15.0
node -v
실행
node
이후 자바스크립트 코드를 그대로 사용할 수 있다.
종료
process.exit();
또는 ctrl+c 두번
js파일 실행
node ex01.js
getting started
js 파일 생성 후 실행시키면 서버 생성됨
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
node ex02.js
localhost:3000으로 접근하면 Hello World 확인 가능함
최상위 객체 Global (기존 js에서 Window에 해당)
변수
console.log(__dirname);
console.log(__filename);
console 객체 - 콘솔 화면 관련 기능 수행
메서드
error 에러 출력 (x) 표시
warn 경고 출력 (!) 표시
debug 디버깅 관련 정보
log 로그 출력
info 정보 출력
assert 검증(Assertion)
time(tag) 시간 측정 시작
timeEnd(label) 시간 측정 종료
formatting
console.log('%d <-- number', 1234);
console.log('%d <-- number', 3.14);
console.log('%s <-- string', "abcd");
console.log('%j <-- json', {key1:'val1'});
%% % 문자 자체
process 객체 - 프로그램과 프로세스 관련 기능 수행
console.log(process.argv, '실행 매개 변수');
console.log(process.env, '실행환경 관련 정보');
console.log(process.version, 'Node의 버전');
console.log(process.versions, '종속된 프래그램 버전');
console.log(process.arch, '프로세서의 아키텍쳐 표시');
console.log(process.platform, '플랫폼 정보 표시');
console.log(process.env.MYSQL_USER);
console.log(process.env.MYSQL_PW);
메서드
exit 프로그램 종료
memoryUsage 메모리 사용 정보 객체 반환
uptime 현재 프로그램이 실행된 시간
exports 모듈과 관련된 기능 수행 (CommonJS)
방법 1
-------------- module01.js
var func1 = function () {
console.log('func1 run...');
};
exports.func1 = func1;
exports.su1 = 1234;
-------------- ex06.js
var f = require('./module01');
f.func1();
console.log(f.su1);
방법 2
--------------- module02.js
var obj = {
su2: 4321,
func2: function() {
console.log('func2 run...')
}
};
module.exports = obj;
--------------- ex07.js
var o = require('./module02');
o.func2();
console.log(o.su2);
Node.js에서 자체적으로 제공하는 모듈
Os mudule
메서드
hostname 운영체제의 호스트명을 반환
type 운영체제의 이름을 반환
platform 운영체제의 플랫폼을 반환
arch 운영체제 아키텍처 반환
release 운영체제의 버전을 반환
uptime 운영체제 실행된 시간을 반환
loadavg 로드 평균값 정보 반환 (Array)
totalmem 운영체제 총 메모리 사이즈 반환
freemem 시스템 사용 가능한 메모리 반환
cpus CPU 정보 반환 (Array)
getNerworkInterfaces 네트워크 인터페이스 정보 반환 (Array)
더 자세한 내용은 Document 문서 참조 - OS Module
Url module
parse URL 문자열을 URL 객체로 변환
format URL 객체를 URL 문자열로 변환
resolve 매개변수를 조합, URL 문자열을 생성하여 반환
var url = require('url')
var msg = "https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=node"
console.log(url.parse(msg).protocol)
console.log(url.parse(msg).host)
console.log(url.parse(msg).port)
console.log(url.parse(msg).path)
console.log(url.parse(msg).query)
console.log(url.parse(msg).auth)
console.log(url.parse(msg).href)
// query String object 반환
console.log(url.parse(msg, true).query)
console.log(url.format(url.parse(msg)));
console.log('-------------');
console.log(url.resolve('https://m.naver.com', 'dept'));
Query String module
parse 쿼리 문자열을 쿼리 객체로 변환
stringify 쿼리 객체를 쿼리 문자열로 변환
var query = require('querystring');
var msg = 'where=nexearch&sm=top_hty&fbm=0&ie=utf8&query=node';
console.log(query.parse(msg));
console.log(query.stringify(query.parse(msg)));
Crypto module
암호화를 위한 모듈
Hash
var crypto = require('crypto');
var msg = 'abcdefg';
var hash = crypto.createHash('MD5'); // 실사용은 sha512로
hash.update(msg);
console.log(hash.digest('hex'));
File System module
readFile(file, encoding, callback) 비동기적 파일 읽기
readFileSync(file, encoding) 동기적 파일 읽기
writeFile(file, encoding, callback) 비동기적 파일 쓰기
writeFileSync(file, encoding) 동기적 파일 쓰기
appendFile(file, encoding, callback) 비동기적 파일 추가
appendFileSync(file, encoding) 동기적 파일 쓰기
readFile
var fs = require('fs');
// 비동기적
fs.readFile('ex01.js', function(err, data) {
console.log(data.toString('utf-8'));
});
// 동기적
var msg = fs.readFileSync('ex01.js', 'utf-8');
console.log(msg);
두 코드다 결과는 아래와 같음
writeFile
var fs = require('fs');
fs.writeFile('temp01.txt','한글작성', function(err){
console.log(err);
})
fs.readFile('temp01.txt', function(err,data){
console.log(err,data.toString('utf-8'));
});
FileSync
var fs = require('fs');
fs.writeFileSync('temp02.txt','한글작성2');
var msg = fs.readFileSync('temp02.txt','utf-8');
console.log(msg);
var fs = require('fs');
fs.writeFile('temp03.txt', '한글작성', function(err){
console.log(err);
});
var msg = fs.readFileSync('temp03.txt','utf-8');
console.log(msg);
위처럼 하게되면 순서가 보장되지않기 때문에 실제로 쓰기도되고 읽기도 되나 제대로 읽어오지 못한다.
자바스크립트에서는 이처럼 동기적인통신을 하게 되면은 그만큼 성능저하가 되기 때문에 사용하는 것을 지양한다.
mkdir
var fs = require('fs');
fs.mkdir('js01', function(err){
console.log(err);
});
rmdir
var fs = require('fs');
fs.rmdir('js01', function(err){
console.log(err);
});
rename
rename은 파일명을 수정하는 용도보단 이동시키는 용도로 더욱더 많이 사용된다.
fs.rename('temp03.txt', './js02/temp05.txt', function(err) {});
readdir
var fs = require('fs');
fs.readdir('.',function(err,files){
files.forEach(function(ele,idx){
console.log(ele);
});
});
events module
var event = require('events');
var obj = new event.EventEmitter();
obj.once('call', function(e){
console.log('이벤트 발생');
});
obj.on('call2', function(e){
console.log('이벤트 발생2');
});
obj.emit('call');
obj.emit('call');
obj.emit('call2');
http module
var http = require('http')
// var query = require('querystring');
var url = require('url');
var fs = require('fs');
var server = http.createServer(function(req,res){
// console.log(query.parse(req.url));
// console.log(url.parse(req.url).path);
// console.log(url.parse(req.url, true).query.id); // localhost:3000/?id=admin => admin
res.writeHead(200,{'Content-Type':'text/html'})
// res.setHeader('Content-Type', 'text/plain');
// res.write('abcd');
// res.write('<h1>abcd</h1>');
// var msg = fs.readFileSync('ex22.html', function(err, data){
// res.write(msg);
fs.readFileSync('ex22.html', function(err, data){
res.write(data);
res.end();
});
// res.end(); // 여기서 끊으면 위의 콜백함수에서는 write가 안된다.
});
server.listen(3000,function(){
console.log('server start...');
});
웹서비스 구현
위의 내장 모듈을 이용한 구현
var http = require('http');
var url = require('url');
var fs = require('fs');
http.createServer(function(req,res) {
var obj = url.parse(req.url, true);
// localhost:3000/index.html
if(obj.path=='/index.html'){
res.writeHead(200, {'Content-Type': 'text/html'})
.end(fs.readFileSync(__dirname + '/js02/index.html'));
// localhost:3000/ex01.html
} else if(obj.path=='/ex01.html'){
res.writeHead(200, {'Content-Type': 'text/html'})
.end(fs.readFileSync(__dirname + '/js02/ex01.html'));
} else {
res.writeHead(404, {'Content-Type': 'text/html'})
.end(fs.readFileSync(__dirname + '/js02/err.html'));
}
}).listen(3000);
express.js 라이브러리를 이용한 웹서비스 구현
설치
npm i express
서버 생성
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
Event
// localhost:3000/dept... 인 것만 이벤트 호출됨
app.use('/dept', function(req,rep,next) {
console.log('/dept 호출...');
next(); // 일치하는 다음패턴 이벤트도 시행함
})
// 먼저 패턴이 맞으면 실행하고 끝나기 때문에 코드 순서가 중요하다.
app.use('/', function(req,res,next) {
console.log('/ 호출...');
})
Response
app.use('/', function(req,res,next) {
res.status(200);
res.send('<h1>ok 페이지...</h1>')
})
static - 정적파일 로드
// 해당 디렉토리의 정적파일들을 불러 올 수 있게된다.
var f = express.static('js02');
app.use(f);
// localhost:3000/index.html
// localhost:3000/ex01.html
RESTful
app.get('/dept', function(req,res,next) {
console.log(req.method)
res.send('<h1>dept 페이지...(get)</h1>')
})
app.post('/dept', function(req,res,next) {
console.log(req.method)
res.send('<h1>dept 페이지...(post)</h1>')
})
app.put('/dept', function(req,res,next) {
console.log(req.method)
res.send('<h1>dept 페이지...(put)</h1>')
})
app.delete('/dept', function(req,res,next) {
console.log(req.method)
res.send('<h1>dept 페이지...(delete)</h1>')
})
PathVariable
app.get('/dept/:deptno', function(req,res,next) {
// PathVariable
console.log(req.method, req.params.deptno)
res.send('<h1>dept 페이지...(get)</h1>')
})
RequestParam
app.get('/dept', function(req,res,next) {
// RequestParam
console.log(req.method, req.query.deptno)
res.send('<h1>dept 페이지...(get)</h1>')
})
body-parser
app.use(express.json())
app.use(express.urlencoded({extended:false}))
app.post('/dept', function(req,res,next) {
// RequestBody
console.log(req.method, req.body.deptno)
res.send('<h1>dept 페이지...(post)</h1>')
})
EJS
Template Engine -설치
npm i ejs
.js
// template
app.set('views', __dirname+'/views')
app.set('view engine', 'ejs')
// localhost:3000/intro
app.get('/intro', function(req,res){
var arr = ['item1', 'item2', 'item3','item4']
var obj = {key1:"val1", key2:"val2"}
var nalja = new Date();
res.render('intro', {msg:'hello', arr:arr, obj:obj, nalja:nalja})
})
.ejs
<body>
<h1>ejs page</h1>
<p><%=msg %></p>
<ul>
<% arr.forEach(function(ele,idx){ %>
<li><%=ele%></li>
<% }) %>
</ul>
<p><%=obj.key1 %></p>
<p><%=obj.key2 %></p>
<p><%=nalja %></p>
</body>
connection Mysql
설치
npm i mysql
connect
var mysql = require('mysql')
var conn = mysql.createConnection({
host: "192.168.99.100",
user: "scott",
password: "tiger",
database: 'lecture'
})
conn.connect(function(err){
if(err) throw err;
console.log('Connected!...');
})
mysql 8.0 버전 이상을 사용할 경우 node와 연결이 되지않는 경우가 있는데 이는 mysql 8.0 버전부터 password를 암호화인증 플러그인이 caching_sha2_password방식이기 때문인데 이 달라진 플러그인을 node에서 지원하지 않을 경우 아래의 오류가 발생된다!
이를 해결하기 위해선 mysql에 root 계정으로 직접 접속해서 아래 명령어로 플러그인을 변경 해주면 된다!.
alter user 'scott'@'%' identified with mysql_native_password by 'tiger';
flush privileges;