polymer따라잡기

29
POLYMER 이해하기 한정현 SK planet [email protected]

Upload: han-jung-hyun

Post on 14-Jul-2015

446 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: Polymer따라잡기

POLYMER 이해하기한정현 SK planet

[email protected]

Page 2: Polymer따라잡기

POLYMER ?• https://www.polymer-project.org/

• 사전적인 의미 : 중합체, 고분자

• 2013.07.11 Pre-release( stable version ) 현재 0.5.2 ( 2015.01.14 기준)

• 2014년 Google 이 공개한 새로운 타입의 Web을 위한 라이브러리 (?)( webcomponents를 만드는.. )

• HTML을 확장해서 재사용이 가능한 custom element 제공

• JS 라이브러리들 안에서만 이용 가능했던 확장성과 캡슐화를 제공

• Shadow Dom, Custom Elements, 모델 기반 view를 포함한 최신 기술 적용

• 빠르고 쉽게 web 어플리케이션 제작 가능

• 현재 최신 browser에서 native 로 polymer features 채택중

• 라이센스 : BSD License

Page 3: Polymer따라잡기

WEBCOMPONENTS?• 쉽고 안정적으로 재사용 할 수 있는 위젯을 만들기 위해 HTML/CSS/JS 지식을 활용 할수 있도록 하는 사양의 집합

• 다시 말하면, 웹 문서 및 어플리케이션 안에서 재사용 가능한 위젯을 만들기 위한것 !

• 각 HTML elements 안에서 encapsulation & interoperability 가능하게 하는것

• 내부 구현 때문에 Component가 다음 버전으로 바뀌어도 Page는 변경 할 필요가 없다.

• http://www.w3.org/wiki/WebComponents/

• 현재 W3C에서 표준화가 진행중

• WebApps -> WebComponents 로 변경

• Chromium 프로젝트에서 blink 에 구현중 http://www.chromium.org/blink/web-components

• Mozilla 는 Brick! : http://brick.mozilla.io/ , http://mozbrick.github.io/brick-tabbar/

✴ 즉 Polymer 가 Web Components(?) Polymer는 Web Components를 구현 하기 위한 도구 (google 개발자가 주도?)

Page 4: Polymer따라잡기

WEBCOMPONENTS MAIN ELEMENTS-1

• WebComponents 를 지탱하는 메인 요소 4개

• Custom Elements

• http://w3c.github.io/webcomponents/spec/custom/

• 사용자에 의해 정의된 Element

• Shadow DOM

• vs Composed DOM ( Rendered DOM) : 렌더링을 안해도 됨

• http://w3c.github.io/webcomponents/spec/custom/,

• http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/

• Document Tree 에 Shadow Host 가 존재 하며 해당 host 가 shadow dom의 root

• Presentation에서 content를 분리 목적

Page 5: Polymer따라잡기

WEBCOMPONENTS MAIN ELEMENTS-2

• HTML Imports

• http://w3c.github.io/webcomponents/spec/imports/

• HTML 문서를 외부자원 처럼 링크 하는 것

• link 요소의 “import” 타입 사용

• ex: < link rel=“import” href=“/imports/newHTML.html”>

• HTML Template

• https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html

• <template> Element : document fragment ( Document 안에 없다는 의미 )

• 사용자가 활성화하기 전까지는 마크업 안에서 비활성화

• JS 를 안에 저장 시킬수는 있지만, 필요할때까지 실행하지 않음

Page 6: Polymer따라잡기

CUSTOM ELEMENTS• 사용자에 의해 직접 정의 될수 있음

• ex: ) HTML :

• ex: ) JS :

• 표준 DOM 메소드로 만들수 있으며, 이벤트를 붙히거나, 프로퍼티에 접근 하거나, CSS 를 입히는것도 가능

• document.registerElement를 이용해서 사용도 가능

<kazikai-element></kazikai-element>

var kazikaiEl = document.createElement( “kazikai-element” );kazikaiEl.innerHTML = “Hello world kazikai”;

var kazikaiElement = document.registerElement( “kazikai-element” );var kazikaiEl = new kazikaiElement();

Page 7: Polymer따라잡기

SHADOW DOM• 목적은 컨텐츠와 프리젠테이션 영역을 분리 ( Polymer 에서는 <template> 태그 안에 있는 부분이 shadow dom)

• shadow dom 은 3개의 서브 트리로 표현 가능

• light DOM:

• custom element를 이용해서 만든 dom

• 사용자에게는 DOM에서 일반적인 서브트리로 보여짐

• shadow DOM ( by document-fragment )

• custom element가 정의되어 shadow root 에 붙혀진 DOM

• 숨겨져 있으며 custom element 의 자식 노드가 아니다.

• composed DOM ( = light DOM + shadow DOM )

• 렌더링 된 DOM, 브라우저에서 실제로 보여지는 부분

Page 8: Polymer따라잡기

HTML IMPORTS• 다른 HTML 문서에서 HTML문서를 재활용 하는 방법

• <script> 태그처럼 외부에서 불러와서 활용

• <link rel =“import” href=“my-custom-element.html”>

• Feature detection 방법 : chrome 31+, 36+에서 최신 스펙 적용 or Polyfill사용

• Load / Error 에 이벤트 걸기

function supportsImports() { return 'import' in document.createElement('link');}if (supportsImports()) { // Good to go!} else { // Use other libraries/require systems to load files.}

<script async> function handleLoad(e) { console.log('Loaded import: ' + e.target.href); } function handleError(e) { console.log('Error loading import: ' + e.target.href); }</script><link rel="import" href=“file.html" onload="handleLoad(event)" onerror="handleError(event)">

Page 9: Polymer따라잡기

TEMPLATES• http://webcomponents.org/articles/introduction-to-template-element/

• https://html.spec.whatwg.org/multipage/scripting.html#the-template-element

• PHP, Django, Ruby on Rails 등등 서버기반 기술에서 주로 사용

• 클라이언트 기반 에서는 주로 mustach.js, handlebars.js, angular.js, backbone.js 등 이 있음

• tempalte을 구동안 정의했던 방식

• div 방식: <div sytle=“display:none”><div>

• script방식 <scritp type=“text/x-handlebars-template></script>

• 결국 렌더링 되지 않고 js/css 를 포함 할수있는 HTML 요소 기반의 template을 만들자

• 그래서 만들어짐

• <tempalte></template>

Page 10: Polymer따라잡기

WEBCOMPONENTS POLYFILL

• 현존 하는 브라우저중에는 해당 Spec 을 지원하는 브라우저가 거의 없음

• Polyfill을 사용해서 해결 가능 하다. webcomponents.js ( http://webcomponents.org/ )

• $ bower install --save webcomponentsjs

• 원래 이름은 platform.js -> webcomponents.js

• https://blog.polymer-project.org/announcements/2014/10/16/platform-becomes-webcomponents

• Mozilla Bricks는 platform.js 사용( 2015.01.15기준)

• dependency (사실상 webcomponents.js 에 통합 되었기 때문에 없다고 보는것이 맞다..)

• weakmap ( ES6의 WeakMap type shim)

• Mutation Observers

Page 11: Polymer따라잡기

WEBCOMPONENTS BROWSER SUPPORT

https://www.polymer-project.org/resources/compatibility.html

엄밀히 말하자면, polymer 의 support 테이블이지만…..

Page 12: Polymer따라잡기

다시 POLYMER?

• Polymer 는 Web Components spec 으로 만들어짐

• 하루에 최소 3개 이상의 디바이스를 사람들은 사용함 -> 동일한 ui 를 각 디바이스에서 보여줄 수 있어야함

• WebComponents 의 Feature를 모두가지고있음

• Custom Element

• Shadow DOM

• HTML Import

• Template

• Everything is an Element === The Polymer world-view

• Functional, Reusable, Interoperable, Encapsulated, Configurable, Programmable, Event Generator, Composable

Page 13: Polymer따라잡기

POLYMER STRUCTUREhttps://github.com/polymer/pica

Page 14: Polymer따라잡기

POLYMER로 만든 예제

• 기본적인 custom element 를 활용

• http://codepen.io/kazikai/pen/dPvvpK

• Carousel

• http://addyosmani.github.io/polymer-ui-carousel/smoke.html

• Selector

• https://www.polymer-project.org/components/core-selector/demo.html

Page 15: Polymer따라잡기

POLYMER 10분만에 만들기-11. Polymer 설치

• Bower: 권장하는 방법: ( bower 는 node.js 가 설치 되어있어야 함 ) : http://bower.io/

• $ bower init

• $ bower install --save Polymer/polymer

• $ bower update ( 새버전 나왔을 경우 )

• zip

• https://www.polymer-project.org/docs/start/getting-the-code.html ( zip down )

• Github

• $ git clone https://github.com/Polymer/polymer.git components/polymer

Page 16: Polymer따라잡기

POLYMER 10분만에 만들기-22. Polymer element 만들기

1. polymer.html 로딩

2. <polymer-element> 를 이용해서 custom element 선언

<link rel="import" href="../bower_components/polymer/polymer.html">

<polymer-element name="my-element" noscript> <template> <span>Hello from <b>my-element</b>. This is my Shadow DOM.</span> </template></polymer-element>

Page 17: Polymer따라잡기

POLYMER 10분만에 만들기-33. 다른 element 사용 하기

• polymer-elment 안에 polymer-element를 사용 가능

• $ bower install Polymer/core-ajax<link rel="import" href="../bower_components/polymer/polymer.html"><link rel="import" href="../bower_components/core-ajax/core-ajax.html">

<polymer-element name="my-element" noscript> <template> <span>I'm <b>my-element</b>. This is my Shadow DOM.</span> <core-ajax url="http://example.com/json" auto response="{{resp}}"></core-ajax> <textarea value="{{resp}}"></textarea> </template></polymer-element>

Page 18: Polymer따라잡기

POLYMER 10분만에 만들기-44. app 만들기

• index.html 생성

• webcomponents.js 로딩 ( polyfill )

<!DOCTYPE html><html> <head> <!-- 1. Load platform support before any code that touches the DOM. --> <script src="bower_components/webcomponentsjs/webcomponents.js"></script> <!-- 2. Load the component using an HTML Import --> <link rel="import" href="elements/my-element.html"> </head> <body> <!-- 3. Declare the element by its tag. --> <my-element></my-element> </body></html>

Page 19: Polymer따라잡기

POLYMER STARTER PROJECT• Starter Project 다운 : https://github.com/Polymer/polymer-tutorial/archive/master.zip

• https://www.polymer-project.org/docs/start/tutorial/intro.html

• HTTP Server 실행

• 간단한 HTTP Server 실행이 필요 함 ( polymer 에서는 python으로 하는법을 추천, 개인적으로 http-server 선호

• python으로 하는법

• 2.x : $ python -m simpeHTTPServer

• 3.x : $ python -m http.server

• node로 하는 법

• $ npm install http-server

• $ http-served

Page 20: Polymer따라잡기

POLYMER CORE EVENT• Polymer 에서 주로 사용하는 기본 이벤트 (순서대로..created>ready>attached>domReady)

• created : element가 만들어 졌을때

• ready : <polymer-element> 가 완전히 준비 되었을때

• attached : DOM에 element 가 붙혀졌을때

• domReady : element 가 light DOM 밑에 존재 하는게 보장 될때

• detached : DOM에서 element 가 제거 될때

• attributeChanged: attribute가 추가/수정 될때Polymer('tag-name', { created: function() { ... }, ready: function() { ... }, attached: function () { ... }, domReady: function() { ... }, detached: function() { ... }, attributeChanged: function(attrName, oldVal, newVal) { //var newVal = this.getAttribute(attrName); console.log(attrName, 'old: ' + oldVal, 'new:', newVal); },});

Page 21: Polymer따라잡기

POLYMER DATA BINDING..<link rel="import" href="/bower_components/polymer/polymer.html"><polymer-element name="greeting-tag"> <!-- outermost template defines the element's shadow DOM --> <template> <ul> <template repeat="{{s in salutations}}"> <li>{{s.what}}: <input type="text" value="{{s.who}}"></li> </template> </ul> <button on-click="{{updateModel}}">Update model</button> <button on-click="{{changeModel}}">change model</button> </template> <script src="greeting-tag.js"></script></polymer-element>

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="bower_components/webcomponentsjs/webcomponents.js"></script> <link rel="import" href="elements/greeting-tag.html"></head> <body> <greeting-tag></greeting-tag></body></html>

var count =0;Polymer('greeting-tag', { ready: function() { this.salutations = [ {what: 'Hello', who: 'World'}, {what: 'Goodbye', who: 'DOM APIs'}, {what: 'Hello', who: 'Declarative'}, {what: 'Goodbye', who: 'Imperative'} ]; this.alternates = ['Hello', 'Hola', 'Howdy']; this.current = 0; console.log( "ready" ); }, updateModel: function() { this.current = (this.current + 1) % this.alternates.length; this.salutations[0].what = this.alternates[this.current]; }, changeModel: function(){ this.salutations[0].who = "kazikai" + count++; }, created: function() { console.log( "created" ); }, attached: function () { console.log( "attached" ); }, domReady: function() { console.log( "domReady" ); }, detached: function() { console.log( "detached" ); }, attributeChanged: function(attrName, oldVal, newVal) { console.log( "attributeChanged" ); //var newVal = this.getAttribute(attrName); console.log(attrName, 'old: ' + oldVal, 'new:', newVal); },});

main.html

greeting-tag.html

greeting-tag.js

Page 22: Polymer따라잡기

CSS 스타일링 하기• Shadow DOM 의 BODY 는 ::host

• :: host { display: block; backgroud:blue; }

• Shadow DOM의 Element 의 조상은 :host-context

• :host-context{ display: block; backgroud:blue; }

• Shadow DOM 안의 element style

• ::host <selector> { }

• Preventing FOUC ( FOUC : 외부 css 에 의해 웹페이지 렌더링 되기 전의 모습 )

• custom-element:unresolved{ }

• Light DOM 안에 있는 부분 컨트롤

• ::content <> {}

Page 23: Polymer따라잡기

기존에 있던 위젯을 POLYMER로 • 기존에 만들어져있던 JS 라이브러리 위젯을 Polymer 로 변환 시도 .

• 방법

• 간단히 main을 custom element 로 쪼갠다음 해당 custom element 생성

• 결과 ->실패

• 이유

• 특정 DOM SELECT가 전혀 안됨

• 대부분의 JS 라이브러리는 argument로 해당 dom의 id 값이나 class 값을 전달해줌)

• Shadow DOM은 기존의 DOM API로 선택이 불가능 하다. ( 결국 제어가 안됨 )

• CSS 도 문제

• CSS 는 inline 형태로 어느정도 해결은 가능 ( <template></template> 안에 <link> 요소 선언하면 가능)

Page 24: Polymer따라잡기

기존에 있던 위젯을 POLYMER로 • Polymer 내장 함수를 통해 해당 dom을 컨트롤 할 수 있음

• Polymer({ attached: function(){ //여기 코드 }});

• shadowRoot 를 활용해서 컨트롤

• var $shadow = $( this.shadowRoot );

• $shadow.find(“[selector]”) 로 하면 해당 shadow DOM 컨트롤 가능

• 또는 /deep/ combinator 사용

• var shadowDomElement = document.querySelector(“body /deep/ [selector] “);

• var $shadowDomEl = $( “body /deep/ [selector]” );

• CSS 도 동일

• body /deep/ [selector] { color ; #fff; }

Page 25: Polymer따라잡기

기존에 있던 위젯을 POLYMER로 • 결국 기존에 있던 js 기반 라이브러리 위젯은 polymer 로 쉽게 포팅 불가능

• shadow dom 을 컨트롤 하는 방법이 있지만… 철학에 맞지 않는다고 판단 ( 독립성 )

• /deep/ 을 사용 하면 CSS 캡슐화를 무시함

• 또한 js 로 외부 DOM에서 shadow DOM을 컨트롤 하는 방식은 기존 Polymer 의 철학과는 다름

• Custom Element 가 변경되면 해당 페이지의 UI 가 변경될 가능성이 존재함

• 결론적으로 기존에 있던 js 기반 라이브러리는 polymer로 개발할경우 polymer 포맷에 맞게 다시 개발해야함

Page 26: Polymer따라잡기

기존 웹사이트 쪼개기• 앞에서 말했던 것처럼 기존의 반응형 웹 사이트를 Polymer 로 쪼개 보자

• 새롭게 css/js 를 만드는게 아니라.. /deep/ ::shadow 만을 이용해서 단순히 쪼개기

• 최종적으로 보이는 Output 은 ( Polymer vs not Polymer )

• 대상

• Landy 사이트 템플릿

• https://github.com/paolotripodi/Landy-v1.0

• header/nav/section 별로 나눠져 있으며, 반응형 페이지라 시도 해봄

• 결과물

• https://github.com/kazikai/Landy-v1.0

Page 27: Polymer따라잡기

쪼갠 결과• 메인 HTML 기준 ( index.html vs polymer-index.html ) Polymer 가 훨씬 깔끔한 형태의 HTML 을 보여줌

• CSS/JS 부분의 Shadow DOM 컨트롤 부분 필요에 의한 JS/CSS 수정

• 전체적인 구조만 변경 해보려고했던 작업이라. body /deep/ 일괄적용

• 외부 라이브러리 수정 불가능

• bootstrap.min.css 와 같은 외부 라이브러리는 수정 불가능 -> layout 일부 깨짐

• bootstrap.min.js 도 수정 불가능-> 애니메이션 작동 불가능

• img/css 파일은 파일 구조가 달라짐에 따라 수정이 필요

Page 28: Polymer따라잡기

결론

• 기존의 순수 HTML/CSS/JS 로 제작된 사이트가 Polymer 로 변경 되려면 많은 노력이 필요함

• Polymer는 적용 하려면 개발 초기부터 적용 되어야만 함

• 적용만 하면 유지/보수가 기존의 HTML보다 편할 것이라 생각 되며 main HTML 페이지가 훨씬 간결해짐

• 단 적용하더라도 webcomponents 의 철학에 맞게 사용해야함

• /deep/ ::shadow 와 같이 외부에서 내부 shadowDOM 을 컨트롤 할수있지만. 결국 유지보수가 어려워지며

• Polymer 가 가진 장점을 잃어버림

• 성능적인 부분에서는 모바일에서 많이 느림

• Browser도 일부만 지원하니 상용화에 바로 적용하는것은 무리가 있음

Page 29: Polymer따라잡기

감사합니다. • 참조

• https://www.polymer-project.org/

• http://webcomponents.org/

• http://mozbrick.github.io/

• http://www.w3.org/wiki/WebComponents/