[Info]Tags categorized posts and contents patterns..

[AJAX] Ajax Code E xamples.. [Book] About the book.. [CSS] CSS Code E xamples.. [DB] Sql Code E xamples.. [DEV] All development stor...

레이블이 JS인 게시물을 표시합니다. 모든 게시물 표시
레이블이 JS인 게시물을 표시합니다. 모든 게시물 표시

2017년 7월 18일 화요일

[JS] Requirify 크롬 익스텐션..


출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

웹 프론트를 개발하다 보면 다른 사이트의 소스를 볼 일이 많이 있다. 어떻게 동작하는지 보려고 하거나 구조를 좀 파악해 보려는 등 여러 가지 상황이 있는데 크롬 개발자 도구 등이 과거보다 무척 좋아졌지만, 콘솔에서 자바스크립트를 실행시켜 보는 경우가 많다. 이런 경우 보통 자신이 익숙한 라이브러리의 소스가 편한데 예를 들어 DOM을 탐색할 때 나는 jQuery 로 쓰는 게 편하지만 다른 사이트를 탐색하에는 jQuery 가 없는 경우도 많아서 네이티브 DOM 쿼리를 사용해야 하는 불편함이 있다. 이런 경우를 위해서 나는 jQuerify라는 크롬 익스텐션을 사용해서 크롬 개발자도구에서 jQuery를 쓰고 있다.(jQuerify는 알아서 충돌나지 않도록 $, $j, $$등으로 사이트에 jQuery를 넣어준다.)

Requirify

Requirify는 Node.js의 require()문법을 사용해서 동적으로 라이브러리를 로딩하는 크롬 익스텐션이다. Requirify를 만든 Matthew Conlen개발문서를 보면 RequireBin에 영감을 받았다고 나와 있고 browserify에 기반을 두고 있다.
최근에 내 주위에 browserify를 쓰는 사람이 늘어나고 있는데 난 아직은 Bower를 주로 사용하고 있어서 자세히 설명하기는 어렵지만 browserify는 npm 모듈을 이용해서 의존성 관리를 하고 브라우저에서 실행할 수 있게 하여 주는 도구이다. 브라우저에서도 Node.js처럼 require();문법으로 의존성을 명시하고 browserify를 이용해서 이를 하나의 파일로 빌드할 수 있게 하는 도구다. Requirefy는 이 메커니즘을 사용한 크롬 익스텐션으로 크롬 개발자도구에서 동적으로 필요한 라이브러리를 로딩한다.


크롬 개발자도구 콘솔에서 Requirify로 라이브러리 로드하기

위 화면에서 보듯이 사이트를 디버깅할 때 lodash가 필요하다면 require('lodash')를 실행하면 browserify-cdn에서 해당 라이브러리를 가져온다. Finished getting lodash라는 문구가 출력되면 해당 사이트에서 정상적으로 lodash를 사용할 수 있다. 다른 사이트의 소스를 보거나 크롬 개발자 도구에서 간단히 라이브러리의 API를 테스트해 보려고 할 때 굳이 HTML 페이지를 따로 만들 필요없이 편하게 사용할 수 있다.

다만 아직 초기 버전이라서 HTTPS를 지원하지 않아서 현재 사이트가 HTTPS라면 Content Security Policy를 위배하기 때문에 라이브러리가 로딩되지 않는다. 이는 현재 이슈로 등록되어 있지만, 아직 해결되지는 않았고 requirefy가 사용하는 browerify-cdn이 아직 HTTPS를 지원하지 않기 때문에 다른 CDN에서 가져오도록 만들거나 browerify-cdn이 HTTPS를 지원해야 해결될 것 같다.

2017년 6월 21일 수요일

[JS] Plato : 자바스크립트 정적분석 도구..


출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

개발할 때 코드의 품질을 관리하는 방법에는 여러 가지가 있다. 품질을 관리하고 개선을 하려면 이전과 비교를 해야 하기 때문에 어떤 정량적인 평가가 필요하다. 이런 정량적인 수치를 회사에서 평가의 기준으로 삼기 때문에 보통 거부감이 많은데(물론 나도 그렇다) 개발자 스스로 소스코드의 품질을 관리하려면 이번 부분에도 신경을 써야 한다고 생각한다. 예를 들어 코드 커버리지같은 경우 평가의 기준이 되어서 모든 코드를 한 번씩 돌려서 커버리지 자체를 80, 90%로 올려버리는 것은 어렵지 않은 일이다. 물론 테스트가 잘 된 코드는 커버리지가 당연히 높겠지만 커버리지가 높다고 테스트가 잘 되었다고 볼 수는 없다. 그래서 커버리지 수치 자체가 중요하다기 보다는 커버리지 측정을 통해서 중요한 부분인데 테스트가 제대로 안 된 곳은 없는지 확인하는 용도로 하는 것이 더 맞는다고 본다.

Plato

plato는 JavaScript 코드를 정적 분석 해서 프로젝트의 복잡도나 유지 보수성을 보여주는 도구이다. 다른 서버 측 언어들에 비해(특히 컴파일언어) 자바스크립트는 이런 쪽의 환경이 많이 부족한 편인데 최근에는 많은 시도가 이뤄지고 괜찮은 프로젝트가 많이 나와서 여러모로 편해진 상황이다. 일단 plato 프로젝트에서 제공하는 jQueryMarionette의 예시를 보자.


Plato의 프로젝트 정적분석 통계

예시라서 여러 날짜의 기록이 그래프로 나오는데 처음 실행해서 분석하면 당연히 하나만 나타난다. Summary에서는 SLOC(source line of code)의 통계와 유지 보수성의 상대수치를 볼 수 있다. 유지 보수성은 100점 만점으로 숫자가 높을수록 유지 보수성이 좋다는 의미인데 정확한 평가 기준은 아직 모르겠다. Maintainability 부분에서는 앞의 전체 평균으로 나왔던 유지 보수성을 파일별로 볼 수가 있고 Lines of code에서는 파일별 SLOC를 한눈에 파악할 수 있다.


프로젝트의 파일별 정적분석 통계

하단의 Files에서는 파일별로 복잡도, JSHint의 Lint 오류, Estimated errors, sloc를 종류별로 정렬해서 볼 수 있다. 소스코드의 복잡도는 Phil Booth의 complexity-report를 사용하고 있다.


파일별 상세 정적분석 통계

각 파일을 클릭하면 파일별로 좀 더 자세한 내용을 볼 수 있고 컴파일언어에 비할 정도는 아니지만, 복잡도가 높은 부분 등에 표시도 해줘서 코드를 개선할 때 참고할 수 있다.

사용방법

npm install -g plato로 plato를 전역 설치를 하면 plato 명령어를 사용할 수 있다.

1
2
3
Bash

plato -r -d reports src1

프로젝트 폴더에서 위처럼 실행하면 된다. -r은 재귀옵션으로 소스 폴더의 하위 폴더를 순회하게 되고 -d reports는 결과 리포트를 만들 디렉터리로 필수값이다. 마지막은 분석할 디렉터리를 지정하면 된다. 웹 브라우저에서 볼 수 있는 HTML 파일 뿐만 아니라 JSON 파일도 함께 생성하기 때문에 직접 HTML 파일을 서버에 띄우지 않더라도 다른 도구에 연동에서 분석 결과를 보여줄 수 있다. 그리고 실행할 때마다 새로 만들어지는 것이 아니라 실행 시점마다 스냅 샷처럼 기존 파일에 추가되기 때문에 정기적으로 실행하면 프로젝트를 개선하는 통계를 추적해서 볼 수 있다.


grunt-plato

grunt-plato는 plato를 Grunt에서 사용할 수 있는 플러그인이다. 나는 주로 Grunt로 프론트앤드를 빌드하는데 Grunt에 연결하면 간단한 명령어로 원하는 설정에 따라 프로젝트를 분석할 수 있고 CI 등에서 자동화 하기도 쉬우므로 쉘에서 직접 사용하는 것보다 빌드도구에 연결해 놓으면 편하다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
JavaScript

  plato: {
    options: {
      jshint: grunt.file.readJSON('.jshintrc')
    },
    task: {
      files: {
        'reports/': ['src/**/*.js']
      }
    }
  }

다른 Grunt 플러그인처럼 옵션을 주고 리포트를 만들 디렉터리와 대상 파일을 지정하면 된다. 이외에도 복잡도에 대한 옵션이나 제외할 파일의 설정 등을 옵션으로 줄 수 있다. 전체적인 상황은 볼 수 있지만 다른 컴파일언어에 비하면 아주 강력하다고는 할 수 없지만, 프로젝트의 전체 상태를 지속해서 볼 수 있고(상당히 깔끔하게 보여주기도 하고) 코드를 개선할 때 참고할 수 있다는 점에서는 사용해볼 만하다.

My Commnet..
나도 자바스크립트를 자주 사용하게 되는 웹쪽의 일을 하고 있긴 하지만 이런 도구를 사용해서 분석을 하거나 할 생각은 전혀 못하고 있었다.. 역시나 이번에도 새롭게 알고 배우고 간다.. 

2017년 3월 8일 수요일

[JS] 크롬 개발자도구의 콘솔을 차단하는 방법..


출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

트위터에서 올라온 링크로 보게 된 Stackoverflow의 글을 보고 트위터에 올렸더니 꽤 많은 리트윗이 일어나서 블로그에도 한번 정리해 둔다. 윗글에 자세한 내용이 나오긴 하지만 정리하자면 이렇다.[트위터 글인데 별도로 가져오지 못해서 해당 부분은 취소처리한다..] 어떤 사람이 페이스북에 들어갔더니 크롬에서 콘솔을 사용할 수 없게 막혀있는데 어떻게 막은 거냐 하는 질문이고 여기에 페이스북의 보안 엔지니어라는 사람이 나타나서 사용자가 콘솔을 이용해서 공격할 수 있는지 테스트하느라고 일부 사용자에게 적용되었던 거라고 답변을 달았다.

1
2
3
4
5
JavaScript

with ((console && console._commandLineAPI) || {}) {
  // code here
}

크롬의 콘솔은 위의 코드로 모두 감싸아져 있으므로 여기서 console._commandLineAPI 를 재정의해서 오류를 던지도록 하면 사용자가 크롬에서의 개발자도구로 콘솔을 사용할 수 없게 할 수 있다.

1
2
3
JavaScript

Object.defineProperty(console, '_commandLineAPI', { get : function() { throw '콘솔을 사용할  없습니다.' } });

웹페이지에서 위 코드를 추가하면 해당 페이지에서 크롬 콘솔을 사용하면 다음과 같이 오류가 난다. 콘솔에서 코드를 사용하면 다 오류가 발생하고 자동완성도 동작하지 않는다. 물론 이 코드는 위의 크롬 콘솔이 코드를 감싸는 구조를 이용한 것이므로 페이지의 자바스크립트로 삽입해야지 크롬 콘솔에서 위 코드를 입력한다고 콘솔이 차단되지 않는다. 위의 Object.defineProperty()는 ES5에 들어간 객체의 프로퍼티를 다루는 API다.


위의 코드를 추가하고 크롬 콘솔을 사용한 화면

글을 쓴 김에 이 글에서 흥미로운 점이 있는데 페이스북의 개발자가 직접 나타나서 답변을 달았다는 점이다. 우리나라였으면 어땠을까 왠지 저런 내용을 공개적으로 쓰려면 회사의 허락을 받아야 될 것 같은 불안감도 있고 보고를 하면 아마도 나중에 가치가 있을지도 모르는 잠재력 있는 스킬일지도 모르니 공개하지 말라고 할 것 같다.(대부분은 자체검열로 답변을 안 달겠지.) 그리고 이 코드를 사용한 발단이 된 Self-XSS 공격도 한 번씩 보면 흥미롭다. 이런 공격은 취약점이라고 하기도 그렇고 참...

마지막으로 윗글의 답변에 나온 대로 보안 공격을 클라이언트에서 차단하려는 접근은 좋지 않은 방법이다. 어차피 우회하려고 맘먹으면 얼마든지 우회할 수 있으므로 보안이라는 의미도 그다지 없다. 왠지 이런 코드가 한때 국내 웹사이트의 기본처럼 되었던 "우클릭 방지"나 "텍스트 복사할 때 강제 출처 추가" 처럼 오용되지 않을까 하는 노파심에 그냥 이런 것도 가능하구나! 정도로 봐주시길...

My Comment..
해당 글은 햄의 말처럼.. 아 이런것도 있구나 하는 정도로 나 스스로도 참고용으로..?? 가져온 글이다.. ㅎㅎ

2017년 1월 20일 금요일

[JS] JSHint의 옵션 정리..


출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

JSHint는 자바스크립트 코드 검사도구이다. 컴파일언어가 아니다 보니 오류를 줄이거나 스타일 가이드를 위해서 이런 도구를 보통 사용하는데 이런 작업을 보통 Linting이라고 한다. 과거에는 더글라스 크록포드가 만든 JSLint를 대부분 쓰고 있었지만 JSLint가 현실에 맞지 않게 너무 엄격해서 JSHint가 등장하고 다른 Linting도구들이 많이 있지만, 일반적으로 JSHint를 가장 많이 쓰는 걸로 보인다.

자바스크립트를 사용할 때 거의 JSHint로 코드검사를 하고 있지만, 막상 필요할 때 그때그때 찾아서 해 버릇해서 딱 정해진 옵션을 가지고 있지도 않았고 잘 모르는 옵션이나 사용하는 옵션이더라도 어떤 내용을 검사해주는지 헷갈리는 경우가 많았다. 이는 이전의 JSHint의 문서화가 그렇게 좋지 못했던 이유도 있었는데 지금은 문서화도 어느 정도 되어 있고 매번 쓰다 보니 한번 정리해야 할 필요가 있다고 생각되어 옵션들을 정리해봤다. 간단히 어떤 옵션인지 내가 알아볼 수 있는 수준으로만 정리했으니 자세한 내용은 JSHint 문서를 참고하면 되고 좀 더 자세한 예제코드는 JSHint의 테스트코드에서 볼 수 있다.

금지(Enforcing) 옵션

아래의 옵션을 true나 특정 값으로 설정하면 JSHint가 해당 내용을 검사해서 더 많은 오류를 알려준다. (옵션을 지정하지 않으면 false로 설정한 것과 같다.)
  • bitwise: ^(XOR), | 같은 bit연산자를 금지한다.
  • camelcase: 변수를 카멜케이스(혹은 UPPER_CASE)로 강제한다(이름은 카멜케이스이지만 var testvar Test모두 가능하다.)
  • curly: if 문이나 while 문 등 중괄호({})를 생략해도 되는 곳에서 중괄호를 강제한다.
  • eqeqeq: 비교문에서 == != 대신 === !== 를 사용하도록 강제한다.
  • es3: 구형브라우저를 위해서 es3 명세를 사용한 경우에 필요하다.
  • forin: for-in 루프를 사용할 때 반드시 필터링을 사용하도록 강제한다. for (var key in obj) 식의 루프에서 프로토타입 체인을 사용한 키를 다 순회하므로 일반적으로 if (obj.hasOwnProperty(key)) {} 같은 조건문을 두는데 이러한 필터링이 없을 경우(꼭 hasOwnProperty여야 하는 건 아니다.) 오류가 나오도록 한다. (루프문안에 다른 실행문이 없으면 무시한다.)
  • freeze: Array, Date, String 같은 네이티브 객체의 프로토타입을 덮어쓸 수 없도록 막는다. Array.prototype.count = function() { }; 와 같이 사용하는 경우 오류 메시지가 나온다.
  • immed: var a = function() {}(); 와 같이 함수를 바로 실행하는 경우 함수를 괄호로 감싸도록 강제한다. 이는 가독성을 높이기 위함이다.
  • indent: 들여쓰기 크기를 정하고 숫자로 지정한다.
  • latedef: 변수를 사용하는 하는 부분 뒤에 정의하는 것을 금지한다. 자바스크립트는 hoisting 때문에 같은 스코프에서 나중에 선언된 변수를 앞에서 사용할 수 있는데 이 부분을 차단한다는 의미이다.
  • newcap: new로 생성자 함수를 사용할 때 대분자로 시작하도록 강제한다. new animal(); 대신 new Animal(); 와 같이 사용해야 한다.
  • noarg: 최적화가 어려워 폐기될 예정인 arguments.caller arguments.callee 의 사용을 막는다.
  • noempty: for (var i=0;i < 10;i++) { } 와 같이 for문 등에서 빈 블록을 금지한다.
  • nonew: new Animal(); 같은 생성자함수의 실행결과를 다른 변수 등에 할당하지 않고는 사용할 수 없게 한다.
  • plusplus: ++, -- 같은 단항연산자를 금지한다.
  • quotmark: 문자열 등에 사용하는 따옴표의 스타일을 강제한다. true 로 지정하면 쌍따옴표, 홑따옴표를 모두 쓸 수 있지만 섞어서 사용할 경우 오류가 나고 single 은 홑따옴표 double 는 쌍따옴표를 강제한다.
  • undef: 선언되지 않은 변수를 사용하면 오류가 발생한다.
  • unused: 변수를 선언하고 사용하지 않으면 오류가 발생한다.
  • strict: 함수에 ECMAScript 5의 strict mode를 강제한다. 이 옵션은 함수범위에만 강제하고 전역 strict mode는 허용하지 않는다.
  • trailing: 라인 끝에 불필요한 공백문자가 들어가면 오류가 발생한다.
  • maxparams: 값을 숫자로 지정하고 함수에서 파라미터의 최대 개수를 지정한다.
  • maxdepth: 제어문의 최대 중첩개수를 지정한다.
  • maxstatements: 한 함수내의 사용할 수 있는 최대 스테이트먼트 개수를 지정한다.
  • maxcomplexity: 코드의 사이클매틱 복잡도(cyclomatic complexity)를 지정한다.
  • maxlen: 한 라인의 최대 길이를 지정한다.

완화(Relaxing) 옵션

아래 옵션을 true 로 설정하면 더 적은 오류를 보여준다.
  • asi: 세미콜론이 빠졌을 때 발생하는 오류를 보여주지 않는다.
  • boss: if (a = 1) 처럼 비교문이 와야 할 곳에 할당문이 올 때 발생하는 오류를 보여주지 않는다.
  • debug: debugger; 문을 코드에 사용했을 때 발생하는 오류를 보여주지 않는다.
  • eqnull: == null 비교에 대한 오류를 보여주지 않는다.
  • esnext: ECMAScript 6 문법을 사용을 허용한다.
  • evil: eval 을 사용했을 때 발생하는 오류를 보여주지 않는다.
  • expr: 함수 호출이나 할당문이 아닌 표현식에 대한 오류를 보여주지 않는다. 주로 테스트에서 true.should.be.ok; 같은 표현식을 사용할 때 필요하다.
  • funcscope: if (true) { var a = 1; } 처럼 제어문 내에서 변수를 정의하는 경우 발생하는 오류를 보여주지 않는다. 자바스크립트는 펑션스코프를 사용하므로 동작에는 이상이 없지만, 오류를 발생할 여지가 있으므로 이 방법을 권장하지 않는다.
  • globalstrict: ECMAScript 5의 strict mode를 전역으로 사용하는 것을 허용한다.
  • iterator: __iterator__ 프로퍼티 사용에 대한 오류를 보여주지 않는다.
  • lastsemic: 한 줄짜리 블록에서 마지막 세미콜론이 빠진 경우에만 오류를 보여주고 블록 내부 등에서 세미콜론을 사용하지 않은 경우에는 오류를 보여주지 않는다.
  • laxbreak: 코드에서 안전하지 않은 줄 바꿈에 대한 오류를 보여주지 않는다. 이 오류는 콤마를 앞에 쓰는 형식에 대한 오류도 보여주지 않는데 이 경우에는 laxcomma를 사용해야 한다.
  • laxcomma: 객체 리터럴등에서 콤마를 앞에(마지막이 아니라) 쓰는 형식을 허용한다.
  • loopfunc: 루프 안에서 함수를 정의하는 경우 발생하는 오류를 보여주지 않는다.
  • moz: 모질라의 자바스크립트 확장 문법(JavaScript 1.7)을 사용하도록 허용한다.
  • multistr: \를 사용해서 문자열을 여러 라인에 걸쳐서 사용하는 경우 발생하는 오류를 보여주지 않는다.
  • notypeof: typeof 의 값을 비교할 때 typeof 의 값이 아닌 값과 비교하는 경우 발생하는 오류를 보여주지 않는다.
  • proto: __proto__ 프로퍼티 사용에 대한 오류를 보여주지 않는다.
  • scripturl: <a href="javascript:"> 처럼 스크립트를 타켓으로 한 URL(javascript:)에 대한 오류를 보여주지 않는다.
  • smarttabs: 탭과 스페이스를 섞어서 사용하는 경우 발생하는 오류를 보여주지 않는다.
  • shadow: 이미 선언된 변수를 재선언해서 발생하는 variable shadowing에 대한 오류를 보여주지 않는다.
  • sub: obj['key'] 대신 .을 사용하는 표기법을 권장하는 오류를 보여주지 않는다.
  • supernew: new function () {} new Object; 처럼 잘못 작성했을 가능성이 있는 생성자에 대한 오류를 보여주지 않는다.
  • validthis: strict 모드로 동작할 때 생성자가 아닌 함수에서 this를 사용하는 것에 대한 오류를 보여주지 않는다.

환경

아래 옵션을 JSHint가 전역 변수들을 미리 정의하도록 한다.
  • browser: 최신 브라우저들의 document, navigator 같은 전역 변수를 정의한다. 이 옵션은 console, alert 은 노출하지 않는다.
  • couch: CouchDB의 전역변수를 정의한다.
  • devel: console, alert 등 개발용으로 사용하는 전역 변수/객체를 정의한다.
  • dojo: Dojo의 전역변수를 정의한다.
  • jquery: jQuery의 전역변수를 정의한다.
  • mootools: MooTools의 전역변수를 정의한다.
  • node: Node.js환경에 맞도록 브라우저 환경에만 어울리는 오류는 무시하고 Node.js에 맞는 전역변수를 정의한다.
  • nonstandard: escapeunescape처럼 표준은 아니지만, 범용적으로 쓰이는 전역변수를 정의한다.
  • phantom: PhantomJS에서 동작하는 환경에 맞는 전역변수를 정의한다.
  • prototypejs: Prototype의 전역변수를 정의한다.
  • rhino: Rhino 환경에 맞는 전역변수를 정의한다.
  • worker: Web Worker 환경에 맞는 전역변수를 정의한다.
  • wsh: Windows ScriptHost 환경에 맞는 전역변수를 정의한다.
  • yui: YUI의 전역변수를 정의한다.

레거시 옵션

아래 옵션들은 폐기되어서 앞으로는 제거될 예정이다. 사용하지 마라.
  • nomen: 변수의 앞이나 뒤에 언더스코어(_)를 사용한 경우 오류가 발생한다.
  • onevar: 함수 안에 var 선언을 하나만 해야 한다.
  • passfail: 이 옵션을 사용하면 첫 오류나 경고에서 멈춘다.
  • white: JSHint가 더글라스 크록포드(Douglas Crockford)의 코딩 스타일가이드에 따라 코드를 검사하도록 한다.

My Comment..
음.. 노상 JS 를 쓰면서도 실질적으로 이런 코드 검사를 해주는 도구가 있는줄은 몰랐다.. 끽해야 F12 를 통한 브라우저 자체제공 도구를 사용하는정도가 다였는데 말이지..

역시 햄 블로그를 찬찬히 보다보면 새로운 것들을 많이 알게 되는 것 같다.. 나 스스로도 정리하고 새로운것을 알아보고 해야되는데.. 아흠.. 그것까진 솔직히 잘 안된다.. ㅎㅎㅎ..

2016년 8월 19일 금요일

[JS] Handlebars에서 if문에 헬퍼함수 사용하기..

출처 : Outsider's Dev Story https://blog.outsider.ne.kr/

handlebars는 템플릿 언어인 Mustache를 확장한 템플릿 라이브러리이다. handlebars를 소개하는 글은 아니지만 처음 보는 사람들을 위해서 간단히 설명하자면 다음과 같이 템플릿을 정의한다.

1
2
3
4
5
6
7
8
9
Html

<script id="example-template" type="text/x-handlebars-template">
  <ul>
    {{#each members}}
      <li>{{name}}
    {{/each}}
  </ul>
</script>

<script> 태그를 사용해서 정의해야 하는 것은 아니고 그냥 템플릿 문자열이면 되기는 하지만 개인적으로는 관리하기도 편하고 작성도 편해서 <script> 태그를 이용하는 방법을 좋아한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
Html

<script type="text/javascript" src="/components/handlebars.js/handlebars.js"></script>
<script type="text/javascript">
  window.addEventListener('load', function(evt) {
    var m = {
      members: [
        {name: 'outsider'},
        {name: 'zziuni'},
        {name: 'danni'},
        {name: 'fallroot'},
        {name: 'boxer'},
        {name: 'aj'},
        {name: 'insane'},
        {name: 'j2p'}
      ]
    }
    var source = document.getElementById('example-template').innerHTML;
    var tmpl = Handlebars.compile(source);
    document.getElementById('wrap').innerHTML = tmpl(m)
  }, false);
</script>

앞에서 정의한 템플릿을 위와 같이 사용한다. <script> 태그로 정의한 템플릿을 가져와서 handlebars로 컴파일해서 템플릿으로 만들고 템플릿에 객체를 전달해서 HTML을 생성한다. 여기서는 wrap라는 <div>에 변환된 <li>를 넣도록 만들었다. 이제 <li>태그를 만들때 name이 모음으로 시작하는 경우에는 다른 스타일을 주기 위해서 if 문을 사용한다고 해보자.

1
2
3
4
5
6
7
8
9
Html

{{#each members}}
  {{#if @index % 2 == 0}}
    <li class="vowel">{{name}}</li>
  {{else}}
    <li class="consonant">{{name}}</li>
  {{/if}}
{{/each}}

템플릿을 위와 같이 작성하기 쉽지만 handlebars는 저런식의 if문을 제공하지 않는다. if자제가 헬퍼메서드로 등록되어 있는데 if 헬퍼함수에 전달한 값을 true/false 여부만 판단할 뿐이고 일반적인 자바스크립트처럼 저런식의 표현식은 제공하지 않는다. {{#if name}}과 같은 정도로만 사용할 수 있고 name을 가지고 true/false 여부만 판단한다.(name은 값이 존재하므로 저렇게 사용하면 여기서는 항상 true이다.)

하지만 당연히 간단한 if문 외에 로직이 필요한 if문이 필요하게 마련인데 이는 직접 헬퍼함수를 등록해서 해결할 수 있다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
JavaScript

Handlebars.registerHelper('isVowel', function(options) {
  var regexp = /^[aeiou]/;
  if (regexp.test(this.name)) {
    return options.fn(this);
  } else {
    return options.inverse(this);
  }
});

헬퍼함수는 Handlebars.registerHelper()를 사용해서 등록할 수 있고 첫 인자가 헬퍼함수의 이름이고 두번째 함수가 헬퍼함수이다. 헬퍼함수는 기본적으로 options라는 객체를 인자로 받는데 이는 자동으로 전달되는 인자이다. 즉 options만 받도록 작성했다는 것은 전달하는 인자가 없다는 것으로 인자가 있다면 자동으로 앞에 붙는다. 즉 인자가 1개 있으면 function(arg1, options) {} 처럼 작성해야 한다. 여기서는 isVowel이라는 헬퍼함수를 if문처럼 사용할 것이므로 원하는 조건(여기서는 이름이 문자로 시작하면)이 true이면 options.fn(this)를 반환해서 if 구문의 내용을 사용하고 false이면 options.inverse(this)를 반환해서 else 구문을 사용하도록 작성했다. handlebars에서는 대부분 그런데 this에 현재 컨텍스트의 값이 들어간다.(여기서는 each문으로 돌아가는 members의 값들..)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Html

<ul>
  {{#each members}}
    {{#isVowel}}
      <li class="vowel">{{name}}</li>
    {{else}}
      <li class="consonant">{{name}}</li>
    {{/isVowel}}
  {{/each}}
</ul>

템플릿은 위와 같이 작성한다. if문대신에 isVowel 헬퍼함수를 사용했다.({{/isVowel}}로 닫아준 것에 주의!!) else문은 그대로 사용하고 이렇게 사용하면 원하는 조건으로 if문을 사용할 수 있다. 물론 헬퍼함수에 파라미터가 필요하다면 전달해주면 된다.

2016년 2월 19일 금요일

[Info]Tags categorized posts and contents patterns..


  • [AJAX] Ajax Code Examples..
  • [Book] About the book..
  • [CSS] CSS Code Examples..
  • [DB] Sql Code Examples..
  • [DEV] All development story..
  • [EP] Epilogue..
  • [HTML] Html Code Examples..
  • [JAVA] Java Code Examples..
  • [jQuery] jQuery Code Examples..
  • [JS] JavaScript Code Examples..
  • [JSP] Jsp Code Examples..
  • [Talk] Free Talk..
  • [Tool] About tools..
  • [.NET] .Net Code Examples..
  • [NEWS] IT News..
  • [Hobby] All My hobbies..
  • [Linux] Linux Instruction word..
  • [UFC] Ultimate Fighting Championship News..

  • 태그 작성시 글의 성격에 따른 카테고리 기본적으로 추가..
  • [Book] 내용에 대한 내 생각은 [블라블라..] 로 문장 뒤에 작성..
  • 내용 중 취소를 해야될 내용은 취소선 표시 후 [취소이유..] 로 문장 뒤에 취소 이유 작성..
  • 내용에 추가 작성시 맨 하단에 2016.01.01 수정 & 추가.. [굵게/먼저한 순서대로 작성..]
  • 한 해 마지막 및 시작은 매년 1월1일에 "Started in 2017 & Terminated in 2016" 의 제목으로 작성..