jQuery vs Angular 코드 비교

들어가기 전에

이 포스팅은 지난 2015 나는 프로그래머다 컨퍼런스 중 React 라이브 코딩에서 보고 알게 된 jQuery versus React.js thinking 글에서 영감을 얻어 (원저자의 허락을 받고) Angular 버전으로  쓴 글 입니다.

This post is the result affected by original post “jQuery versus React.js thinking” that I found on React.js live coding session in “I am programmer” conference. I wrote this post with the permission of original blog post’s author.

이 글에서는 아주 간단한 예제를 jQuery와 Angular로 각각 구현하여 어떤 차이점이 있는지 확인해 보려고 합니다. jQuery와 Angular의 직접적인 비교라기 보다 최근의 프론트엔드 프레임워크가 어떤 방식으로 어플리케이션을 구성하는지 확인하기 위한 목적의 글입니다.

예제 설명

예제는 jQuery versus React.js thinking과 동일하며 아래와 같은 기능으로 이루어져 있습니다.

  • 아이템의 목록이 있으며 아이템은 detail 정보를 기본적으로 드러내지 않음
  • 사용자가 아이템 클릭 시에 해당 아이템의 detail 정보가 펼쳐짐
  • 이 때 클릭 안 한 아이템들은 grey로 색 변경
  • 클릭한 아이템을 재클릭 시, detail 정보는 다시 감추고 원래 상태로 돌아감
  • 클릭해서 펼쳤던 아이템 외에 다른 아이템 클릭 시 펼쳤던 아이템은 닫히고 클릭한 아이템을 펼침

jQuery 방식

jQuery 방식의 소스는 원 글의 소스와 동일합니다.

라이브 예제
JS Bin on jsbin.com

jQuery 방식의 구현은 먼저html 파일에 아이템 정보가 정적으로 표현되어 있습니다. JavaScript 코드를 보면 DOM의 정보와 속성을 변경하기 위해서는 “li”, “:hidden”과 같은 셀렉터를 사용해서 접근합니다.

간단한 예제이지만 jQuery방식의 구현의 문제점을 요약하면 역할이 혼재되어 있다는 것입니다. 구체적으로 다음과 같

  1. html 파일 안에 뷰의 정보와 데이터가 공존한다.
  2. JavaScript 코드에 DOM의 조회 및 상태 갱신이 로직이 함께 있다.

결론적으로 기능이 복잡해 질수록 jQuery 방식의 개발 방법론에는 다소 간의 어려움이 있습니다. 그렇다면 Angular를 사용하면 어떻게 구현하는지 확인해 봅시다.

Angular 방식

Angular는 컴포넌트 기반으로 애플리케이션을 구성합니다.  컴포넌트는 화면을 구성할 뷰를  관리할 논리적인 개념입니다. Angular는 뷰와 직접적인 관계를 가진 로직을 컴포넌트에 담습니다. 주로는 데이터를 사용자에게 보여주기 위한 로직이나 뷰에서 발생한 이벤트를 처리하는 로직입니다.

간단한 예제이기 때문에 하나의 파일 안에서 모든 기능을 구현해 넣을 수 있습니다. 하지만 Angular  스타일 다운 특징을 보여주고자 일부 요소를  역할에 맞게 나누었습니다. 예제는 JavaScript에 타입 등의 syntax가 추가된 Typescript로 구현되어 있습니다. 먼저 동작하는 예제를 확인해 봅시다.

라이브 예제

컴포넌트 단위 구성

앞서 잠깐 언급한 것과 같이 Angular는 하나의 뷰를 여러 컴포넌트로 구성합니다. 본 예제에서는 AppComponent, ProductsComponent로 뷰를 구성합니다.  index.html 코드를 보면 다음 코드를 발견할 수 있습니다.

src/app/app.component.ts

app-root라는 태그는 이 예제에서 필자가 선언한 컴포넌트의 태그명입니다. 이 태그의 비밀은 AppComponent의 코드를 보면 알 수 있습니다. AppComponent 코드인 src/app/app.component.ts 파일의 내용은 다음과 같습니다.

코드의 4번줄에 app-root가 보이네요. AppComponent는 5-8번줄에 template에 선언된 뷰 템플릿을 갖는 간단한 컴포넌트 입니다. 본 예제의 루트 컨테이너와 같은 역할을 한다고 생각해도 됩니다.

src/app/products/products.component.ts

그럼, 템플릿의 7번줄에 선언된 app-products도 마찬가지로 다른 컴포넌트의 태그입니다. 하나 남은 ProductComponent가 바로 app-products의 주인입니다. 그럼 역시 코드를 확인해 봅시다.

ProductsComponent는 AppComponent보다 좀 더 긴 코드 입니다.  먼저 5번줄 부터 봅시다. 앞서 AppComponent의 뷰에 선언된 app-products를 확인할 수 있습니다.  이어서 각각 template, styles라는 키에 ProductsComponent의 뷰가 갖는 템플릿 정보와 스타일 정보가 있습니다.

클래스에 선언된 속성은 모두 뷰에서 사용할 상태정보를 담당합니다. jQuery 방식과 달리 데이터를 클래스의 속성으로 선언함으로 명시적으로 뷰와 데이터를 분리한 것을 볼 수 있습니다.

뷰에 노출될 아이템은 28번줄의 products 속성입니다. 이 데이터는 ProductService라는 클래스에 있습니다. Angular는 실제 비즈니스 로직은 Service 클래스에 담도록 안내하고 있습니다. Service를 Component에서 가져다 쓸 때에는 간단한 선언을 통해서 자동으로 Service객체를 주입받습니다. 32번줄의 생성자의 인자가 Component에서 사용할 의존성을 선언하는 방법입니다.

product.service

서비스 클래스는 아이템 데이터를 반환하는 getProducts 메서드 하나 만을 갖고 있습니다. ES6에 추가된 const 키워드를 사용하여 상수로 mock 데이터를 선언하여 메서드에서 반환합니다. 실제 상황에서는 getProducts 메서드 안에서 ajax 호출을 하도록 구현합니다.

2번 라인에서 import한 Product와 12번 라인에 메서드의 반환타입으로 Product[]로 되어 있는 것은 아이템 데이터의 타입을 명시한 Product 클래스 정보입니다. Typescript는 반드시 타입을 필요로 하기에 다음과 같이 모델 클래스를 선언하여 사용합니다.(자세한 내용은 연재 중인 Angular.io 글 목록을 참고해 주세요.)

 

이 글에서 Angular의 모든 것을 일일이 설명하지 않았습니다. jQuery 방식과 비교할 때 Angular는 어떤 형태로 구현하는지를 초점을 두고 가볍게 살펴 보았습니다. Angular 방식의 구현이  jQuery방식과 다른 점은 역할과 관심사의 분리입니다. 명시적으로 파일 혹은 Angular가 제공하는 개념 단위로 관심사를 분리할 수 있습니다.

  • template: 뷰 역할
  • component: 뷰와 모델, 상태 관리
  • service: 비즈니스 로직

분리된 코드는 Angular 프레임워크가 필요에 따라 적절하게 실행할 수 있도록 책임집니다. jQuery 방식에 비해 파일 개수도 늘어나고, 코드의 양도 늘어나지만 Angular 방식은 코드의 양이 늘어나고 복잡해 질수록 기능 개선 및 유지보수에 훨씬 더 쉬운 방면 jQuery 방식은 상대적으로 코드의 복잡도가 증가하게 됩니다.

Angular는 독립적인 컴포넌트 방식으로 뷰를 개발하기 때문에 재사용에도 용이하며, DOM으로부터 벗어나서 컴포넌트 단위로 독립적인 테스트까지 가능합니다.

결론

웹 어플리케이션의 복잡도가 증가하면서 지속적인 개선 및 유지보수를 고려할 때, 일정 규모 이상의 웹 어플리케이션 개발 시 프레임워크 사용은 더 이상 선택사항이 아니라고 생각합니다.

블로그의 내용을 바탕으로 앵귤러 첫걸음 이라는 책이 출판되었습니다. 블로그에서 담기 힘든 자세한 내용을 책으로 엮었습니다. 조금 더 다양한 예제와 설명은 책에서 제공합니다. 블로그의 글도 시간을 내어 최신버전에 맞게 내용을 짬짬히 업데이트 할 예정입니다.

Angular 글 목록보기

참고: jquery-versus-react-thinking

Angular 시작하기: 용어과 개념 정리

본 글은 Angular를 시작하는데 걸림돌이 되기 쉬운  용어와 개념을 다룹니다. 지난 5월에 글을 쓴 이후로 1년 가까운 시간이 지났지만 Angular를 둘러싼 프론트엔드 개발환경의 개념은 달라지지 않았습니다. 최근 급격하게 변화한 프론트엔드개발 환경의 용어와 개념 앞에 두려워 하지말고 차근히 알아봅시다.

2016년 새해 Angular 2가  5월 3일 기준 Release Candidate 버전으로 변경이 되었습니다. 그래서 지난  6개월 여 동안 실제 프로젝트에 적용하면서 느낀 경험을 바탕으로 Angular에 대해서 이야기 합니다. 목록은 Angular 글 목록보기 에서 확인해 주세요.

 

Angular는 버전2가 정식 출시되면서 더 이상 Angular2로 부르지 않고 Angular로 호명하기로 하였습니다. 버전은 Semver에 따라 변경될 뿐 앞으로 명칭을 Angular(앵귤러)로 사용하면 됩니다. 참고: http://angularjs.blogspot.kr/2017/01/branding-guidelines-for-angular-and.html

 

Angular 프레임워크는 최신 웹프론드 기술을 기반으로 웹 개발을 좀 더 구조적으로 할 수 있는 환경을 제공해 줍니다. 따라서 기존에 서버 개발만 주로 하셨던 분들도 Angular를 사용하면 좀 더 쉽고 재미있게 웹앱을 개발할 수 있습니다. 갈수록 뜨거워지는 프론트엔드 기술에 눈독 들이고 계셨다면 이번 기회에 Angular를 학습해 보는 것도 좋은 기회가 될 것 같습니다.  글의 대상 독자가 HTML과 DOM, 자바스크립트 대한 기본적인 지식과 사용 경험을 가지고 있다는 것을 전제로 합니다.

 

오늘은 Angular 기반의 웹 어플리케이션 개발을 하기 위해서 필수적으로 짚고 넘어가야 할 프론트엔드 웹기술의 배경을 다루는 것으로 시작합니다.

Background

Angular를 공부하기로 마음 먹고 공식 사이트의 튜토리얼매뉴얼을 읽다 보면 “이거 무슨 소리지…” 하는 생각이 들지도 모르겠습니다. Angular라는 고지를 제대로 점령하기 위해서는 Angular를 둘러싼 여러 개념을  차근히 살펴볼 필요가 있습니다.  Angular 프레임워크 안에 이미 최신의 프론트 엔드 기술과 개념들이 어우려저 사용되고 있기 때문에 우리는 이 개념들을 하나씩 이해하고 넘어가야 합니다. 각각의 개념이 뭔가 복잡해 보이지만 실상은 그리 어려운 것도 복잡한 것도 아닙니다. Angular를 사용하려면 적어도 아래와 같은 키워드를 한 번씩 훑어보지 않을 수 없습니다.

  • NPM
  • ES6와 Module(CommonJS, AMD…)
  • Transpiler(Polyfill, shim)
  • TypeScript, (typings, tsd)
  • Angular 프레임워크 관련 개념: MVVM, Change Detector, Observable, Immutable, Two-way Binding, Zone.js
  • RxJs
  • Webpack 등의 Bundler

위에서 열거한 키워드 중에서 본 글에서는 NPM부터 Typescript까지 살펴봅니다.

NPM

NPM은 Node Package Management의 약자로 자바스크립트로 쓰여진 패키지 (혹은 라이브러리) 관리 도구 입니다. NPM에 Node가 붙어 있어서 NodeJs를 공부해야만 하는 것은 아닙니다.  또한 NPM은 Angular2 만을 위한 툴도 아닙니다. NPM은 광활한 오픈소스 세계에서 다앙햔 자바스크립트 패키지들을 버전별 의존성 이슈 없이 편리하게 관리하기 위한 툴입니다. Java 에 익숙하신 분들이라면 NPM을 메이븐이나 그래들 정도로 생각하셔도 됩니다.

 

NPM을 통해서 사용할 패키지는 package.json 파일에 정의 되어 있습니다. Angular가 사용하는 핵심 패키지 정보 역시 package.json 파일에 있습니다. 대표적으로 SystemJs, RxJs 등이 그 예입니다. 다음은 실제 QuickStart Seed 프로젝트에서 볼 수 있는 Angular의  package.json 파일 내용 중 일부입니다.

 

 

설정에서 “dependencies”와 “devDependencies”에 각각 Angular에서 필요로하는 패키지들이 선언되어 있습니다. 속성명에서 유추할 수 있듯이 “dependencies”에 등록된 패키지는 Angular에 필수 의존 패키지이고 “devDependencies”는 개발에 부가적으로 필요하지만 실제 앱 결과물에는 필요하지 않은 패키지들을 넣습니다.

 

NPM은 패키지 관리 기능 외에 특정 작업을 수행할 스크립트 명령어를 등록할 수 있습니다. 이 명령어는 “scripts” 속성 안에 열거 합니다.  “scripts” 속성 안에 선언된 명령어는 “npm run (명령어)” 형태로 쉘에서 실행이 가능합니다. NPM과 관련된 기본 명령 스크립트는 이후에 다시 설명하기로 하고, 일단 지금은 NPM이 여러분이 만들 웹 애플리케이션에서 필요한 외부 자바스크립트 패키지들을 관리해주는 도구로 생각하는 걸로 합니다.

 

ES6 (ECMA 2015)

Java 언어에도 언어를 구성하는 스펙의 버전이 있는 것처럼 자바스크립트에도 버전이 있다는 것을 혹시 알고 계셨나요? ES6는 ECMA Script6의 약자로 현재 우리가 브라우저에서 사용하는 자바스크립트의 표준의 버전명입니다. 자바스크립트 표준을 제정하는 ECMA와 상당히 오랜만에 확정(2015년 6월)된 ES6는 자바스크립트에 참 많은 변화를 가져왔는데요. 그래서 아직 ES6 스펙을 브라우저들이 100% 지원하고 있지는 않습니다. 그래서 각 브라우저마다 그리고 버전 별로 어느 정도 까지 ES6를 지원하는지를 나타내는주는 아래와 같은 사이트도 있습니다.

 

es6_browser_support

Transpiler

생각보다 ES6에 대한 구현이 아직은 충분하지 않은 상황인데요. 그렇다고 해서 ES6를 쓸 수 없는 것은 아닙니다. 아직 브라우저에서 미구현된 언어의 기능을 보완해 주기 위한 polyfill이나 shim이라는 postfix가 붙은 라이브러리들이 있습니다. 네이버 영어사전을 찾아보니 polyfill은 사전적 적의가 “충전솜”이고, shim은 “(두 사물 사이의 틈새 등에 끼우는) 끼움쇠”라네요. 이런 류의 라이브러리들은 대개 브라우저가 미지원하는 기능을 스크립트로 지원하기 위한 용도라는 것을 참고로 알아두시면 될 것 같습니다.

 

이런 라이브러리말고 직접 스크립트를 변경하는 transpiler가 있습니다. compiler는 익숙하지만 transpiler라는 용어는 익숙치 않을 수도 있는데요. 하나의 언어를 다른 형태의 언어로 변환해 주는 기능을 부각시키는 표현으로 compiler라는 표현보다 transpiler라는 표현을 쓰는 것으로 추측되는데, 실상 하는 일은 브라우저가 아직 지원하지 못하는 스펙의 자바스크립트 소스를 현재 브라우저가 지원하는 ES5 기준의 소스로 변환해주는 것입니다. 대표적인 transpiler로 React 덕을 좀 본게 아닌가 싶은 Babel이 있습니다. ECMA와 자바스크립트의 역사나 그 기원(?)이 궁금하신 분들은 온라인에서 무료로 볼 수 있는 Speaking Js 챕터 4장을 참조하시면 도움을 얻을 수 있습니다.

 

Typescript

Angular는 아래 매뉴얼에서 볼 수 있듯이 Javascript, Dart, Typescript, 까지 총 3가지 언어로 개발할 수 있도록 지원합니다. 선택한 언어에 따라 매뉴얼의 예제도 당연히 다르게 나옵니다.

 

angular2_doc_type

3가지 언어 가운데 이 포스트에서는  Typescript를 Angular의 개발언어로 소개하고자 합니다.

그럼 Typescript를 한 번 살펴봅시다. Typescript는 Microsoft에서 만든 언어입니다. 공식 사이트에서는 Typescript를 이렇게 소개하고 있습니다.

Typescript is typed super set of Javascript that compiles to plain Javascsript.

공식적인 정의는 그렇고 3개월 정도 써보면서 느낀 점은자바스크립트에 “타입”을 추가해서 만든 확장형 자바스크립트 언어라고 볼 수 있습니다.  (똑같은 말인가?..) Angular 하나 써 보자고 Typescript라는 새로운 언어를 배워야 하는거냐는 질문을 하실 수도 있겠지만, 우리는 Typescript를 선택해서 앞으로 Angular를 개발하기로 합니다. 새로운 것을 배운다면 그에 따른 이점이 있어야 할텐데요. Typescript의 장점을 직접 소개하기 보다 Angular팀이 왜 Typescript를 선택했는지 자세히 알 수 있는 글을 한 편 소개하는 것으로 대신 할까 합니다.

Angular에서 Typecript를 사용하는 이유

이 글은 Angular 코어 개발팀 빅터 사브킨이 쓴 것을 번역한 것입니다.  Typescript를 만든 사람이 설명하는 Typescript에 대한 소개 영상도 Typescript의 강점을 확인하는데 큰 도움이 됩니다.

 

 

그래도 간단히 Typescript를 살펴보자면 아래 그림이 Typescript에 대한 설명을 대신해 줄 수 있습니다.

 

참조: Typescript Won (링크는 하단 참조)

 

보시다시피 Typescript는 새로운 언어라기 보다는 기존의 자바스크립트(ES5)와 위에서 설명한 ES6 스펙에 type과 관련된 추가적인 syntax가 추가된 언어입니다. 따라서 학습곡선이 그렇게 높지 않아 꼭 권하고 싶습니다. 왜냐하면 그림이 이미 설명하듯이 Typescript를 쓰다 보면 자연스럽게 최신의 자바스크립트 Syntax에 익숙해 질 수 있기 때문입니다. 시간날 때 틈틈히 매뉴얼 한 번 읽으면 누구나 Typescript를 쓸 수 있습니다.

Typescript를 사용해야 하는 또 다른 이유는 실제로 Angular 프레임워크 자체도  Typescript로 쓰여져 있기 때문입니다.  이 내용이 지난해 3월 MSDN에 공식 발표되기도 했었지는데요. 오프라인 상에서도 Angular 개발팀과 Typescript 팀이 활발하게 교류하고 있다고 합니다. Angular에서 Typescript를 얼마나 활발하게 쓰는지 보여주는 단적인 예가 데코레이터라고 하는 문법입니다.  하단의 코드 샘플에서 @Component… 문법이 데코레이터라고 하는 것인데, 아직 Typescript 정식 문법은 아니고 실험버전이라 반드시 Typescript 컴파일 설정에 emitDecoratorMetadata를 “true”로 해줘야 합니다.

 

 

지금은 무슨 내용인지 이해하려고 노력하지 않으셔도 됩니다. 요지는 Angular는 Typescript를 아주 깊게 사용하고 있으며, Typescript가 가진 장점이 많기 때문에 우리도 Typescript로 Angular를 개발하자는 것입니다.

 

이번 글에서는 Angular를 본격적으로 개발하기에 앞서 Angular를 둘러싼 기반 기술과 개념 중 일부인 NPM, ES6, Transpier, Typescript까지 살펴보았습니다. 이어지는 포스팅에서 본격적으로 Typescript를 사용하여 간단한 Todo App을 작성해 보고, Angular의 기본 배경 및 개념을 다루도록 하겠습니다.

블로그의 내용을 바탕으로 앵귤러 첫걸음 이라는 책이 출판되었습니다. 블로그에서 담기 힘든 자세한 내용을 책으로 엮었습니다. 조금 더 다양한 예제와 설명은 책에서 제공합니다. 블로그의 글도 시간을 내어 최신버전에 맞게 내용을 짬짬히 업데이트 할 예정입니다.

Angular2 글 목록보기

참고 링크

  • http://ngcourse.rangle.io/handout/why_angular_2.html (Angular 학습에 필요한 전반적인 기술 다룬 내용, 강추)
  • https://angular.io/docs/ts/latest/tutorial/ (공식 튜토리얼)
  • http://victorsavkin.com/ (angular 커미터 블로그, angular 동작원리 잘 설명되어 있음
  • http://blog.thoughtram.io/categories/angular-2/ (angular 전문 컨설팅 독일 회사 블로그 내용 설명 좋음)
  • http://seokjun.kr/ecmascript-6-features/ (ECMA6 간략 설명)
  • http://xgrommx.github.io/rx-book/ (Rx.js 설명: Angular 에서 아주 열심히 Rx.js 씀)
  • http://rxmarbles.com/ (Rx 이해를 돕는 애니매이션 사이트)
  • http://mobicon.tistory.com/category/Angular.io (한글 개인 블로그)
  • http://es6-features.org/#StatementBodies (ES6 와 ES5 코드 비교)
  • https://kangax.github.io/compat-table/es6/ (ES6 브라우저호환성)
  • http://han41858.tistory.com/3
  • http://sculove.github.io/slides/2016_FETrend/#/
  • https://kangax.github.io/compat-table/es6/
  • https://medium.com/@basarat/typescript-won-a4e0dfde4b08#.2xxoq0vo8 (Typescript Won)
  • https://www.gitbook.com/book/basarat/typescript (Typescript 학습자료)

영상 참고

2015년 angular 컨퍼런스에서 창시자가 angular의 개념에 대한 설명