Node.js 기본
Upcoming SlideShare
Loading in...5
×
 

Node.js 기본

on

  • 14,839 views

node.js 의 기본이 되는 부분을 정리해놓은 자료 입니다. ...

node.js 의 기본이 되는 부분을 정리해놓은 자료 입니다.
시중에 나와있는 서적과 인터넷 자료를 분석 후 기본이 되는 부분만 정리해놓았습니다.
이전 업데이트와 다르게 비동기 모듈, express, heroku 설치, 디버깅 방법이 추가되었습니다.

Statistics

Views

Total Views
14,839
Views on SlideShare
14,743
Embed Views
96

Actions

Likes
141
Downloads
622
Comments
9

6 Embeds 96

https://twitter.com 47
http://mangastorytelling.tistory.com 19
http://sencha.tistory.com 15
http://cafe.naver.com 10
http://www.hanrss.com 4
http://www.pinterest.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • 굿!
    Are you sure you want to
    Your message goes here
    Processing…
  • 정말 최고신거같아요. 클라개발만하다가 노드첨하는데 이해가 쏙쏙되네요.
    Are you sure you want to
    Your message goes here
    Processing…
  • 자료 많은 도움이 되었습니다. 감사합니다.
    Are you sure you want to
    Your message goes here
    Processing…
  • @Daehee Han 링크에 걸린 블로그에 보면 모바일 서버에 사용된 모든 스택이 node.js로 되어있다고 하네요. 전체 서버를 모바일 서버로 변경해야 겠네요^^ 감사합니다.
    Are you sure you want to
    Your message goes here
    Processing…
  • 중간에 Linkedin 전체 스택이 노드로 되어있다는 점은 사실과 다르네요. 모바일 (+ 웹) API에 node를 사용하고 있는 것으로 알고 있습니다.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Node.js 기본 Node.js 기본 Presentation Transcript

  • Node.js 기본 발표자 : 한정현 kazikai84@gmail.com SK planet
  • Node.js 에 대해서.. • 서버사이드 자바스크립트 (V8 엔진으로 컴파일) 프레임워크 • 이벤트 기반으로 동작 하며, Non -Blocking I/O 방식 • 목적은 확장가능한 네트워크 프로그램들을 간단하게 만드는것 • 현재(2014.01.08) 버전: v0.10.24 • CommonJS 모듈 시스템 • C랑 C++로 만들어짐 • 2009년 라이언 달이 JSConf 에 발표하면서 화제 • 단 하나의 쓰레드가 이벤트 루프를 구동
  • Node.js 장점 • 가벼움 ( 아래의 코드로 간단한 http server 를 돌릴수 있음 ) ! ! ! ! ! • 빠름 :10만 동시 접속 테스트 성공 - 스프라이트를 전송하는 초당 20,000번의 트래픽, CPU 점유율은 5~40% • 추후 25만 동시 접속도 성공 • http://blog.caustik.com/2012/04/08/scaling-node-js-to-100k-concurrent-connections/ • apache에 비해 간단한 http속도가 3배 빠름 • http://zgadzaj.com/benchmarking-nodejs-basic-performance-tests-against-apache-php ! • 많은 모듈 : 현재 53919 개 ( npm 으로 공개된것들) • 자바스크립트로 다 할수있음 var sys = require('sys'), http = require('http'); http.createServer(function(req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.write('<p>Hello World</p>'); res.end(); }).listen(8080);
  • Node.js 단점 • 쉽게 구현되는 JSON 프로토콜을 이용하면 바이너리 데이터에 비 해서 encoding/decoding 이 느릴수 있음 • 이벤트 구동 방식 프로그래밍은 구현하기 쉽지 않음 • 실수로 동기적 코드를 이용하는 경우 치명적인 성능 저하를 유발 할 수 있다. • 아직 0.10.24 이다.(불안정)
  • 왜 Non-Blocking 인가? • 기존의 Web Application에서 db를 조작할때 var result = db.query(“select * from T”); // use result • Event-driven 방식에서 db를 조작할때 db.query("select..", function (result) { //use result } • event loop 만 즉각적으로 return 되어 중간에 delay 되는 시간이 없다.
  • 그럼 왜 그동안 사용안했나? • 문화적 • event 방식 구현이 익숙치 않다. ! • 인프라적 • C는 익명함수도 없고 closure도 없음, callback 도 만들기 어려움 • 대부분의 library 들이 non-blocking i/o 를 지원 하지 않음 (database 라이브러리도 ) • POSIX 에서 비동기 파일 입출력을 이용할수 없음 (구현 된것도 있지만, 깔끔하지 않다. ) puts("Enter your name: "); var name = gets(); puts("Name: " + name); puts("Enter your name: "); gets(function (name) { puts("Name: " + name); }); VS
  • 자바스크립트인 이유 in Node.js • 익명 함수, closures • 한번에 1개의 callback • 함수를 파라미터로 전달, 변수에 할당 가능, 리턴값으로 사용 가능 ( first-class function ) • 이미 이벤트 기반이 익숙한 language • 특정 시점에 실행중인 이벤트 핸들러는 하나 뿐임 • 모든 이벤트 핸들러는 방해 없이 실행을 마칠수있음
  • 어디서 사용하나? 관련 소식들.. • Storify • Cloud IDE 9 • Linked in : 전체 서버 스택이 모두 node 로 되어있음 • 확장성/ 성능적이 이점 때문에 사용 • http://venturebeat.com/2011/08/16/linkedin-node/ • Ebay & Papal
  • 설치 • http://nodejs.org/download/ • Windows/Mac 은 쉽게 설치 가능 • Linux 는 환경 준비 필요 (리눅스만 좀 까다로움) • python2.6+/ libssl-dev 설치 • debian/Ubuntu • $ sudo apt-get update • $ sudo apt-get upgrade • $ sudo apt-get install build-essentil openssl libssl-dev pkg-confi • wget http://nodejs.org/dist/v0.10.24/node-v0.10.24.tar.gz • tar -zxf node-v0.10.24.tar.gz • ./configure • make && sudo make install • 짝수 버전은 stable 버전 이고, 홀수 버전은 unstable 버전임, 홀수 버전은 API또한 향후에 수정 될 수있음, 안정 버전은 공개 API 변경안함.
  • npm install 하기 • 전역모드 설치 : /usr/local/lib/node_modules • $ npm install -g <패키지명> • 지역모드 • $ npm install <패키지명> • 버전 설치 • $ npm install <패키지명>@<버전> • $ npm install jshint@1.1.0 //1.1.0 설치 • $ npm install jshint@1.1.x //해당 브랜치의 최신 배포판 • $ npm install jshint@“<2.0” // 하위 버전 • $ npm install jshint@“>=0.1.0 <2.1” // 0.1과 2.1 사이의 최신 배포판
  • npm uninstall/update • 전역모드 제거 : /usr/local/lib/node_modules • $ npm uninstall -g <패키지명> • 지역모드 제거 • $ npm uninstall <패키지명> • 업데이트 • $ npm update <패키지명> • $ npm -g update <패키지명>
  • 의존성 관리하기 • npm 으로 설치하면 해당 모듈의 의존성을 확인 가능 ! ! • package.json • npm install 하면 한번에 설치됨 • name 과 version 필드 꼭 필요 (공개 패키지를 기술하기 위해 고안되어서. ) ! ! ! { "name": "planet.js", "version": "1.1.0", "description": "SKP", "main": "Gruntfile.js", "scripts": { "test": "SKP Web Tech. Dev Team" }, "repository": { "type": "git" }, "dependencies": { "fstream": "~0.1.18", "archiver": "~0.1.0", "rimraf": “~2.0.2" } }
  • publish 하기 ! ! ! ! ! ! • ! • 결과물 : https://npmjs.org/package/kazikai • 이거 하고 한개 증가…53 920 $ npm set init.author.name "Your Name" $ npm set init.author.email "you@example.com" $ npm set init.author.url "http://yourblog.com" $ npm adduser $ cd /path/to/your-project // 프로젝트로 이동 $ npm init $ npm install -g pakmanager $ pakmanager deps $ npm publish ./
  • 모듈 저장/불러오기 • Node.js 에서 모듈을 로드 하려면 다음과 같이 작성한다. • 또한 작성한 함수를 모듈로 내보내기 위해서는 아래와 같이 작성하면 된다. (2방식 모두 가능) ! ! ! • 위와 같이 작성한 함수를 사용하려면 아래와 같이 사용 가능한다. export.add = function (a,b){ return a+b; }; var add = function (a,b){ return a+b; }; exports.add = add; //위 코드를 add.js 에 저장 var module1= require(“web”); var add = require(‘./add.js’); console.log( add.add(1,2) );
  • 모듈 로딩 • 코어 모듈 로딩 : 기존 node.js 바이너리 배포판 내에 미리 컴파일 된 모듈 • var module1 = require(‘http’); • 모듈명으로만 참조 한다. 같은 이름의 서드파티 모듈이 존재하더라도 우선적으로 로딩 됨 • 파일 모듈 로딩 : 절대/상대 경로 로 로딩 하면 로딩 가능 • var module2 = require(‘/home/a/b’); • var module2 = require(‘./b.js’); • var module2 = require(‘./b’); //js 확장자는 생략 가능
  • 모듈 로딩 • 폴더 모듈 로딩 • var module3 = require(‘./moduleDir’); • 해당 폴더내에서 모듈을 찾음 . • 패키지라고 가정 하며, package.json을 찾는다. • package.json 의 main 속성을 분석해 상대경로를 찾는다. • package.json파일이 없다면 index.js 를 찾는다.
  • 모듈 로딩 • node_modules 폴더 이용한 로딩 • var module4 = require(‘mymodule.js’); • 위와 같이 작성하면 해당 경로의 ./node_moduels/mymodule.js 를 찾음 • 그래서 없으면 상위의 node_modules를 찾는다. • 위와 같은 형식으로 root 폴더까지 탐색후 없으면 error
  • 모듈 캐싱 • 모듈 캐싱 • 모듈은 처음 로딩 될때 캐싱 된다. • 그렇기 때문에 require로 같은 모듈을 불러온다면, 반환되는 모듈은 항상 같다. • 초기화 할때 발생하는 event를 사용하거나, 해당 로직을 추가 한 경우 주의 • 간단한 예제를 보자 test.jsinit.js 결과
  • 개발을 도와주는.. REPL • REPL : read-eval-print loop 라고 불리는 대화형 구성요소 • $ node 라고 입력하면 사용 가능 • > 명령줄 프롬프트 제공 • 입력하는 모든것이 V8 JavaScript 엔진에서 처리된다. • 세션 종로 : Ctrl -C 2번 / Ctrl -D • 예제 1: > 3>2>1 결과는 ? • 예제 2 : console.log(global) • 모듈의 내부를 보고싶을때 유용함 : cache도 확인 가능
  • 개발을 도와주는.. REPL • .help • .clear • 컨텍스트 개체를 재설정 하고, 여러줄로 된 수식을 지움 처음부터, 다시 시작 • .save ./save.js • 입력된 내용만 저장 • .break • 여러줄로 된 항목을 입력하는도중에 위치를 잃어버렸을 경우 다시 시작할수있음 • .exit • REPL 종료 • .load • 파일을 현재 세션으로 로드 한다.
  • 내장 객체 : process • 프로그램과 관련된 정보를 나타내는 객체 • 브라우저에는 존재 하지 않음! ! ! ! ! ! ! ! • argv : 실행 매개 변수 : 어떤 파일에서 실행 된것인지? • env : 컴퓨터 환경 관련 정보 • version : Node.js 버전 : 0.10.24 • versions : Node.js 종속된 프로그램 버전 • arch: 프로그램 아키텍쳐 : 32비트 ?64비트 • platform: 플랫폼 • memoryUsage(): 메모리 사용량 • uptime() : 프로그램 실행된 시간 • exit() : 프로그램 종료
  • 내장 모듈을 보기전에. • Node.js 는 stable api / unstable api 가 나눠짐 • 각 api 의 level이 있음 : http://nodejs.org/api/documentation.html • 개발시에 필히 몇레벨인지 확인한후, 사용하는것이 필요 : • Stability 0 : Deprecated • 문제가 있어서 변경될 예정, 사용하면, 상당한 문제를 야기할수있음 • 하위호환성 없으니 신뢰하지 말아야함 • Stability 1 : Experimental • 나온지 얼마 안됨, 변경되거나 삭제될 수도 있음 • 사용한다면, 피드백을 node.js core 팀에게 줘야함 • Stablility 2 : Unstable • 현재 만들고 있지만, 상용화 하기는 부족함 • 하위 호환성이 일부 있을수도 있음
  • 내장 모듈을 보기전에. • Stability 3 : Stable • 사용에는 큰 문제가 없으나, 코드가 깔끔하지 않기 때문에 마이너한 변화가 있을 예정 • 하위 호환성 보장 • Stability 4 : API Frozen • 다양한 상품에서 넓게 테스트해서 이제는 거의 안바뀜 • Stablility 5 : Locked • 정말 심각한 버그가 있지 않는 이상 절대 안바뀜
  • 내장 모듈 : OS • require(‘os’); 로 사용 : stability 4 • 운영체제와 연관된 유틸리티 함수들 : http://nodejs.org/api/os.html • tmpdir() : 시스템의 기본 임시 폴더를 리턴 • hostname() : 운영체제의 호스트 이름 • type() : 운영체제 이름 • platform() : 운영체제 • arch() : CPU 아키텍쳐 • uptime() : 운영체제 실행된 시간 • loadavg() : 운영체제 loadaverage • totalmem() : 메모리 • freemem() : 가용 메모리 • cpus() : cpu • getNetworkInterfaces() : 네트워크 환경
  • crypto 모듈: 예제로 이해 하기 • crypto 모듈은 해시 생성과 암호화를 수행 하는 모듈임 : stability 2 • id/pw 를 저장 하는 서버에서 매우 중요한 모듈 • 해시화 한 결과 값만 저장 하기때문에 해커가 결과값을 가지고 있어도, 정보를 보호 할 수있다. var crypto = require('crypto'); var key = 'websecretkey'; var input = '12345678'; ! var cipher = crypto.createCipher('aes192', key ); cipher.update(input, 'utf-8', 'base64'); var cipherOutput = cipher.final('base64'); ! var decipher = crypto.createDecipher('aes192', key); decipher.update(cipherOutput, 'base64', 'utf-8'); var decipherOutput = decipher.final('utf-8'); ! console.log("input : " + input ); console.log("cipherOutput : " + cipherOutput ); console.log("decipherOutput : " + decipherOutput );
  • 내장 모듈: FS • 노드의 파일 api는 대부분 유닉스 API를 직접 변환하여, 사용하는 방식이 유사함 • 파일 조회 및 조작 함수가 있으므로, Node.js 에서 빈번하게 사용 됨 • stability 3: http://nodejs.org/api/fs.html • var fs = require(‘fs’); 로 로딩 • readFile / readFileSync 와 같이 비동기/동기 방식의 api가 2개씩 존재함 • 비동기 버전은 콜백이 항상 마지막 인수로 들어가게 됨 • 비동기 버전을 사용 할 경우, 순차적으로 실행이 안될 수 있기 때문에 고려해서 작성해야함 fs.rename('./name.js', './name2.js', function (err) { if (err) throw err; console.log('renamed complete'); }); fs.stat(‘./name2.js’, function (err, stats) { if (err) throw err; console.log('stats: ' + JSON.stringify(stats)); }); error 발생
  • 내장 모듈: FS • 앞장의 비동기 버전의 error를 해결하려면 아래와 같이 작성해야 한다. ! fs.rename('./name.js', './name2.js', function (err) { if (err) throw err; fs.stat('./name2.js', function (err, stats) { if (err) throw err; console.log('stats: ' + JSON.stringify(stats)); }); });
  • 이벤트 • node.js 는 이벤트 타입과 이벤트 핸들러를 통해 이벤트를 생성 할수 있음 • Stabliltiy 4 • var a = require(‘events’).EventEmitter; • var b = new a(); //이렇게 해도됨 var b = new( require(‘events’).EventEmitter )( ); • 기본 이벤트 method 는 “addListener” ( 일부책에서 addEventListener라고 잘못나와있음) ! ! • 이벤트 연결 개수는 제한이 있으며, 10개 가 넘는 이벤트는 개발자 실수로 간주 하고 error를 출력 • .setMaxListeners(n) 를 통해 이벤트 등록 개수를 변경 할수 있다. ( 0 무한대) • 이벤트가 발생 되었을때 리스너중 하나가 예외를 발생 시킨다면, 다음 이벤트 리스너는 호출 되지 않을 수있음 b.on(‘exit',function () { console.log("exit test"); });
  • 이벤트 • 제거는 removeListener( type, callback ) • 콜백 함수의 이름을 지정해서 등록한 경우만 가능하다. • 익명함수로 등록한 콜백은 제거가 안됨 • removeAllListeners( type ) • 모든 리스너를 제거 하는 함수 ( 익명 함수도 제거가 가능하다.) • 한번만 바인딩 하고싶을 경우 once() • 이벤트 강제 발생은 emit( type ) ! ! ! • 커스텀 이벤트 이미터는 다음에..
  • 커스톰 이벤트 만들기 • util 모듈과 EventEmitter 모듈 사용 ! ! ! ! util = require('util'); var eventEmitter = require('events').EventEmitter; ! var Custom = function() {}; ! // util.inherits 이 이벤트를 상속한 util.inherits( Custom, eventEmitter ); ! var custom = new Custom(); custom.on('event1', function() { console.log('event1'); }); custom.emit('event1');
  • 전역 객체에 관해서.. • 사용자가 모듈을 포함 시킬 필요없이 사용 가능한 전역 객체 = global • console.log( global ); // 이와 같이 출력 가능 ( 커맨드 창에서 꼭 실행해보자 ) • 브라우저의 window 객체와 유사하지만, 사용가능한 매소드나, 속성이 다름 • window 객체는 진정한 전역 객체 : 전역 변수 선언하면, 웹페이지와 모든 라이브러리에서 접근 가능 • node 는 모듈안에서만 전역 객체 : 애플리케이션이나, 다른 모듈에서 최상위 모듈변수는 접근 불가능 • 모듈에서 내보내어진 것만 접근 가능
  • Promise VS Callback • 초기의 Node는 1970년대에 등장한 개념인 Promise 를 사용 하여 비동기가 만들어졌음 • promise는 success & error 라는 두개의 이벤트만을 발생시키는 개체였음, • 위 2개의 이벤트만 발생하며, 한번만 발생함 • promise는 이벤트가 종료될때 적절한 기능을 수행 할 수있었다. • 하지만, Node 0.1.30 에서 제거됨. • 제거사유는 다음과 같다. 많은 사람들은 개체를 생성할 필요가 없는 파일 시스템 동작에 대한 저수준 인터페이스만을 원하는 반면, promise와 유사 하지만, 어떻게든 다른 것을 원하는 사람들도 많은것 같다. 따라서 promise 대신 최종 인수 콜백을 사용하도록 하고, 보다 나은 추상화 계층을 구축하는 것은 사용자 라이브러리 에 맡기도록 하겠다. - Ryan Dahl
  • 비동기 패턴 및 제어 흐름 모듈 • Node 의 함수들은 대부분 비동기로 동작 하기 때문에 비동기를 제어하는 패턴을 제공하는 모듈들이 있음 • 가장 흔히 사용하는 seires와 parallel 을 대부분의 모듈에서 제공 ( 일부는 promise 도 제공 ) • 유지/보수가 제일 활발한 control flow 모듈중 가장 인기 있는 것들 2가지 : Step & Async
  • Step 모듈 • Step 은 순차 및 병렬 실행의 흐름을 간단하게 제어 할수있게 해주는데 초점을 맞춘 모듈 • 설치 방법 : $ npm install step • 단 한개의 개체만 제공 : var Step = require(‘step’); var Step = require('step'); var fs = require('fs'); ! var data; Step( function readData() { fs.readFile('./data.txt', 'utf8', this ); // fs.freadFile의 전달 인자는 err, data }, function modifyData(err, data) { if ( err ) throw error; console.log( "text" + data ); return data.replace('example','modify'); }, function writeData(err, data) { if ( err ) throw error; fs.writeFile( './data.txt', data, this ) } );
  • Async 모듈 • Async 모듈은 forEach, map, fileter 등을 독자적으로 변형한 것처럼 컬렉션을 관리하는 기능도 제공, • 제어 흐름을 처리하는 기능이 중요 • Async 와 Async.js 모듈 두개가 존재 하므로, 혼동 하지 않도록 주의 한다. • Caolan McMahon이 만든 Async 를 사용해야 함 : https://github.com/caolan/async • 설치 : $ npm install async • 흐름 제어 관련 메소드들 waterfall : 함수가 순서대로 호출 되고, 모든 함수의 결과가 마지막 콜백에 배열로 전달 series : 함수들이 순서대로 호출되며, 선택적으로 결과가 마지막 콜백에 배열로 전달 parallel : 함수들이 병렬로 실행되며, 실행이 완료되면, 결과들이 마지막 콜백으로 전달 whilst : 한 함수를 반복적으로 호출하되, 사전 준비 테스트가 false를 반환하거나, 오류를 발생하는 경우에 만 마지막 콜백이 호출 queue: 지정된 동시 제한 수까지 함수를 병렬로 호출 하고, 함수중 하나가 완료되면 새로운 함수가 큐에 들 어감 until: 한 함수를 반복적으로 호출 하되, 후처리 테스트가 false를 반환하거나 오류를 발생하는 경우에만 마 지막 콜백이 호출 auto : 함수가 요구사항을 기반으로 호츌되며, 각 함수는 이전 콜백의 결과를 받는다. iterator: 각 함수가 다음 함수를 호출하며, 각각 다음에 있는 반복자에 접근할 수있음 apply: 이전에 적용된 인수를 가지고, 다른 제어 흐름 함수와 결합되는 연속 함수 nextTick : Node의 process.nextTick을 기반으로 이벤트 루푸의 다음번 루프에서 콜백 호출
  • Async 모듈 예제 ! ! ! ! var fs = require('fs'); var async = require('async'); ! async.waterfall([ function readData( callback ){ fs.readFile( './data1.txt', 'utf8', function( err, data ){ callback( err, data ); }); }, function modifyData( data, callback ){ var modifiedData = data.replace('example','modify'); callback( null, modifiedData ); // 비동기가 아닌경우 이런식으로 callback을 전달해줘야한 다. }, function writeData( data, callback ){ fs.writeFile( './data1.txt', data, function( err ) { callback( err, data ); }); } ], function( err, result ){ if ( err ) throw err; console.log("callback"); console.log( result ); });
  • Server객체 • HTTP 모듈에서 가장 중요한 객체 : http 모듈의 createServer(); 메서드로 생성 • sever객체는 listen() 과 close() 메소드를 보유 • sever.listen( 80 ) : 80포트로 서버 실행 • server.close() : 서버 종료 • sever객체는 EventEmiiter 객체 기반으로 생성 되었으며, 이벤트를 연결 할수있음 • request : 클라이언트가 요청할때 발생 : on메서드 사용없이 매개변수로 입력 가능 • connection : 클라이언트가 접속할때 발생 • close : 서버가 종료될때 발생 • checkContinue : 클라이언트가 지속적인 연결을 하고있을때 발생 • ungrade: 클라이언트가 HTTP 업그레이드 요청할때 발생 • clientError: 클라이언트에서 오류가 발생할 경우 발생
  • 쉬어가기: Node 단독실행방법 • node app.js • #!/usr/local/bin/node • chmod a+x app.js • ./app.js
  • node 사용패턴: 문법가이드 • https://github.com/felixge/node-style-guide • 노드는 특정한 convention은 없지만, 가장 유용한 위 가이드를 참조 한다. • 2 스페이스 들여”쓰기 • new line n 사용: ( 윈도우 스타일 rn 은 금지 ) • 빈공간을 만들지 말라. • 세미콜론 사용 • 한 라인에 80자로 제한 • 싱글 quote 사용 • 같은 라인에 중괄호 사용: if (true) {
  • node 사용패턴: 문법가이드 ! • var 선언에 var 를 꼭 붙혀라 ( 크록포드 스타일은 무시) • 소문자 camel case기법으로 변수, 속성, 함수 이름 사용 • 상수는 당연히 대문자다 • === 사용 • object 와 배열 선언 방법 ! ! • • 삼중 연산자는 아래와 같이 사용 var a = { good: 'code', 'is': 'pretty' }; var b = ['hello', 'sk', 'planet']; var foo = (a === b) ? 1 : 2;
  • node 사용패턴: 문법가이드 • 내장 객체의 prototype 확장 금지 • 조건 문의 조건은 항상 올바른 의미를 가진 변수에 할당해서 사용 ! ! ! • 작은 함수들을 사용해라 ( 15라인 정도의) • 중첩된 조건문을 피하기 위해 가능한 함수가 리턴해라 (else 를 굳이 넣을필요가 없다. ) • 삼항 연산자는 아래와 같이 사용해라. ! ! • 클로져에는 이름을 명시하라. var isValidPassword = password.length >= 4 && /^(?=.*d).{4,}$/.test(password); ! if (isValidPassword) { console.log('winning'); } var foo = (a === b) ? 1 : 2;
  • node 사용패턴: 문법가이드 ! • 중첩 콜백 사용 금지 ( 아래와 같은 경우 익명 함수를 명명함수로 바꿔야함 ) ! ! ! • 아래의 경우가 올바른 사용 setTimeout(function() { client.connect(function() { console.log('losing'); }); }, 1000); setTimeout(function() { client.connect(afterConnect); }, 1000); ! function afterConnect() { console.log('winning'); }
  • Node server 체크 방법 • crontab 과 curl 을 이용해서 사용 가능 : crontab -e • curl 로 특정시간 node server를 체크 한다음 response 를 분석하여, server 가 오류인지 아닌지 판단
  • 유용한 모듈 : SUPERVISOR • 전역모듈로 터미널에서 사용 가능 • 설치 : $ npm install -g supervisor ( 관리자 권한 필요 ) • 사용 방법 : supervisor test.js ( 실행시킬 app) • 용도 : 변경된 스크립트를 재실행 하지 않아도 종료 후 다시 실행해준다. • 기본 명령어를 확인 하기 위해서는 supervisor 커맨드를 입력하면 된다. • 이 모듈은 해당 application이 종료되면 무한으로 다시 실행하므로 주의하여 사용 필요
  • 유용한 모듈: FOREVER • 전역모듈로 터미널에서 사용 가능 • 설치 : $ npm install -g forever ( 관리자 권한 필요 ) • 사용 방법 : forever start test.js ( 실행시킬 app) • 예외 하나로 쉽게 웹 서비스가 죽어버리는 node.js 를 보완 하고자 만들어진 모듈 ( 예외 처리가 안된경우) • 기본 명령어를 확인 하기 위해서는 forever 커맨드를 입력하면 된다. • 예외가 발생하여도 서버는 다시 시작 된다. • 많이 사용 하는 커맨드 • $ forever list : 현재 실행되고 있는 웹 서버를 확인 할때 • $ forever start app.js : app.js 를 실행 • $ forever stop 0 : 해당 번호를 가지고있는 프로세스 종료
  • FOREVER- 예제 • 아래와 같은 코드를 실제 실행 해보자 • $ node app.js vs $ forever start app.js • nonExistentFunc() 때문에 브라우저에 해당 url을 요청 하면 한번 실행 되고 죽는다. • 하지만 forever 모듈로 실행하면, 오류가 발생해도 다시 서버는 살아있음 • 실제 서비스를 운영할때는 안정적인 서비스를 위해 forever 모듈 사용 필요 var http = require('http'); http.createServer( function( request, response) { response.writeHead( 200, {'Content-Type': 'text/plain'}); response.end('Hello Worldn'); nonExistentFunc(); }).listen( 8080 ); console.log('Server running at http://127.0.0.1:8080');
  • 유용한 모듈 : EXPRESS • node.js 에서 가장 많이 쓰이는 web 프레임워크 : small & robust ? • https://www.npmjs.org/package/express • 설치 : npm install express • 기능들 • Robust routing • HTTP helpers (redirection, caching, etc) • View system supporting 14+ template engines • Content negotiation • Focus on high performance • Environment based configuration • Executable for generating applications quickly • High test coverage
  • EXPRESS 시작하기 • $ npm install -g express-generator@3 ( 관리자권한 ) • $ express extest(생성할 폴더) • $ cd extest • $ npm install( 패키지 설치 ) • $ npm start • http://localhost:3000/ 로 접속
  • EXPRESS: response 객체 • response : express 모듈로 서버를 생성할때 생성되는 두번째 매개 변수 • ex:) ! ! • response객체의 매서드 • send(); //매개변수로 있는 값을 응답 ( HTML, JSON, STATUS CODE ) • json(); // json형태로 응답 • jsonp(); // jsonp 형태로 응답 • redirect(); // 웹페이지 경로를 강제로 이동 • response.send(404, ‘<h1>ERROR</h1>’); 같이 error 전달도 가능 // STATUS CODE 는 첫번째인자 app.use(function(request, response) { response.writeHead( 200, { 'Content-Type': 'text/html' }); response.end( '<h1>Hello world</h1>' ); });
  • EXPRESS: request 객체 • request : express 모듈로 서버를 생성할때 생성되는 첫번째 매개 변수 • ex:) ! ! • request객체의 매서드 • header(); // 요청한 헤더의 속성 get /set • accepts(); // 요청한 헤더의 accept 속성 확인 • param(); // 요청한 parameters get • is(); // 요청한 헤더의 Contetn-Type 속성을 확인 • var ua = request.header( ‘User-Agent’); //userAgent 값 저장 app.use(function(request, response) { response.writeHead( 200, { 'Content-Type': 'text/html' }); response.end( '<h1>Hello world</h1>' ); });
  • EXPRESS: robust routing • express의 feature중 하나인 routing 기술은 브라우저 요청에 따라 적절한 page를 제공 하는 기술 • app.use( app.router ); // 미들웨어를 설정해줘야 함 • routing을 위해 선언해줘야 하지만, 없어도 자동으로추가된다. ( 선언 순서는 중요함 ) • https://groups.google.com/forum/#!topic/express-js/OvMo-SYMIMg • get( path, callback ); // GET 요청 • post( path, callback ); // POST 요청 • put( path, callback ); // PUT 요청 • del( path, callback ); // DELETE 요청 • all( path, callback ); // 모든 요청 • url 경로( path ) 를 지정할때는 대소문자를 구별 하지 않는다. • 전체 선택자 사용은 제일 마지막에: router 메소드를 사용한 순서대로 요청을 확인함 app.all( *, function(request, response) { response.writeHead( 200, { 'Content-Type': 'text/html' }); response.end( '<h1>Hello world</h1>' ); }); https://github.com/visionmedia/express/wiki/New- features-in-4.x app.router 4.x 에서 제거 되었음 : 사용 안해도 됨
  • express: 쿠키 & 바디 parser • express는 브라우저에서 요청한 쿠키를 추출하여 사용 할수 있음 • app.use( express.cookieParser() ); • 위 코드가 실행 되면, request 에 cookie를 저장 가능 : request.cookie • 또한 POST 요청이 올때 body 에 데이터가 저장되는데, 이때 bodyParser()가 필요 • app.use( express.bodyParser() ); • 위 코드가 실행되면, request에 body 속성이 부여: request.body
  • GET VS POST • 일반적인 입력 방식은 application/x-www-form-urlencoded 인코딩 사용 • 파일을 전송 할때는 multipart/form-data 사용 • 요청 방식과 encoding 방식은 동시 사용 • GET 방식은 데이터 조회 등에 사용 • POST 방식은 데이터 등록 등의 형식에 사용 • PUT 방식은 데이터 수정에 사용 • DELETE 방식은 데이저 삭제에 사용
  • EXPRESS: SESSION • 서버가 정보를 저장할때는 session을 이용 • session 미들웨어를 사용 하면, request.session 이 만들어짐 • session을 읽기 전에 cookieparser 가 먼저 실행 되어야 함 • app.use( express.cookieParser() ); • app.use( express.session( { secret: ‘kazikai’ } ) ); // session 생성 • 브라우저를 종료하고 다시 실행하면, 세션은 유지 되지 않음
  • 쉬어가기 : 다음 코드의 실행 횟수 var http = require('http'); var fs = require('fs'); var testNumber = 1000; function writeNumber (res) { var counter = 0; testNumber++; console.log("writeNumber function call"); for( var i = 0; i< 100; i++ ){ counter++; res.write(counter.toString() + 'n'); } console.log( "testNumber: " + testNumber ); res.write( testNumber + 'n' ); } http.createServer( function(req,res){ var query = require('url').parse(req.url).query; var app = require('querystring').parse(query).file + ".txt"; res.writeHead( 200, { 'Content-Type': 'text/plain' }); writeNumber( res ); //console.log("req.url" + req.url); fs.readFile( app, 'utf-8', function( err, data){ if( err ){ res.write( 'Could not find or open file for reading n'); } else { res.write( data ); console.log( "data: " + data ); } res.end(); }); }).listen( 9999 ); console.log( 'server runnigng at 9999'); 다음코드에서 writeNumber function call 은 몇번 출력될까? 그렇다면, localhost:9999 를 두번 접속했 을때 마지막에 나오는 숫자는? 이유는? 다음 페이지에 답
  • 쉬어가기 : 답 • 2번 : 즉 2번 요청이 온다. • url 정보에 사용하기 위한 favicon.ico 를 한번더 요청함 • 1003 이 마지막 숫자 • 1001 이 나오지만, 내부적으로 1002 가 1번실행에 됨 • 다음 요청때는 1003이 헤더에 쓰여지고, 1004로 저장됨(2번째) • 이 정보를 요청 할때 (2번째 request)는 헤더가 다시 날라오지 않는다.
  • 서버 로깅 하기 • node.js 는 로거 미들웨어를 활용 할수있다. • connect 모듈 : $ npm install connect • logger.js 작성 -> node logger.js 실행 • 브라우저를 열고 접속 : localhost:8080 • app.use( connect.logger(‘tiny’) ); 와 ‘short’ 모드가 있음 var connect = require('connect'); var app = connect(); app.use( connect.logger() ); app.use( function ( req, res ) { res.end('Hello world!'); }); app.listen(8080);
  • 멀티코어 관련 : Cluster 모듈 • var cluster = require(‘cluster’); 로 사용 가능 • 0.6 버전 부터 내장되어있으므로 따로 설치할 필요 없음 • cluster를 사용하면, 쓰레드를 나누지 않는 node.js 특성과 다르게 동작함 • 사용법 var cluster = require('cluster'); var os = require('os'); var cpu = os.cpus().length; console.log( 'CPU :', cpu ); if ( cluster.isMaster ){ for ( var i = 0; i < cpuCount; i ++ ){ console.log( 'cluster fork'); // 마스터 프로세스에서만 fork 를 사용 가능 cluster.fork(); //worker 프로세스 생성 } } else { //여기에 워커 프로세스 를 넣으면 된다. console.log( 'worker '); }
  • Node debug : console • node.js 에서 가장 기본적으로 디버깅 하기 위한 함수 • console.log • 객체를 문자열로 serialize 하여 합쳐주고 결과를 표준 출력 스트림에 출력해줌 • console.log 가 formatting 을 하는것이 아니라. util.format 함수가 수행 하는것, • 인자가 모두 util.format 에 전달된후 이 결과가 표준 출력 스트림에 출력된다. • 프로세스 출력 스트림에 대한 쓰기 작업이 blocking 작업 • 로깅이 일어나는 동안 이벤트 루프가 차단됨 • 즉 애플리케이션 및 이 함수를 사용하는 빈도가 증가 하면, 성능에 영향을 주기 때문에 배포 할 경우에는 • console.log 사용을 지양해야 함
  • Node debug : 내장debugger • console.log 를 사용 하기 어려운 경우 디버그 모드를 사용 가능 • node 내장 디버거 사용 사용방법 >> $ node debug test.js • 위와 같이 하면 메인 모듈의 첫번째 줄에서 실행이 멈춤 • 자주쓰는 커맨드 • $debug> next // 다음 상황으로 넘어간다. • $debug> step // 만약 함수안으로 들어가려면 step 을 입력 • $debug> watch(‘a’); // a라는 변수 관찰 • $debug> out //함수 안을 나갈때 • $debug> sb(‘test.js’, 8) // 8번째 라인 브레이크 =포인트 • $debug>cont // 브레이크포인트까지 빠르게 넘어갈수있다. ! • $debug> help // 포함된 모든 명령어 볼수있음
  • Node debug : node-inspector • 가장 직관적이며 FE 개발시사용하는 크롬 인스펙터를 사용 • https://github.com/node-inspector/node-inspector • 설치 : $ npm install -g node-inspector • 사용 : $ node-debug app.js • 자동으로 웹브라우저 실행된다.
  • Heroku 란? • https://www.heroku.com/ • 무료로 node.js 서버를 사용 할수있음 • node.js 를 클라우드로 설치 하여 운영 할수있는 플랫폼 • 가입 : https://dashboard.heroku.com/apps • heroku 클라이언트 다운 : heroku 커맨드를 사용 할수있음 • https://devcenter.heroku.com/categories/nodejs ( node.js 개발 가이드 문서 ) • https://devcenter.heroku.com/articles/getting-started-with-nodejs ( 다음장에 나와있는 설명 원문)
  • Heroku 설치:1 • 앞장에서 생성한 plalab 이란 폴더로 이동 ( git repository ) • web.js 파일 생성 ! ! ! ! ! ! • $ npm init : 각 정보 입력 package.json을 만들어줌 • $ npm install express logfmt — save : express와 logfmt 모듈 설치후 package.json 에 추가 • package.json 에 node engine 버전 추가 : // web.js var express = require("express"); var logfmt = require("logfmt"); var app = express(); app.use(logfmt.requestLogger()); ! app.get('/', function(req, res) { res.send('Hello World!'); }); var port = Number(process.env.PORT || 5000); app.listen(port, function() { console.log("Listening on " + port); }); { "engines": { "node": "0.10.x" } }
  • Heroku 설치:2 • root directory에 Procfile 이란 파일생성후 아래 스크립트를 추가한다. • web: node web.js • 생성한후 테스트 $ foreman start //foreman은 heroku 클라이언트를 설치할때 설치되었음 • ! • 이제는 만든 코드를 git 에 저장한다 • $ git init • $ git add . • $ git commit -m “init” //init 은 커밋 메시지 • $ heroku create // heroku 에 새로운 app을 생성 한다. • $ git push heroku master // 지금 만든 프로젝트를 heroku 저장소에 push 한다.
  • Heroku 테스트 • 이제 모든 과정 완료 • 테스트 방법 • $ heroku ps:scale web=1 // 이 방법으로 web.js 를 실행 한다. web=0 은 슬립 상태로 .. • $ heroku ps // 잘 실행 되고 있는지 체크 ! • $ heroku open // 브라우저 상에서 해당 node.js 서버가 실행되는 url을 요청 한다. • $ heroku logs // 로깅을 보여줌 • heroku 는 월 750 dyno hour 를 무료로 제공 한다. ( 31 * 24 = 754? ) 한 어플리케이션당 • dyno 는 computing power 의 개념 • 시간당 사용량으로 요금이 부과 됨 • https://devcenter.heroku.com/articles/usage-and-billing
  • 참조 • 프로페셔널 Node.js • 제대로 배우는 Node.js 프로그래밍 • 모던 웹을 위한 Node.js 프로그래밍 • http://nodejs.org/ • http://s3.amazonaws.com/four.livejournal/20091117/jsconf.pdf • http://nodejs.org/jsconf2010.pdf • Web..
  • 끝 • 감사합니다.