Angular4 구글은 어떻게 성능 개선을 했나?

Angular 2.x 대비 Angular 4.x에서 바뀐점을 살펴보고,
구글은 어떻게 성능 개선을 했는지에 대해 방법론적으로 살펴본다.

이 발표자료는 구글에서 공유한 ViewEngine Design 문서와
Angular4 릴리즈 소식을 전하는 Blog 내용을 참고하여 작성하였습니다.

자료 : https://sculove.github.io/slides/angular4/

Comment and share

Rxjs-활용기2

in Tech

Deview2016 Angular2 VS React, React VS Angular2 발표에서도
RxJS를 언급했지만, 지금까지도, RxJS를 왜 Angular2가 도입했는가에 대한 이유는 모르겠다.

이를 알아보기 위해,
Angular2 프로젝트를 하면서, RxJS를 가급적 많이 사용하고 있는데,
그 중 하나 느낀 점이 있어 몇자 끄적여 본다.

왜 Angular2는 RxJS를 도입했는가?

일반적으로 Angular2를 사용하게 되면, 화면에 표현되는 요소는 Component로 만들고,
실제 데이터를 가져오는 작업은 Service에서 담당한다.
이 둘의 관계를 RxJS의 Observable 객체를 통해 subscribe로 연결된다.
좀 간단히 보면, 다음 그림과 같다.

Component와 Service 간의 구조에서 RxJS는 둘 사이를 이어주는 다리가 되고,
단방향의 데이터를 가져오는데 결합도가 약하게 연결된다.

이 말을 좀 풀어서 쓰면,
Component에서는 Service를 DI(Dependency Injection)로 주입받고,
주입된 상태에서 데이터를 가져오는 것은 Observable 객체로 연결이 된다는 말이다.
이렇게 되면 Component 입장에서는 주입된 Service의 메소드(foo)만 알면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Component({})
class AppComponent extends Component {
// DI로 service 주입
construnctor(service: Service) {
this.service
.foo()
// operator 적용
// filter(...)
// map(...)
// ...
.subscribe(x => {
// 데이터를 받음.
});
}
}

@Injectable()
class Service {
foo(): Observable {}
}

또한, Service에서는 Component와의 연결을 Observable로 사용하기 위해, 메소드의 반환값을 Observable로 사용한다.
반환값이 Observable이기 때문에, RxJS의 operator를 적용하면, Service가 주는 데이터를 변경하거나, 무시하거나, 기타 등등의 작업들을 Component가 할 수 있다.

즉, Angular2에서 RxJS를 사용하면 Component가 갑이되고, Service가 을이 되는 것이다.

예전에는 Service가 주는 데이터만 가지고 처리했다면, 이제는 Component가 데이터의 처리를 결정할수 있게 된 것이다.
흔히 이를 Push방식의 장점이라고 이야기 한다.

그럼 RxJS를 사용하면, 단순히 갑과 을의 관계가 바꿔서 좋다는 말인가? 좋긴하다.
하지만, 그렇다고 이게 RxJS를 사용하는 이유라고 보기에는 납득이 안된다.
더 해봐야겠다.

RxJS와 Typescript 의 캐미

Angular2프로젝트를 하면서 확실하게 안 사실이 있다.
바로 RxJS와 Typescript의 캐미(chemi)이다.

프로젝트를 하다보면 알겠지만, 앞에서 보여준 그림처럼 Component와 Service간의 관계가 1:1인 상황은 많지 않다.
하나의 Component에서 여러개의 Service를 사용하기도 하고, 하나의 Service와 여러개의 Component가 연결되어 있기도 하다.
또한, Service에서 다른 Service와 연결되어 있기도 한다.

Component와 Service간에는 항상 데이터들이 흐르게 되는데. 이때 전달되는 데이터를 따라가기는 쉽지 않다.
물론, 오늘 개발한 코드라면 아주 쉽게 따라 갈수 있겠지만,
개발한 코드가 몇 달 전이거나, 내가 아닌 다른 이가 개발한 코드라면, 데이터 흐름을 따라가는 것은 쉬운일이 아니다.

하지만, 우리는 개발자이니깐 이런 것쯤은 충분히 이겨낼수 있다고 생각한다.
왜? 우린 프로니깐 ㅋㅋ

그런데 문제는 RxJS로 연결 될 경우, 이 Operator에 의해 중간 중간 전달되는 데이터가 변형이 된다는 것이다.
바로, 이런식으로…

1
2
3
4
5
6
7
8
this.service
.foo()
.map(x => {
return somthingFn(x);
})
.subscribe(x => {
// 데이터를 받음.
});

만약, Javascript의 역량을 최대한으로 끌어올려서 데이터를 간결하게(?) 변형(?) 시킨다면,
무슨 데이터가 왔는지 또는 넘겨진 데이터의 속성이 무었인지 확인하기가 어렵다.

하지만. RxJS와 Typescript가 만나면 상황은 좀 달라진다.

1
2
3
4
5
6
7
8
this.service
.foo()
.map((x: Student) => {
return somthingFn(x);
})
.subscribe((x: SmartStudent) => {
// 데이터를 받음.
});

Student 데이터를 받아서, SmartStudent 데이터로 변경했다는 것을 알 수 있다.
한 눈에 데이터가 어떻게 변했는지바로 확인 가능하다.
만약, vscode와 같은 훌륭한 IDE툴이 있다면.데이터의 속성이 또 어떤 것인지 바로 파악할수 있다.

그래서 만약, RxJS를 사용한다면, 꼭! Typescript와 함께하는 걸 추천한다.

Angular2가 RxJS를 왜 도입했는지에 대해서는 아직도 잘 모르겠다.
하지만, Typescript와 RxJS의 캐미가 정말 짱 좋다는 사실은 확인했다.

분명, RxJS와 Angular2의 캐미도 확인할 수 있으니라 본다.ㅋㅋ

Comment and share

오늘은 Angular2 정식릴리즈 이후, 지금까지 어떻게 변해 왔고, 앞으로 어떻게 변할지에 대해 간단히 살펴보자.

Release

Angular2는 2016년 9월 14일 이후, 지금까지 꾸준한 업데이트로 빠르게 변해가고 있다. 총 4번의 patch가 이루어졌으며, 1번의 minor 버전이 업데이트 되었다. 현재는 2번째 minor 업데이트가 진행 중에 있다.

  • 2.0.0 릴리즈 (2016.09.14)
  • 2.0.1 릴리즈 (2016.09.23)
  • 2.0.2 릴리즈 (2016.10.05)
  • 2.1.0 릴리즈 (2016.10.12)
  • 2.1.1 릴리즈, 2.2.0-beta.0 (2016.10.20)
  • 2.1.2 릴리즈, 2.2.0-beta.1 (2016.10.27)
  • 2.2.0-rc0 (2016.11.02)

이렇게 Angular2가 빠르게 발전해 나가고 있는 이유 중에 하나는 중소기업에 버금가는 막대한 인력이 이 프로젝트를 진행하고 있기 때문이다.

Angular의 창시자 Miško Hevery 외에 6명의 리더가 존재하고, 25명의 구글러가 개발자로 있다. 더불어, 30명의 커뮤니티 인력이 주요 개발자로 포진해 있다. 그 외에도 300여명의 Contributer가 github 상에 존재한다.
https://angular.io/about/

이를 경제적인 가치(?)로 환산한다면, 어마어마한 금액이 될 것으로 보인다.
돈도 될 것 같지 않은 FE 프레임워크에 왜 구글은 이렇게 막대한 자원을 투입하고 있을까? 구글입장에서는 푼돈인 건가? 아니면, 무슨 심오한 뜻이 있지 않을까?

Android OS와 같은 플랫폼 전쟁을 FE에서도 하려는 것인가?
우매한 나로서는 당췌 모르겠다. ㅠㅠ

하지만, 푼돈이 아니라면…아마 구글이 Angular2에 기대하는 바는 굉장히 클 것으로 보인다.
실제 그 꿈은 실로 원대하다.

Release 정책

Angular는 정식 버전을 공개하면서, 프레임워크 운영 정책에 대한 이야기도 함께 공개를 했다.
http://angularjs.blogspot.kr/2016/10/versioning-and-releasing-angular.html?view=classic

우선, Angular2의 버전 규칙을 기본적으로 Semantic Versioning(MAJOR.MINOR.PATCH)을 사용하기로 하였다. 더불어, 6개월 단위로 Major 업그레이드를 한다고 공개했다.
이 말은, 6개월 마다 Angular3, Angular4, Angular5를 내놓겠다는 이야기이다.

아 갑자기 머리가 아프다.

Angular1에서 Angular2로 왔더니 다시, 3,4,5,…을 내 놓겠다고?

하지만, 그렇게 걱정하지 않아도 된다. React는 0.14.0에서 15.0.0으로 바꾸지 않았던가? Angular2도 3,4,5의 연장선에 있기 때문에 새로운 것이 아니다.

또한, 릴리즈도 정말 쉬지 않고 계속한다. 매주 patch 릴리즈를 하고, 3개월 동안 3번의 minor 릴리즈를 하고, 이후 2달 간은 1개의 major 릴리즈를 한다.

앞으로의 방향성

앞으로 Angular는 다음 작업들에 집중한다고 공개했다.
http://angularjs.blogspot.kr/2016/09/angular2-final.html?view=classic

그래서…

현재 구글의 행보로 앞으로를 추측해 본다면, Angular2의 갈길은 아직 멀어 보인다. 또한, 그 앞날을 예측하기는 더더구나 어려워 보인다.

하지만, Angular1과 같이 자사 서비스에 쓰지 않는 프레임워크를 만들고 있는 것 같지는 않다. 이번에는 꼭! 구글에서 쓰는 프레임워크를 만들려는 확고한 의지가 보인다.

Comment and share

Angular2 rc5: Component에서 ngModule 단위로

2016년 8월 9일 Angular2 rc5가 발표되었다. Angular2 rc5에서는 전체적으로 구조 자체를 바꾸었다. 기존 Angular1이 module 방식을 채택했던 것에 비해 Angular2는 React와 같이 Component 단위로 구성되었다. 하지만, rc5에서는 다시 예전의 모습으로 돌아왔다.

그렇다면, Angular2는 Component 방식에서 Angular1에서 쓰던 module 방식으로 왜 돌아 왔을까?

어떤 기능(feature)을 구현하기에 Component는 너무 작은 단위이다.

하나의 기능(feature)를 개발하기 위해서는 UI를 구성하는 View가 있을 수 있고, 기능을 담당하는 service가 있을 수 있다. 더불어, feature내에서 사용하는 pipe나 directive도 존재할 수 있다.
ngModule은 이런 Component, Direcitve, Pipe, serice를 하나로 묶어서 관리 할수 있는 단위이다.
각각의 요소들이 ngModule 단위로 묶이다 보니 ngModule 단위의 배포나 관리 또한 편해졌다.
더불어, Router에서 ngModule 단위로 Lazy Loading도 가능해 졌다.

ngModule 내에서의 Dependency는 공유된다.

이젠 이전 버전에 무의식적으로 넣었던 module.id도 더 이상 코드에 기술 할 필요가 없고, Component별로 명시하던 directives, pipes, 등도 더 이상 기술 할 필요가 없다.
모두 ngModule에 명시하면 된다. 이 방식의 장점은 ngModule에서 dependency를 관리하고, 실제 사용하는 dependency를 한 눈에 다~ 볼 수 있다. 뿐만 아니라, 코드도 더 간결해진다.
이렇게 할수 있는 이유는 바로 ngModule이 JavaScript의 module과 같이 module 단위로 scope를 갖기 때문에, ngModule에 명시된 Component들은 ngModule에 명시된 dependencie 객체들(directive, pipe, service, component)을 자유롭게 사용할 수 있다.
참고로, Component의 directives, pipes들은 depreacted 되었다.

하지만, 불편한 것도 있다. ngModule에서 쓰는 모든 자원을 declarations이나 providers로 수동으로 명시 해줘야하는 번거로움(?)이 있다. 또한, React와 다르게 Component 기반이 아닌 ngModule 단위의 접근으로 바뀌다 보니, 가벼운 느낌보다도 뭔가 무거워진 느낌도 든다.

rc5에 대한 자세한 사항은 다음 링크를 확인해보기 바란다.

Angular2는 왜 자꾸 인터페이스를 바꾸는가?

기존 rc4에서는 router와 form에 대한 인터페이스를 바꾸더니, 이번에는 Component 기반의 구조에서 ngModule 기반으로 구조 자체를 변경하였다.
일반적인 프로세스 단계로 봤을 때, rc(Release Candidate) 버전은 인터페이스 변경보다는 버그 개선에 포커스가 맞춰져 있지만, Angular2는 rc가 발표될 때마다 대다수 인터페이스를 변경하고 있다.

지금 서비스에 Angular2를 도입하려는 사람들에게는 지극히 비상식적인 일인 것 같지만, 다른 한편으로는 고무적인 일 인것 같다. 물론 개인적인 생각이다.

모든 S/W가 마찬가지겠지만, 특히 프레임워크가 한 번 릴리즈 된 이후, 인터페이스를 변경하는 것은 정말 어려운 일이다. 따라서, 정말 잘 결정해야만 한다. 그러기 위해서는 사용자의 피드백을 중심으로 논의가 이루어져야 하며, 그 논의의 결과가 프레임워크에 반영되어야 할 것이다.
Angular2는 이런면에서 사용자의 피드백을 열심히 받고 있는 것 같다. 다양한 의견들에 대한 논의가 이루어지고 있고 이로 인해 Angular2가 변해가고 있다.

ngModule에 대한 어느 사용자의 커멘트 https://github.com/angular/angular/issues/10552#issuecomment-238819504

지금까지의 Angular2의 행보로 본다면, Angular1과 React에서 많은 교훈 점을 찾고자 노력하고 있는 모습이 역력하다.

React의 단방향 설계와 성능적인 장점 요소를 가져오면서도,
Angular1이 가지고 있었던 프레임워크의 역할과 개발생산성의 장점을 모두 잡으려고 하는 노력이 보인다. 더불어, ember 프레임워크의 장점 중의 하나인 ember-cli도 angular-cli를 통해 하나 하나 흡수해 나가고 있다.

앞으로 정식 릴리즈가 될 때까지 얼마나 많은 rc가 배포 될지는 모르지만…
고민한 만큼 뭔가 대단한 녀석이 나올 것만 같다.

Comment and share

React로 프로젝트를 진행하신 분들의 경험을 듣는 기회가 있었다.
많은 이야기가 있었지만, 그 중 공통적으로 React가 아쉽다고 이야기한 부분 중 하나로, 초기 개발환경에 대한 부분이 지원되었으면 좋겠다는 이야기가 있었다.

feature 단위로 폴더를 구성할 지, type 단위로 폴더를 구성할 지,
Webpack을 쓸지 grunt,gulp를 쓸 지,

소소하지만, 개발시 논란의 여지가 되는 부분들.
개발자라면 익히 경험했을 것이다.

feature 단위인 경우는 작업 분할이 쉬운 반면, type 단위의 경우는 각 타입별 확인이 편하며, 공통 기능들을 관리할 수 있는 장점이 있다. 이런 타입의 특.장점을 살려 차선책으로 2가지 타입을 병행해서 사용하는 경우도 존재한다.

구성원들의 상황에 따라 “이거 정해지는 대로 쓰자” 부터 “향후 유지보수에 막대한 영향력을 미치기 때문에 정말 중요하게 결정해야 한다” 고 주장하는 이도 있다. 이런 주장이 둘 다 틀린 주장은 아니다.
하지만, 개인적으로 이런 환경에 대한 것은 정답이 없는것 같다. 단지 Best Practice가 있을 뿐이다

React에서는 이런 Best Practice를 직접 찾아서 적용하고 검토해봐야 하는 상황에 직면하는 경우가 많은 반면, 다행히 Angular2는 이런 부분에 대한 고민이 공식적(official)으로 정리가 되어 있다.

Angular2 Style Guide

https://angular.io/docs/ts/latest/guide/style-guide.html

LIFT (Locate, Identify, Flat, Try to DRY) 원리에 따라 폴더구조를 구성하고 있다.
우선, 기본적인 모양은 feature 단위로 구성하고, 그 feature 내부에서 공통적으로 활용하는 부분은 shared를 나눠서 관리하고 있다.

처음에는
“음… 이렇게 그냥 잘 정했구나” 정도로 생각했는데….

개인적으로 놀란 것은…
바로, Angular-cli도 이 구조로 구성을 한다는 것이다.

내가 주목했던 부분은 바로

일관성

그리고

자주 접하게 되는 고민의 솔루션

이 Angular2에 녹아 있다는 것이다.

우리가 프레임워크를 쓰는 이유 중의 하나는 자주 접하는 문제에 대한 솔루션을 프레임워크를 통해 손쉽게 해결하고, 일관된 코드를 유지하고, 재사용성을 높임으로써 보다 높은 생산성을 유지하기 위해서 이다.
이런 의미에서 Angular2는 프레임워크가 추구해야할 근본 취지를 잘 지키고 있는 것으로 보인다.

Angular-cli

React에서는 최근 create-react-app이 등장했다. 아직은 미약하지만 고무적인 일이다.
하지만, Angular2 개발자들에게는 이미 준비 되어 있다.
바로 위에서 잠깐 언급했던 Angular-cli 이다.

Angular-cli는 지금도 개발이 되고 있지만, 기본적으로 Angular2에서 가이드하는 코딩 스타일을 준수하고 있다.
아쉽게도 세세한 부분에 대해서는 가이드와 일치 하지 않는 부분이 존재하지만, 그 부분은 차차 개선되리라 믿는다.

잘은 모르지만, 아마도, 지금 Angular-cli 가 ember-cli를 기준으로 만들어지고 있기 때문에, 약간 엇박자가 나오고 있는 부분이 있는 것 같다.

아래는 실제로 개인적으로 겪었던 일이다.

angular-cli에 의해 생성한 프로젝트는 기본적으로 tslint.json 을 생성한다. 만약, tslint.json 파일의 규칙을 사용자가 바꾼 후, angular-cli를 통해 컴포넌트나 서비스를 만들게 되면. tslint.json에 변경한 규칙이 적용되지 않는다.
이 부분에 대해서는 개발하고 있는 github에 요청해 봤으나, 특별한 답을 얻지 못했다.
angular-cli로 생성한 프로젝트에서 제공하는 npm run format 명령 또한 마찬가지다. tslint.json을 기반으로 formating이 적용되지 않는다.

그래서 알아낸 사실은…
angular-cli는 .clang-format에 의해 code style을 관리하고, 이를 기준으로 명령이 수행된다.
따라서, 만약 tslint.json의 규칙을 바꾼다면, .clang-format도 함께 바꿔줘야한다.
바로 요렇게 .clang-format에 추가한다.

1
2
3
4
JavaScriptQuotes: Double
IndentWidth: 4
TabWidth: 4
UseTab: ForIndentation

위 코드는 더블 쿼테이션과 space대신 탭을 쓴 예이다.

참고로 clang-format 관련 사이트
https://clangformat.com/
http://clang.llvm.org/docs/ClangFormatStyleOptions.html

아마 내부적으로 ember-cli의 dependency를 제거하기 위한 노력이 진행되고 있는 것으로 보인다.
그런 취지에서 나온게 바로 angular-cli webpack 버전인 것 같다.

아래 같이 설치하면 webpack 버전 angular-cli를 받을 수 있다.

1
npm install -g angular-cli@webpack

친절하게도 기존 개발자를 위해 migration 가이드도 있다.
https://github.com/angular/angular-cli/blob/master/WEBPACK_UPDATE.md

정말 반가운 소식이다. 나도 개인적으로 webpack이 더 좋다. 친숙하기도 하고 ㅋㅋ

올해 내로 꼭! 더 좋은 모습이 나오길 기대해 본다.

Comment and share

Angular 1.x은 높은 생산성으로 많은 개발자들의 마음을 뺏아 갔습니다. 반면, Two-way binding과 client rendering 구조로 성능에 문제가 있다라는 지탄을 받았습니다.
이런 Front-End 프레임워크에 대한 관심은 Facebook의 React로 이어졌습니다.
React는 Virtual DOM과 JSX의 server rendering을 이용하여 성능이 좋다라는 이야기와 함께 개발자들에게 뜨거운 관심을 받았습니다. 2016년 개발자들 사이에서 가장 뜨거운 감자였으며, 지금도 많은 개발자들이 관심을 갖고, 도입을 고려하는 있는 프레임워크(?)입니다.

하지만, 저의 개인적인 견해는

우리는 React보다 Angular2에 더 주목해야한다

고 생각합니다.

React는 라이브러리이고, Angular2는 프레임워크이기 때문에 비교하는 것 자체가 말이 안된다고 이야기하는 이도 있지만, 지극히 제 관점에서 React와 Angular2 생태계 내에서 비교를 간단히 해보겠습니다.

Performance

구조적인 개선

저희가 만드는 서비스에서 느리다라고 말하는 부분이 실제로는 어떤 부분일까요?

  • Client Rendering으로 인해 하얀화면이 보이는 것? (FOUC:Flash of unstyled content)
  • 데이터 변경시, 여러 뷰들이 실시간으로 일괄 변경되는 부분?
  • 애니메이션 동작시 매끄럽지 않은 부분?
Server Rendering 지원

처음에 이야기한 Client Rendering 부분은 Angular 1.x 가 구조적으로 극복하기 힘든부분입니다. 하지만 Angular2에서는 angular-universal 을 통해 React와 같이 Server Rendering을 지원합니다.

단방향 데이터 흐름의 구조

다음으로 데이터 변경시 여러 뷰들이 실시간으로 변경되는 부분 입니다.
Angular 1.x에서는 Two-way binding을 이용하여, 데이터 변경만으로 뷰들을 일괄 변경할 수 있는 기능을 제공했지만, 이와 같이 데이터 흐름이 양방향으로 이루어 지다 보니, cascade 효과가 발생하여, 불필요한 digest가 발생합니다. 이로 인해 구조적으로 성능문제에 직면하게 될 확률이 높아 집니다.
반면, React에서는 단방향 데이터 흐름을 통해 데이터가 상위에서 하위로 전달하는 방식을 사용합니다. 따라서, Angular1과 같이 성능적인 문제에 직면하게 될 확률이 낮습니다.
Angular2도 React와 같이 컴포넌트 단위의 단방향 데이터 흐름의 구조를 취하고 있습니다.

마지막으로, 애니메이션 동작시 매끄럽지 않는 부분은 사실 React나 Angular 1/2로 해결하기에는 어려움이 있습니다. 오히려 Native를 이용한 개발이 더 효과적이기 때문에 이부분에 대한 설명은 생략하도록 하겠습니다.

데이터 변경 확인 방법

React, Angular 1/2 모두 DOM을 기준으로 작업하는 기존 방식(JQuery)과 다르게, 데이터 기준으로 개발을 해야만 합니다. 이때 가장 중요한 것이 실제 데이터가 변경되는 시점을 찾는 방법입니다.

React에서는 데이터 변경여부를 Immutable 객체를 이용하거나, Virtual DOM을 이용하여 비교를 합니다. 실제 브라우저 DOM을 기준으로 비교하지 않기때문에, 그만큼 성능이 빠릅니다. 하지만, Angular1에서는 이러한 기능이 없었기 때문에, digest loop를 통해 변경여부를 확인합니다. 더군다나, 양방향 데이터 흐름 덕(?)에 digest lopp 1번 호출시, 최소 2번 최대 9번까지 확인하게 됩니다.
하지만, Angular2에서는 이런 문제를 ChangeDitector Tree, Immutable, Observable을 이용하여 React와 같이 메모리 영역에서 변경여부를 확인합니다.

즉, Angular2는 Angular1과 같은 단점을 보강했고, React와 같은 구조를 가지고 있기 때문에, 성능상 크게 차이는 없다라고 이야기할 수 있을 것 같네요.


자 여기까지는 Angular2도 React 만큼 괜찮다 라는 일종의 변론이었고, 이제 본격적으로 React보다 Angular2에 더 주목해야하는 이유에 대해 이야기해 보겠습니다.

React보다 Angular2에 더 주목해야하는 이유

1. 템플릿(마크업)과 코드의 분리

React는 개발시 코드 안에 JSX가 포함되어 있습니다. 마크업부터 처음부터 다 개발하는 FE개발자라면 오히려 굉장한 장점일 수 있습니다. 하지만, 마크업 개발자와 FE 개발자가 협업해야하는 상황이라면 꽤나 불편한 환경일 수 있습니다. (물론, React에서는 복잡한 작업을 통해 JSX와 코드를 분리할 수 있습니다. 하지만,… 근본적으로 떼어내기는 쉬운일이 아닙니다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
render() {
var list = this.props.pagelist.map((v, i) => {
return <li key={i}><Link to={v.url}>{v.text}</Link></li>
});
return (
<div className="main-container">
<h1>{this.props.title}</h1>
<p>{this.state.message}</p>
<nav className="navbar navbar-default" role="navigation">
<div className="col-sm-7 col-sm-offset-2">
{list}
</div>
</nav>
{this.props.children}
</div>
);
}

하지만, Angular2에서는 다음과 같이 템플릿 자체를 별도의 파일로 관리 할 수 있습니다.

1
2
3
4
@Component({
templateUrl: 'app.component.html',
// ...
})

2. HTML 표준과 Web Component

React는 JSX라는 새로운 언어로 뷰를 만듭니다. 이 JSX 는 우리가 생각하는 마크업(HTML)과 비슷하지만, 다른 언어입니다.
예를 들어 JSX 는 꼭! 상위 루트가 있어야 합니다.

1
<rooot>...</root>

아래 같이 작성할 경우에는 에러가 발생합니다.

1
<root1>...</root1> <root2>...</root2>

더군다나, html의 class 속성도 중복되기 때문에 className으로 변경해서 사용해야합니다.

하지만, HTML 표준 마크업을 템플릿으로 사용하는 Angular2는 JSX의 제약이 전혀 없습니다. 더군다나 Web Component 를 지원하고 있기 때문에, Shadow DOM과 같이 뷰 단위로 css를 지정할수도 있습니다.

3. TypeScript

타입이 존재하지만. 존재하지 않는 언어

TypeScript를 지원하기 때문에 Angular2가 진입장벽이라고 이야기하시는 분이 많습니다. 사실, 저 또한 그랬습니다. 하지만, 좀 써보니 그렇지 않은 것 같습니다.
예를 들어, React에서는 Component의 prop에 타입을 지정합니다. 다음과 같습니다.

1
2
3
4
Main.propTypes = {
title: PropTypes.string.isRequired,
pagelist: PropTypes.array
};

자유도가 높은 JavaScript에서 왜 이런 작업을 하는 것일까요? 당연히 필요하기 때문입니다. Front-End 비중이 높아지면 질수록, 타입체크는 꼭 필요한 기능 중 하나인거죠.
하지만, TypeScript는 다음과 같이 코드에서 부터 타입을 명시할수 있습니다.

1
2
var title: string;
var pagelist: string[];

가장 좋은 점은 타입을 지정하는 것이 꼭! 필수는 아니다는 것입니다. 그래서 TypeScript로 개발을 하더라도 그냥 JavaScript와 같이 쓸수 있습니다.

미래를 준비하는 언어

React를 쓰려면 JSX를 변경하기 위해 transpile 과정을 꼭! 해야만 합니다. 그래서 일반적으로는 ES6 까지 함께 적용하여 개발을 합니다.
Angular2가 사용하는 TypeScript 또한 꼭! transplie 과정을 거칩니다. 어차피 개발환경에서 하는 일은 동일합니다.
하지만, TypeScript는 아래와 같이 ES5,6 기본 스펙을 포함하고 있고, 더불어 annotations과 type을 가지고 있습니다. ES2017에서 decorator, async와 같은 스펙이 이미 논의되고 있습니다. 이 부분이 TypeScript를 사용하게 되면 미리 사용할 수 있는 장점이 있습니다. 즉, 최신의 ECMAScript 를 사용할 수 있다는 것입니다.

4. 프레임워크 내에서의 설계

Angular1은 controller, service, directive등과 DI(Dependency Injection) 방식을 제공하여 많은 면에서 정해진 룰(?)에 의해 개발을 할 수 있는 장점이 있습니다. 반면, React는 Flux나 Redux와 같은 데이타 플로우 설계에 대한 많은 선택지가 있습니다.
많은 선택지가 있다는 것은 선택을 해야하는 자유도가 높아 유연성이 좋다는 의미이기도 하지만, 다른 한편으로는 올바른 선택을 하기 위해서는 많은 경험과 높은 이해도가 필요하다는 이야기 입니다.

Angular2는 Angular1과 React의 중간점에 있다고 생각됩니다. React와 다르게 프레임워크이기 때문에, 어느 정도 정해진 플로우를 사용하면서, Flux, Redux, RxJS와 같은 것을 유연하게 적용할수도 있습니다.

5. 브라우저 벤더 “구글”

Angular2는 구글 주도하에 개발되고 있는 Front-End 프레임워크입니다. 브라우저를 만드는 구글이기 때문에, Angular2에도 브라우저의 표준을 따르려고 하는 모습이 보입니다. 기본적으로 사용하는 템플릿도 HTML표준이고, 컴포넌트들의 모습도 Web Component를 지향하고 있으며, 심지어 애니메이션 처리하는 부분도 Web Animation API를 지향하고 있습니다.
물론, Facebook의 React도 그 행보가 유사하지만, 구글과 같이 민첩하고 직접적으로 표준을 지켜나가는 모습은 아닙니다.

간단한 페이지들은 오히려 프레임워크를 도입하지 않는 것이 더 효과적입니다. 하지만, 만약 프레임워크를 도입한다면, React뿐만 아니라, Angular2도 함께 고려해보는 것도 좋을것 같습니다.
참고로 Angular2는 2016말 정식릴리즈를 준비중이며, 현재는 RC.4까지 진행되었습니다.

Comment and share

Angular2가 낯선 이유

TypeScript를 기본으로 개발하는 Angular2가 생소하게 느껴지는 것은 당연한 일 일지도 모른다. 하지만, 그것보다 Angular2가 더 낯설게 느껴지는 이유는 Angular2에서만 사용하는 이상한 기호들([], (), [()], *, #) 때문이다.

Binding

angular1의 장점이 Two-way binding이자, 단점 또한 Two-way binding이다. Two-way binding으로 사용성은 증가했지만, 이로 인해, 성능의 단점이 생기게 된 것이다.
Angular2에서는 이러한 단점을 줄이고자, 이상한 기호들([],(),[()])을 이용하여 다양한 binding을 제공한다.

One-way binding

  • model에서 view로의 One-way binding은 { {} }, [], bind-target을 사용한다.
  • view에서 model로의 One-way binding은 (), on-target을 사용한다. 주로 이벤트가 그 대상이다.

Two-way binding

  • model과 view의 Two-way binding은 [()], bindon-target을 사용한다.

참고URL : https://angular.io/docs/ts/latest/guide/template-syntax.html#!#binding-syntax

* (star)

Angular 예제에서 처음 접하게되는 *ngFor의 예는 그냥 쓰이기에는 쉬운 것 같지만, 왜 *를 붙이지라고 생각해보면 꽤 이상하다는 것을 느낄 수 있다.
angular에서는 데이터를 순환하여 화면에 표현하고자 한다면 다음과 같이 작성한다.

1
<div *ngFor="let hero of heroes">{{hero.fullName}}</div>

*는 사용하기 쉽게 쓰기 위한, sugar code이다. ngFor, ngIf, ngSwitch와 같이 DOM 변경이 필요한 디렉티브인 경우에는 template 디렉티브를 사용 한다. 즉 위의 코드는 다음과 같이 사용한다.

1
2
<!-- template 디렉티브 property 로 값을 전달 -->
<div template="ngFor:let hero of heroes">{{hero.fullName}}</div>

또는

1
2
3
4
<!-- template 디렉티브에 직접 값을 전달 -->
<template [ngFor]="let hero of heroes">
<div>{{hero.fullName}}</div>
</template>

하지만, *를 사용하면 다음과 같이 간단히 사용할 수 있다.

1
<div *ngFor="let hero of heroes">{{hero.fullName}}</div>

참고URL : https://angular.io/docs/ts/latest/guide/template-syntax.html#!#star-template

# (sharp)

Angular2에서 보는 다음 코드역시 낯설다.

1
<input #box (keyup)="0" />

우선 여기서 #은 CSS Selector에 익숙한 사용자라면, 아이디를 지정하는 것인가? 라고 생각할 수 있겠지만, 실제 이 #의 의미는 다르다.

#box템플릿 내에서 사용하는 input 엘리먼트 인스턴스 자신을 가리키는 변수이다. 즉, Template reference variables 이다.

1
<p>{{box.value}}</p>

따라서, 위와 같이 사용하면, input 엘리먼트. 즉, HTMLInputElement의 value를 가리킨다.

다만, 여기서 주의할 것은 Template reference variables는 바인드가 되어 있지 않으면, 사용할 수 없다.
따라서, 위의 코드 처럼 keyup 이벤트에 가장 간단한 표현인 "0"을 의도적으로 바인딩 시킨다.

실제 템플릿 코드는 다음과 같이 사용할 수 있다.

1
2
<input #box (keyup)="0" />
<p>{{box.value}}</p>

Comment and share

  • page 1 of 1
Author's picture

sculove

아내와 아들 그리고 딸밖에 모르는 남편


FrontEnd Developer


대한민국/서울