2. 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
3. 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 개발자가 주도?)
4. 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/
• DocumentTree 에 Shadow Host 가 존재 하며 해당 host 가 shadow dom의 root
• Presentation에서 content를 분리 목적
5. WEBCOMPONENTS
MAIN ELEMENTS-2
• HTML Imports
• http://w3c.github.io/webcomponents/spec/imports/
• HTML 문서를 외부자원 처럼 링크 하는 것
• link 요소의 “import” 타입 사용
• ex: < link rel=“import” href=“/imports/newHTML.html”>
• HTMLTemplate
• https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html
• <template> Element : document fragment ( Document 안에 없다는 의미 )
• 사용자가 활성화하기 전까지는 마크업 안에서 비활성화
• JS 를 안에 저장 시킬수는 있지만, 필요할때까지 실행하지 않음
6. 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();
7. 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, 브라우저에서 실제로 보여지는 부분
8. 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)">
10. 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
12. 다시 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
14. 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
15. POLYMER 10분만에 만들기-1
1. 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
16. POLYMER 10분만에 만들기-2
2. 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>
17. POLYMER 10분만에 만들기-3
3. 다른 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>
18. POLYMER 10분만에 만들기-4
4. 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>
19. 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
20. 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);
},
});
22. 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 <> {}
23. 기존에 있던 위젯을 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> 요소 선언하면 가능)
24. 기존에 있던 위젯을 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; }
25. 기존에 있던 위젯을 POLYMER로
• 결국 기존에 있던 js 기반 라이브러리 위젯은 polymer 로 쉽게 포팅 불가능
• shadow dom 을 컨트롤 하는 방법이 있지만… 철학에 맞지 않는다고 판단 ( 독립성 )
• /deep/ 을 사용 하면 CSS 캡슐화를 무시함
• 또한 js 로 외부 DOM에서 shadow DOM을 컨트롤 하는 방식은 기존 Polymer 의 철학과는 다름
• Custom Element 가 변경되면 해당 페이지의 UI 가 변경될 가능성이 존재함
• 결론적으로 기존에 있던 js 기반 라이브러리는 polymer로 개발할경우 polymer 포맷에 맞게 다시 개발해야함
26. 기존 웹사이트 쪼개기
• 앞에서 말했던 것처럼 기존의 반응형 웹 사이트를 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
27. 쪼갠 결과
• 메인 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 파일은 파일 구조가 달라짐에 따라 수정이 필요
28. 결론
• 기존의 순수 HTML/CSS/JS 로 제작된 사이트가 Polymer 로 변경 되려면 많은 노력이 필요함
• Polymer는 적용 하려면 개발 초기부터 적용 되어야만 함
• 적용만 하면 유지/보수가 기존의 HTML보다 편할 것이라 생각 되며 main HTML 페이지가 훨씬 간결해짐
• 단 적용하더라도 webcomponents 의 철학에 맞게 사용해야함
• /deep/ ::shadow 와 같이 외부에서 내부 shadowDOM 을 컨트롤 할수있지만. 결국 유지보수가 어려워지며
• Polymer 가 가진 장점을 잃어버림
• 성능적인 부분에서는 모바일에서 많이 느림
• Browser도 일부만 지원하니 상용화에 바로 적용하는것은 무리가 있음