2017년 10월 21일 토요일

Node.js 공부[2]

2챕터

노드  간단하게 살펴보기이디.
책에서는 실행방법을 간단히 소개하고있다.

명령 프롬프트 창에서 실행하기 




브라켓의 확장 기능 NodeJS Integration 설치 후 브라켓에서 실행




노드 셸에서 직접 코드 입력하고 실행 



노드에서 사용할 수 있는 대표적인 전역 객체

console : 콘솔 창에 결과를 보여주는 객체
ex)
console.log('%d', 10); >>숫자
console.log('%s', '안녕'); >>문자열
console.log('%j', {name: '안녕'}); >>JSON객체

process : 프로세스의 실행에 대한 정보를 다루는 객체

exports : 모듈을 다루는 객체

**JSON 이란??
자바스크립트의 객체 포맷으로 단말끼리 데이터를 주고받을 때 많이 사용함.
중괄호{}를 이용해 객체를 만들 수 있으며, 그 안에 key와 value 으로 구성된 속성들은 ,로 구분함. 

JSON 참조
http://boramjeong.com/140199144589
http://www.json.org/json-ko.html
https://ko.wikipedia.org/wiki/JSON


이 3개에 대해 예제를 통해 보자 

콘솔 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var result = 0;
console.time('duration_sum'); //time 실행 시간을 측정하기 위한 시간을 기록
for(var i =1; i<=10000; i++){
    result +=1;
}
console.timeEnd('duration_sum'); //timeEnd 실행시간을 측정하기 위한 끝시간 기록
console.log('결과물은: %d', result);
console.log('현재 실행한 파일의 이름: %s', __filename); //실행한 파일의 이름을 출력, 파일의 전체 패스가 출력됨
console.log('현재 실행한 파일의 패스: %s', __dirname); //실행한 파일이 들어 있는 폴더를 출력, 폴더 전체의 패스가 출력됨
var Person = {name:"소녀시대", age:20};
console.dir(Person);
//ㅎㅇ
cs

예제 실행 결과 


프로세스 객체 예제

process 객체는 프로그램을 실행했을 때 만들어지는 프로세스 정보를 다루는 객체이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
console.log('argv 속성의 파라미 수:' + process.argv.length);
//argv : 프로세스를 실행할 때 전달되는 파라미터(매개변수) 정보
console.dir(process.argv);
if(process.argv.length > 2){
    console.log('세 번째 파라미터의 값 :S', process.argv[2]);    
}
process.argv.forEach(function(item, index){
console.log(index+':', item);
});
console.dir(process.env);
//env : 환경 변수 정보 
//exit() : 프로세스를 끝내는 메소드
cs

결과

port 와 7001 를 추가하여 실행해본 결과이다. 
argv는 배열 객체이므로 인덱스 2를 사용하면 세번째 파라미터 값을 알 수 있다.
forEach문을 실행한 결과를 보면 port와 7001이 추가되어 출력되는 것을 볼 수 있다. 
추가 안해줬을때는 0,1 번만 출력됨을 알 수 있다. 


Exports / 모듈 예제

모듈을 통해 기능을 나누어 프로그램을 관리할 수 있다. 
이때 exports 객체의 속성으로 변수나 함수를 지정하면 그 속성을 다른 곳에서 불러와 사용할 수 있다. 

2가지형태로 불러올 수 있다.
1
2
3
4
5
6
//exports.함수 형태
exports.add = function(a,b){
    return a+ b;
}
cs
1
2
3
4
5
6
7
8
9
10
11
//module.exports형태
var calc ={};
calc.add = function(a,b){
    return a+b;
};
module.exports = calc;
cs

1
2
3
4
5
6
7
8
9
10
11
//exports.함수 호출
var calc = require('./calc');
console.log('모듈로 분리한 후 - calc 함수 호출 결과 : %d', calc.add(10,10));
//module.exports 호출 
var calc2 = require('./calc2');
console.log('모듈로 분리한 후 - calc2.add 함수 호출 결괴: %d', calc2.add(1010));
cs

실행 결과


외장 모듈 사용하기 

다른 사람이 만들어 놓은 모듈을 불러와 사용할 수 있다. 
책에선 시스템 환경 변수에 접근할 수 있는 nconf를 사용한다. 
모듈은 npm패키지를 사용하여 다운로드 할 수 있다. 

npm을 사용하여 nconf 패키지 설치 
경로에 보면 node_modules 라는 폴더가 생성되었다. 

그 후 
1
2
3
4
var nconf = require('nconf');
nconf.env();
console.log('OS 환경 변수의 값 : %s' , nconf.get('OS'));
cs
실행 시 정상적으로 작동한다.(패키지 설치전에는 nconf 모듈을 찾을 수 없다고 뜬다)



하지만 설치한 노드모듈은 이 프로젝트 폴더 내에서만 작동하므로, 이 폴더를 상위로 옮기면 모든 프로젝트에 적용가능하다. 

만약 다른 프로젝트나 PC에서 자신이 만든 프로그램을 실행하려할때 외부 패키지가 많다면 일일히 다시 설치해야할 것이다. 
노드에서는 외부 패키지의 수만큼 npm명령을 입력해야하는 번거로움을 없앨 수 있도록 package.json파일 안에 패키지들의 정보를 넣어둘 수 있다.

예제 폴더에 package.json을 만드려면 해당 폴더 경로에서 npm init 실행 후 name:질문에 node라 입력 후 엔터를 계속 입력하면 생성된다. name에는 영문 소문자이면 된다고 한다. 

package.json 이후 패키지 설치할때는 npm install ㅁㅁ --save 를  하면된다.
dependencies 속성에서 설치된 것을 볼 수 있다. 

이 모듈들을 다른 곳에서 사용하고 싶을때는 package.json파일을 옮긴 후 npm install 명령을 입력하면 dependencies 속성을 참조하여 패키지들이 설치된다. 


내장 모듈 사용하기

노드를 설치했을 때 기본적으로 들어 있는 몇가지 내장모듈에 대해 간단히 살펴본다.
https://nodejs.org/api/ 에서 내장 모듈에 대한 정보를 찾을 수 있다.

책에서는 os와 path 모듈에 대한 예제가 나와있다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//시스템 정보를 알려주는 os모듈
var os = require('os'); 
//파일 패스를 다루는 path 모듈
var path = require('path');
console.log('시스템의 hostname : %s', os.hostname());
//hostname():운영체제의 호스트 이름을 알려준다.
console.log('시스템의 메모리: %d / %d', os.freemem(), os.totalmem());
//freemem(): 시스템에서 사용가능한 메모리 용량을 알려준다. 
//totalmem(): 시스템의 전체 메모리 용량을 알려준다.
console.log('시스템의 CPU 정보\n');
console.dir(os.cpus());
//cpus(): CPU정보를 알려준다
console.log('시스템의 네트워크 인터페이스 정보\n');
console.dir(os.networkInterfaces());
//networkInterfaces(): 네트워크 인터페이스 정보를 담은 배열 객체를 반환함
//디렉터리 이름 합치기
var directories = ["users""mikes""docs"];
var docsDirectory = directories.join(path.sep);
//join() : 여러개의 이름들을 모두 합쳐 하나의 파일패스로 만들어 준다. 파일 패스를 완성 할때 구분자 등을 알아서 조정해준다.
console.log('문서 디렉토리 : %s', docsDirectory);
//디렉터리 이름과 파일 이름 합치기 
var curPath = path.join('/Users/mike''notepad.exe');
console.log('파일 패스 : %s', curPath);
//패승에서 디렉터리, 파일 이름, 확장 구별하기
var filename="C:\\Users\\mike\\notepad.exe";
var dirname = path.dirname(filename);
//dirname(): 파일 패스에서 디렉터리 이름을 반환한다. 
var basename = path.basename(filename);
//basename(): 파일 패스에서 이름을 반환한다.
var extname = path.extname(filename);
//extname(): 파일 패스에서 파일의 확장자를 반환한다. 
console.log('디렉터리 : %s, 파일 이름: %s, 확장자: %s', dirname, basename, extname);
cs


4챕터부터 미션이 생기니 3챕터까지는 빠르게 해야할 것 같다.

ajax 예제(cot에서 쓰인 부분 정리)

커뮤니티 페이지(Cot)에서 ajax를 쓴 부분을 정리


게시물 조회시 댓글을 ajax방식으로 호출 했다.
1
2
3
4
5
6
7
8
9
10
11
//게시물 조회시 댓글 호출    
function listReply() {
        $.ajax({
            type : "get",
            url : "${path}/freereply/list.do?bnum=${dto.bnum}",
            success : function(result) {
                // responseText가 result에 저장됨.
                $("#listReply").html(result);
            }
        });
    }
cs

type은 통신 타입이다. POST 또는 GET을 선택할 수 있다.
url은 요청할 url로 글번호(bnum)에 맞는 댓글들을 불러오는 컨트롤러로 연결된다.
success는 성공적으로 요청/응답이 되면 listReply 부분에 결과를 html형식으로 표시한다.
해당 jsp에서는 

<!-- 댓글 목록 위치 -->
<div id="listReply"></div>

으로 댓글 목록을 위치시켰다.



댓글 수정화면 댓글의 댓글 창또한 ajax를 이용해 새로고침 없이 창을 보이게 하였다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 댓글 수정화면 생성 
function showReplyModify(rnum) {
    $.ajax({
        type : "get",
        url : "${path}/freereply/detail/" + rnum,
        success : function(result) {
            $("#modifyReply").html(result);
            // 태그.css("속성", "값")
            $("#modifyReply").css("visibility""visible");
        }
    })
}
// 댓글의  코멘트 생성 
function showReplyComment(rnum) {
    $.ajax({
        type : "get",
        url : "${path}/freereply/commentwrite/" + rnum,
        success : function(result) {
            $("#ReplyComment").html(result);
            // 태그.css("속성", "값")
            $("#ReplyComment").css("visibility""visible");
        }
    })
}
cs
형태는 위와 비슷하다. 


로그인을 사이드 메뉴에서 구현하였다. 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function signin() {
            if($("#user_id").val()==""){
                alert("아이디를 입력해주세요.");
                $("#user_id").focus();
                }else if($("#password").val() ==""){
                    alert("비밀번호를 입력해주세요");
                    $("#password").focus();
                    
                    }else{
            $.ajax({
                url : './j_spring_security_check',
                data : $('form input').serialize(),
                type : 'POST',
                dataType : 'json',
               
            }).done(function(body) {
                var message = body.response.message;
                var error = body.response.error;
                if (error)
                    get_msg(message);
                if (error == false) {
                    var url = '${referer}';
                    if (url == '')
                        url = '<c:url value="/users/mypage" />';
                    location.href = url;
                }
            });
         }
        }
cs
앞의 if문은 아이디 비밀번호 체크이므로, ajax부터 본다면, 

data는 서버에 요청시 보낼 파라미터이다.
dataType은 응답 받을 데이터 타입을 선택한다.(XML, TEXT, HTML, JSON 등) 

아까랑 다르게 success가 아닌 done인데 같은의미인데 순서가 다른 것 같다.
검색해보니 success error 보다는 done fail 패턴이 동일한 요청에 대해 여러 성공 콜백을 호출할 때 함수 배열을 통해 더 깔끔?하게 처리해서 최근 done이 많이 쓰이는 것 같다...


beforesend에 대해서도 찾아볼 것 

2017년 10월 20일 금요일

Node.js 공부[1]

예전에 조금했던 Do it node.js 책을 다시 공부시작!

이번엔 제대로 정리해보면서 한 게시글에 1챕터씩 정리!

노드 정리 블로그가 많으니 찾아보면서 하자
http://asfirstalways.tistory.com/43

1챕터

노드(Node.js)는 자바스크립트를 이용해서 서버를 만들 수 있는 개발 도구


노드는 왜 만들게 되었는가??

웹 서버에 파일을 업로드할 때, 업로드가 완료되기 전까지 웹 서버에서 데이터를 조회한다거나 하는 등의 작업을 할 수 없었는데, 이 문제를 해결하기 위해 만든 것
>> 비동기 입출력(논블록킹 입출력, Non-Blocking IO)방식 적용


동기 입출력 방식 vs 비동기 입출력 방식 비교
참고 ,,다시 정리 할것 

모듈이란?

필요한 기능을 별도의 자바스크립트로 만든 후 필요할 때 불러와서 사용할 수 있음

>>이 여러 개의 모듈을 합쳐서 하나의 패키지로 만들어 두면, 다른 프로그래머들도 npm을 통해 쉽게 설치하여 사용할 수 있음
npm(Node Package Manager)


노드 특징

V8엔진
자바스크립트는 코드를 한 줄씩 해석하면서 실행하는 인터프리터 방식을 사용하여 속도가 느려 문제가 되었지만, 구글(크롬)의 V8엔진으로 해결
>>V8엔진은 자바스크립트 코드를 네이티브 코드로 바꾼 후 실행할 수 있는데, 노드는 V8엔진을 이용해 자바스크립트 코드를 빠르게 실행할 수 있음

이벤트 기반 방식
입력장치로 데이터를 전송했을때만 작동하는 방식
자원 최소화 가능?

Non-Blocking
비동기 참조

Single Thread

개발 도구

책에서는 브라켓과 크롬을 사용한다.  [2]부턴 직접 써볼듯?

2017년 10월 16일 월요일

TDD이란? / Junit 연습. 예제

먼저 테스트 주도 개발(TDD, Test Driven Development)란??

-설계 이후 코드 개발 및 테스트 케이스를 작성하는 기존의 개발 프로세스와 다르게 테스트 케이스를 작성한 후 실제 코드를 개발하여 리펙토링 하는 절차

[기존]


[TDD]

TDD장점은?

-작업과 동시에 테스트를 진행함으로써 실시간으로 오류를 파악할 수 있음
-짧은 개발주기를 통해 고객의 요구사항을 빠르게 수용하거나 피드백을 줄 수 있고, 현재 상황을 쉽게 파악할 수 있음
-자동화 도구를 이용해 TDD의 테스트 케이스를 단위테스트로 사용가능
[JUnit, cppUnit, NUnit 등]


단점은? 

-기존의 개발 프로세스에 테스트 케이스 설계까지 추가되므로 코드 생산 비용이 높아짐

>>하지만 객체지향적인 코딩 능력을 향상시킬 수 있다고 한다. 



////////////////////////////////////////////////////////////////

<Junit을 이용한 기본테스트>

간단한 계산기 자바 코드가 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.net.mypage;
public class Calculator {
    int add(int i, int j){
        return i+j;
    }
    
    int subtract(int i, int j){
        return i- j;
    }
    
    int multiply(int i, int j){
        return i*j;
        
    }
    
}
cs
이것을 테스트하려면 상단 메뉴의 New Java Class 부분의 JUnit Test case를 생성하면 된다. 


그 후 이렇게 코드 작성 후 Run As 부분의 JUnit test를 통해 테스트 가능하다 .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.net.mypage;
import static org.junit.Assert.*;
import org.junit.Test;
public class CalculatorTest {
    
    @Test
    public void add() {
        Calculator cal = new Calculator();
        int res = cal.add(24);
        //과거 였으면 sys.out으로 확인했겠지만 junit은 assert를 통해 (기대하는 값, 결과 값) 으로 확인할 수 있음 
        assertEquals(6, res);
        
    }
    
}
테스트 성공시 이런 화면이 보이고 실패시 failures 부분에 숫자가 올라간다.



<테스트 독립성>

Before와 after 어노테이션을 통해 test메소드 실행하기 전과 후 처리를 해줄 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.net.mypage;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class CalculatorTest {
    private Calculator cal;
    
    
    //before를 통해 test 메소드가 실행될때마다 setup이라는 메소드가 호출됨  cal 초기화 작업을 매번함 (선 처리 작업)
    @Before 
    public void setup(){
        cal = new Calculator();
        System.out.println("setup");
    }
    
    
    @Test
    public void add() {
        
        assertEquals(8, cal.add(17));
        System.out.println("add!");
    }
    
    @Test
    public void mul() {
        
        assertEquals(8, cal.multiply(18));
        System.out.println("multiply");
    }
    //after는 test메소드 실행 후 실행됨 (후처리 작업) >>before와 after를 통해 테스트 독립성 제공 
    @After
    public void after(){
        System.out.println("after");
    }
    
    
}
cs


콘솔창으로 보는 메소드 실행 순서

Test메소드 실행하기 전 Before가 선언된 setup메소드 실행 > test 실행 > after 실행
두번째 test 실행하기 전 다시 before 실행 > test 실행 > after 실행