SlideShare a Scribd company logo
1 of 57
Download to read offline
컴포넌트 관점에서 개발하기
2017 프론트엔드 트렌드&인사이트
주우영
프런트엔드 개발 시작하기
네이버는 이렇게 한다!, 위키북스
JavaScript Promise
한빛 eBook, 한빛미디어
페이스북 프론트엔드개발 그룹 운영
https://www.facebook.com/groups/webfrontend/
레진엔터테인먼트 프론트엔드개발팀
오늘, 새로운 기술과
기능을 나열하기 보다
현대 UI 개발에 있어 중요히
여기는 부분에 대해 이야기합니다.
현대 프레임워크의 공통된 접근법
컴포넌트 단위로 사고하고 디자인
import {Component} from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h1>Welcome to {{title}}</h1>
`,
styles: [`
h1 {
font-size: 4em;
}
`]
})
export class AppComponent {
title = 'app';
}
import {Component} from 'react';
const style = {
fontSize: '4em'
};
class HelloMessage extends Component {
static defaultProps = {
title: 'React'
};
render() {
return (
<h1 style={style}>
Welcome to {this.props.title}
</h1>
);
}
}
<style scoped>
h1 {
font-size: 4em;
}
</style>
<template>
<h1>Welcome to {{title}}</h1>
</template>
<script type="text/babel">
export default {
data () {
return {
title: 'Vue'
}
}
}
</script>
<dom-module id="hello-element">
<template>
<style>
h1 {font-size: 4em}
</style>
<h1>Welcome to {{title}}</h1>
</template>
<script>
class HelloElement extends Polymer.Element {
static get is() {return "hello-element";}
constructor() {
super();
this.title = "Polymer";
}
}
customElements.define(HelloElement.is, HelloElement);
</script>
</dom-module>
WHY
COMPONENT?
하나의 문제를 잘 해결하는
COMPONENT
프로그램
새로운 방법이 아닌
예로부터 모든 공학 분야의
공학자가 자주 사용해 오던
문제 해결 방법
Unix Philosophy
Write programs that do one thing and do it well.
Write programs to work together.
Doug Mcllroy, Unix pipeline inventor
The UNIX Philosophy in 9 paramount precepts
Mike Gancarz (a member of the team that designed the X Window System)
Small is beautiful.
Make each program do one thing well.
Write programs handle text streams, because that is a universal interface.
$ ps -ef
Processes Status
Report a snapshot of the current processes
$ grep gradle
Globally search a regular expression and print
Searching plain-text data sets for lines that match a regular expression
$ ps -ef | grep gradle
사고의 분산을 막고 하나의 문제에 집중함으로써
효율적으로 개발할 수 있다
설계의 오류를 쉽게 파악할 수 있고
상대적으로 테스트하기 쉽다
이식성을 높일 수 있고
변경에 유연하게 대체할 수 있다
API
UI는 자주적으로 동작하는 또 다른 프로그램,
그것을 API로 제어한다는 사고로 접근
자바스크립트를 개발할 때 우리는
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
DOM을 직접 핸들링, 장황하고 UI의 형태를 한눈에
파악하기 힘듦
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
상태를 class나 data attr에 설정 및 사용하여
전체적인 상태 흐름을 알기 힘듦
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
DOM API의 비용은 비쌈. 상태 변화를 위해 

DOM API 호출이 남용됨
_changeTabs() {
const fragment = this._parseFragment();
if (fragment === null) {
return;
}
_.each(fragment, (value, key) => {
const target = $(_.find(this.$sections, i => {
return $(i).dataset('type') === key);
});
// 선택한 탭으로 변경한다.
target.find('.cs-tab li').removeClass('is-on');
target.find('.cs-tab li')
.has(`a[href='#${value}']`).addClass('is-on');
// 탭에 해당하는 목록으로 변경한다.
target.find('.cs-body').removeClass('is-on');
target.find(`.cs-body#cs-${key}-${value}`)
.addClass('is-on');
});
}
UI 상태 변화를 위한 render 외의 부가적 메서드
다량 정의
프리젠테이션 로직은 크고 복잡.
테스트하고 유지보수하기 괴롭다
Functional Programming
컴포넌트 접근법은 함수형 프로그래밍하고도 관련이 깊다
부작용(Side effect)없이 하나의 일을 잘 수행하는 함수
그러한 함수를 조합 / 구성함으로써 큰 문제를 해결
F2 F3 F4 F5F1
{

“type”: “oval”,

“size”: 32

}
Functional Programming and UI Component
View = Function(state)
function Header({title, desc}) {
return (
<header className="header">
<div className="header__inner">
<h1 className="header__title">{title}</h1>
<p className="header__description">{desc}</p>
</div>
</header>
);
}
View = Function(state)
REMEMBER
Header({
title: 'Hello World!',
desc: 'This is Awesome.'
});
<header class="...">
<div class="...">
<h1 class="...">Hello World!</h1>
<p class="...">This is Awesome.</p>
</div>
</header>
<header class="...">
<div class="...">
<h1 class="...">Hello World!</h1>
<p class="...">This is Awesome</p>
</div>
</header>
<header class="...">
<div class="...">
<h1 class="...">Welcome</h1>
<p class="...">This is Awesome</p>
</div>
</header>
Equal?
<header class="...">
<div class="...">
<h1 class="...">Hello World!</h1>
<p class="...">This is Awesome</p>
</div>
</header>
<header class="...">
<div class="...">
<h1 class="...">Welcome</h1>
<p class="...">This is Awesome</p>
</div>
</header>
Equal?
<header class="...">
<div class="...">
<h1 class="...">Hello World!</h1>
<p class="...">This is Awesome</p>
</div>
</header>
<header class="...">
<div class="...">
<h1 class="...">Welcome</h1>
<p class="...">This is Awesome</p>
</div>
</header>
Equal? FAIL
Snapshot Testing with Jest
HTML(TMPL), CSS, 자바스크립트를 분리하는게
당연한 관심사의 분리라고 생각
과거 우리는.
Templates separate technologies, not concerns.
템플릿은 기술의 분리일 뿐 관심사의 분리가 아니다.
Pete Hunt, React developer
페이트 헌트, 리액트 개발자
“
”
KingCard Component
중요한건 해결하고자 하는 문제
같은 문제를 해결한다면 관심사는 같다
이때, 분리된 환경 보다
한 곳에 있는 경우가 훨씬 수월하다
관심사가 같다면 수정 시,
함께 수정해야 할 확률이 높다
HTML, CSS를 어떻게든 셋팅한 후
자바스크립트를 이어서 테스트
UI 테스트에 대한 자원 준비 없이
곧바로 컴포넌트를 테스트
Test IconText Component
it('iconDirection 속성에 left를 지정하면 아이콘이 좌측에 배치된다.', () => {
// Given
// When
const wrapper = shallow(
<IconText
label="친구초대"
icon="add-friend"
iconDirection="left"
/>
);
// Then
const children = wrapper.children('.icon-text__inner').children();
expect(children.first()).to.have.className('icon-text__icon');
expect(children.last()).to.have.className('icon-text__label');
});
"## Header
$ "## Header.js
$ "## Header.test.js
$ %## style.scss
"## TallCard
$ "## TallCard.js
$ "## TallCard.test.js
$ %## style.scss
"## KingCard
$ "## KingCard.js
$ "## KingCard.test.js
$ %## style.scss
%## StickyBar
"## StickyBar.js
"## StickyBar.test.js
%## style.scss
따라서 관련있는 것은
최대한 가까이에 두는
구조가 현재 유행
const Button = (props) => (
<button className={'large' in props && 'large'}>
{props.children}
<style jsx>{`
button {
padding: 20px;
background: #eee;
color: #999
}
.large {
padding: 50px
}
`}</style>
</button>
);
또는 하나의 파일 내 모든 관심사를
작성하는 방식도 선호
뭘 좀 만들어 봅시다.
이런 UI를 개발해 달라고 했을때
가장 먼저 한가지 일을 수행하는
최소 단위를 분석
뭘 좀 만들어 봅시다.
이런 UI를 개발해 달라고 했을때
가장 먼저 한가지 일을 수행하는
최소 단위를 분석
뭘 좀 만들어 봅시다.
이런 UI를 개발해 달라고 했을때
가장 먼저 한가지 일을 수행하는
최소 단위를 분석
뭘 좀 만들어 봅시다.
이런 UI를 개발해 달라고 했을때
가장 먼저 한가지 일을 수행하는
최소 단위를 분석
<TallCard/>
를 만들어 봅시다.
BEM(Block, Element, Modifier)
컴포넌트와 어울리게 마크업하기
Block
애플리케이션의 구성 요소로서 독립된 존재
Element
블록을 구성하는 작은 단위 또는 자식 개체
Modifier
블록이나 요소의 테마, 동작을 표현
Block
TallCard
Element
Information
Modifier
BadgeUp
Thumbnail
tall-card
tall-card__badge
tall-card__badge-up
tall-card__thumbnail
tall-card__image
tall-card__information
tall-card__title
tall-card__meta
tall-card__meta-key
tall-card__meta-value
BEM tree
BEM(Block, Element, Modifier)
컴포넌트와 어울리게 마크업하기
<div class="tall-card tall-card_badge_up">
<div class="tall-card__badge">
<i class=“tall-card__badge-up">
<span class="blind">UP</span>
</i>
</div>
<div class="tall-card__thumbnail">
<img class="tall-card__image" src="" alt=""/>
</div>
<div className="tall-card__information">
<h5 className="tall-card__title">레바툰</h5>
<dl class="tall-card__meta">
<dt class=“tall-card__meta-key">장르</dt>
<dd class=“tall-card__meta-value">개그 / 일상</dd>
<dt class=“tall-card__meta-key">작가</dt>
<dd class=“tall-card__meta-value">레바</dd>
</dl>
</div>
</div>
Markup with BEM
const TallCard = ({title, image, badge, metadata = []}) => (
<div className={`tall-card ${badge === 'up' ? ‘tall-card_badge_up' … `}>
<div className="tall-card__badge">
<i className=“tall-card__badge-up”/>
</div>
<div className="tall-card__thumbnail">
<img className="…" src={image} alt={`${title}의 썸네일`}/>
</div>
<div className="tall-card__information">
<h5 className="tall-card__title">{title}</h5>
{metadata.length > 0 ? (
<dl className=“tall-card__meta">
${metadata.map(({key, value}) => ([
<dt className=“tall-card__meta-key">{key}</dt>,
<dt className=“tall-card__meta-key">{value}</dt>
]))}
</dl>
) : null}
</div>
</div>
);
Create React Component
$module: 'icon-text';
.#{$module} {
&__badge {
/*...*/
&__up {/*...*/}
}
&__thumbnail {
/*...*/
&__image {/*...*/}
}
&__information {/*...*/}
&__title {/*...*/}
&__meta {/*…*/}
&__meta-key {/*...*/}
&__mata-value {/*...*/}
}
Styling with SASS
SASS의 interpolation은
컴포넌트 접근법과 잘 어울린다
스타일링 영역을 문법적으로
명확히 표현할 수 있다
"## TallCard
"## TallCard.js
%## TallCard.scss
"## TallCard
"## TallCard.js
"## TallCard.html
%## TallCard.scss
File structure
마크업 코드를 템플릿으로 분리한 경우
마크업을 자바스크립트에 포함한 경우
Context Free
<CardGroup/><SquareCard/> type = subscriptions
상위 컴포넌트 스타일이 하위 컴포넌트 스타일에 영향을 주면 안된다
컴포넌트는 어떤 문맥에서든 자유로워야 한다
badge = up sensational = true
만약 특정 문맥에서 컴포넌트가 변화한다면 해당 컴포넌트에
Context Free
<SquareCard/>
badge = new
새로운 변환자(Modifier)를 추가한다
Context Free
<CardGroup/>
CardList 컴포넌트는 badge가 up인 SquareCard 컴포넌트를
자식 컴포넌트로 포함하고 있을 뿐이다
type = subscriptions
타인의 잣대에 얽매이면 행복할 수 없듯
컴포넌트 역시 특정 문맥에 얽매이면
행복할 수 없다
감사합니다.

More Related Content

What's hot

golang과 websocket을 활용한 서버프로그래밍 - 장애없는 서버 런칭 도전기
golang과 websocket을 활용한 서버프로그래밍 - 장애없는 서버 런칭 도전기golang과 websocket을 활용한 서버프로그래밍 - 장애없는 서버 런칭 도전기
golang과 websocket을 활용한 서버프로그래밍 - 장애없는 서버 런칭 도전기Sangik Bae
 
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트) 마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트) Amazon Web Services Korea
 
[125]웹 성능 최적화에 필요한 브라우저의 모든 것
[125]웹 성능 최적화에 필요한 브라우저의 모든 것[125]웹 성능 최적화에 필요한 브라우저의 모든 것
[125]웹 성능 최적화에 필요한 브라우저의 모든 것NAVER D2
 
Introduction to angular with a simple but complete project
Introduction to angular with a simple but complete projectIntroduction to angular with a simple but complete project
Introduction to angular with a simple but complete projectJadson Santos
 
리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션QooJuice
 
Massive service basic
Massive service basicMassive service basic
Massive service basicDaeMyung Kang
 
코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)
코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)
코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)Suhyun Park
 
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...Edureka!
 
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceKGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceXionglong Jin
 
React JS - A quick introduction tutorial
React JS - A quick introduction tutorialReact JS - A quick introduction tutorial
React JS - A quick introduction tutorialMohammed Fazuluddin
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향Young-Ho Cho
 
마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기Jaewoo Ahn
 
3. 마이크로 서비스 아키텍쳐
3. 마이크로 서비스 아키텍쳐3. 마이크로 서비스 아키텍쳐
3. 마이크로 서비스 아키텍쳐Terry Cho
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기현철 조
 
신입 웹 개발자 포트폴리오 / 댓글 게시판
신입 웹 개발자 포트폴리오 / 댓글 게시판신입 웹 개발자 포트폴리오 / 댓글 게시판
신입 웹 개발자 포트폴리오 / 댓글 게시판hyeonjae Cheon
 
도메인 주도 설계의 본질
도메인 주도 설계의 본질도메인 주도 설계의 본질
도메인 주도 설계의 본질Young-Ho Cho
 

What's hot (20)

golang과 websocket을 활용한 서버프로그래밍 - 장애없는 서버 런칭 도전기
golang과 websocket을 활용한 서버프로그래밍 - 장애없는 서버 런칭 도전기golang과 websocket을 활용한 서버프로그래밍 - 장애없는 서버 런칭 도전기
golang과 websocket을 활용한 서버프로그래밍 - 장애없는 서버 런칭 도전기
 
NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
 
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트) 마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
마이크로서비스 기반 클라우드 아키텍처 구성 모범 사례 - 윤석찬 (AWS 테크에반젤리스트)
 
[125]웹 성능 최적화에 필요한 브라우저의 모든 것
[125]웹 성능 최적화에 필요한 브라우저의 모든 것[125]웹 성능 최적화에 필요한 브라우저의 모든 것
[125]웹 성능 최적화에 필요한 브라우저의 모든 것
 
Introduction to angular with a simple but complete project
Introduction to angular with a simple but complete projectIntroduction to angular with a simple but complete project
Introduction to angular with a simple but complete project
 
리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션리플렉션과 가비지 컬렉션
리플렉션과 가비지 컬렉션
 
An Overview on Nuxt.js
An Overview on Nuxt.jsAn Overview on Nuxt.js
An Overview on Nuxt.js
 
Massive service basic
Massive service basicMassive service basic
Massive service basic
 
코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)
코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)
코딩 테스트 및 알고리즘 문제해결 공부 방법 (고려대학교 KUCC, 2022년 4월)
 
Introduction to NodeJS
Introduction to NodeJSIntroduction to NodeJS
Introduction to NodeJS
 
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
 
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceKGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
 
React JS - A quick introduction tutorial
React JS - A quick introduction tutorialReact JS - A quick introduction tutorial
React JS - A quick introduction tutorial
 
[수정본] 우아한 객체지향
[수정본] 우아한 객체지향[수정본] 우아한 객체지향
[수정본] 우아한 객체지향
 
마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기마이크로서비스 아키텍처로 개발하기
마이크로서비스 아키텍처로 개발하기
 
3. 마이크로 서비스 아키텍쳐
3. 마이크로 서비스 아키텍쳐3. 마이크로 서비스 아키텍쳐
3. 마이크로 서비스 아키텍쳐
 
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
 
신입 웹 개발자 포트폴리오 / 댓글 게시판
신입 웹 개발자 포트폴리오 / 댓글 게시판신입 웹 개발자 포트폴리오 / 댓글 게시판
신입 웹 개발자 포트폴리오 / 댓글 게시판
 
Angular
AngularAngular
Angular
 
도메인 주도 설계의 본질
도메인 주도 설계의 본질도메인 주도 설계의 본질
도메인 주도 설계의 본질
 

Viewers also liked

비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기jeong seok yang
 
퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다jeong seok yang
 
퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다jeong seok yang
 
하코사세미나_캔버스 파이그래프 만들기
하코사세미나_캔버스 파이그래프 만들기하코사세미나_캔버스 파이그래프 만들기
하코사세미나_캔버스 파이그래프 만들기정석 양
 
JavaScript 2014 프론트엔드 기술 리뷰
JavaScript 2014 프론트엔드 기술 리뷰JavaScript 2014 프론트엔드 기술 리뷰
JavaScript 2014 프론트엔드 기술 리뷰Kenu, GwangNam Heo
 
나의 jQuery 실력 향상기
나의 jQuery 실력 향상기나의 jQuery 실력 향상기
나의 jQuery 실력 향상기정석 양
 
프론트엔드 개발자의 자바스크립트
프론트엔드 개발자의 자바스크립트 프론트엔드 개발자의 자바스크립트
프론트엔드 개발자의 자바스크립트 jeong seok yang
 
JavaSript Template Engine
JavaSript Template EngineJavaSript Template Engine
JavaSript Template EngineOhgyun Ahn
 
퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다정석 양
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web AnimationsChang W. Doh
 
[토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강 [토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강 우영 주
 

Viewers also liked (12)

비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기
 
퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다
 
퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다퍼블리셔, 디자인을 퍼블리싱하다
퍼블리셔, 디자인을 퍼블리싱하다
 
하코사세미나_캔버스 파이그래프 만들기
하코사세미나_캔버스 파이그래프 만들기하코사세미나_캔버스 파이그래프 만들기
하코사세미나_캔버스 파이그래프 만들기
 
JavaScript 2014 프론트엔드 기술 리뷰
JavaScript 2014 프론트엔드 기술 리뷰JavaScript 2014 프론트엔드 기술 리뷰
JavaScript 2014 프론트엔드 기술 리뷰
 
Jquery핵심노토
Jquery핵심노토Jquery핵심노토
Jquery핵심노토
 
나의 jQuery 실력 향상기
나의 jQuery 실력 향상기나의 jQuery 실력 향상기
나의 jQuery 실력 향상기
 
프론트엔드 개발자의 자바스크립트
프론트엔드 개발자의 자바스크립트 프론트엔드 개발자의 자바스크립트
프론트엔드 개발자의 자바스크립트
 
JavaSript Template Engine
JavaSript Template EngineJavaSript Template Engine
JavaSript Template Engine
 
퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다퍼블리셔, 프론트엔드개발을 시작하다
퍼블리셔, 프론트엔드개발을 시작하다
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations
 
[토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강 [토크아이티] 프런트엔드 개발 시작하기 저자 특강
[토크아이티] 프런트엔드 개발 시작하기 저자 특강
 

Similar to 컴포넌트 관점에서 개발하기

ABC: 다시 생각하는 컴포넌트
ABC: 다시 생각하는 컴포넌트ABC: 다시 생각하는 컴포넌트
ABC: 다시 생각하는 컴포넌트Chanhee Lee
 
Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Kyoung Up Jung
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
Java script 강의자료_ed13
Java script 강의자료_ed13Java script 강의자료_ed13
Java script 강의자료_ed13hungrok
 
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내Tae-Seong Park
 
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)SangIn Choung
 
ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는Taegon Kim
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Testbeom kyun choi
 
자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기Jeado Ko
 
개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)SangIn Choung
 
김윤환_포트폴리오
김윤환_포트폴리오김윤환_포트폴리오
김윤환_포트폴리오Yun-hwan Kim
 
Express framework tutorial
Express framework tutorialExpress framework tutorial
Express framework tutorial우림 류
 
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기Kenneth Ceyer
 
디자인 시스템 디자인하기
디자인 시스템 디자인하기디자인 시스템 디자인하기
디자인 시스템 디자인하기sangyong lee
 
[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱NAVER D2
 
워드프레스 For 플러그인
워드프레스 For 플러그인워드프레스 For 플러그인
워드프레스 For 플러그인082net
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 Yong Joon Moon
 

Similar to 컴포넌트 관점에서 개발하기 (20)

ABC: 다시 생각하는 컴포넌트
ABC: 다시 생각하는 컴포넌트ABC: 다시 생각하는 컴포넌트
ABC: 다시 생각하는 컴포넌트
 
react-ko.pdf
react-ko.pdfreact-ko.pdf
react-ko.pdf
 
Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
Java script 강의자료_ed13
Java script 강의자료_ed13Java script 강의자료_ed13
Java script 강의자료_ed13
 
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
[React-Native-Seoul] React-Native 초심자를 위한 실습위주의 간단한 소개 및 구현법 안내
 
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
애자일 테스트 프랙티스와 사례들 (부제: 협업의 힘)
 
ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는ReactJS | 서버와 클라이어트에서 동시에 사용하는
ReactJS | 서버와 클라이어트에서 동시에 사용하는
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
 
자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기
 
개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)개발이 테스트를 만났을 때(Shift left testing)
개발이 테스트를 만났을 때(Shift left testing)
 
김윤환_포트폴리오
김윤환_포트폴리오김윤환_포트폴리오
김윤환_포트폴리오
 
Express framework tutorial
Express framework tutorialExpress framework tutorial
Express framework tutorial
 
(스프링프레임워크 강좌)스프링부트개요 및 HelloWorld 따라하기
(스프링프레임워크 강좌)스프링부트개요 및 HelloWorld 따라하기(스프링프레임워크 강좌)스프링부트개요 및 HelloWorld 따라하기
(스프링프레임워크 강좌)스프링부트개요 및 HelloWorld 따라하기
 
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기 GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
GDG DevFest 2017 Seoul 프론트엔드 모던 프레임워크 낱낱히 파헤치기
 
디자인 시스템 디자인하기
디자인 시스템 디자인하기디자인 시스템 디자인하기
디자인 시스템 디자인하기
 
[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱[114]angularvs react 김훈민손찬욱
[114]angularvs react 김훈민손찬욱
 
워드프레스 For 플러그인
워드프레스 For 플러그인워드프레스 For 플러그인
워드프레스 For 플러그인
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
 
[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초[Codelab 2017] ReactJS 기초
[Codelab 2017] ReactJS 기초
 

More from 우영 주

스트리밍과 디지털 권리 관리
스트리밍과 디지털 권리 관리스트리밍과 디지털 권리 관리
스트리밍과 디지털 권리 관리우영 주
 
스트리밍과 플레이어
스트리밍과 플레이어스트리밍과 플레이어
스트리밍과 플레이어우영 주
 
프런트엔드개발, 지금과 다음
프런트엔드개발, 지금과 다음프런트엔드개발, 지금과 다음
프런트엔드개발, 지금과 다음우영 주
 
아재가 젊은이에게 사랑받는 마크업을 하는 방법
아재가 젊은이에게 사랑받는 마크업을 하는 방법아재가 젊은이에게 사랑받는 마크업을 하는 방법
아재가 젊은이에게 사랑받는 마크업을 하는 방법우영 주
 
Introduce Guetzli
Introduce GuetzliIntroduce Guetzli
Introduce Guetzli우영 주
 
스코프와 실행문맥
스코프와 실행문맥스코프와 실행문맥
스코프와 실행문맥우영 주
 
좋은 기능을 만드는 방법
좋은 기능을 만드는 방법좋은 기능을 만드는 방법
좋은 기능을 만드는 방법우영 주
 
서비스를 성공적으로 만드는 방법
서비스를 성공적으로 만드는 방법서비스를 성공적으로 만드는 방법
서비스를 성공적으로 만드는 방법우영 주
 
다함께, FluxUtils 한바퀴!
다함께, FluxUtils 한바퀴!다함께, FluxUtils 한바퀴!
다함께, FluxUtils 한바퀴!우영 주
 
BEM을 깨우치다.
BEM을 깨우치다.BEM을 깨우치다.
BEM을 깨우치다.우영 주
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises우영 주
 
명세부터 깨우치는 FILEAPI
명세부터 깨우치는 FILEAPI명세부터 깨우치는 FILEAPI
명세부터 깨우치는 FILEAPI우영 주
 
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기우영 주
 
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)우영 주
 
Javascript Test Double Sinon.js
Javascript Test Double Sinon.jsJavascript Test Double Sinon.js
Javascript Test Double Sinon.js우영 주
 
HTML5 BOILERPLATE를 소개합니다.
HTML5 BOILERPLATE를 소개합니다.HTML5 BOILERPLATE를 소개합니다.
HTML5 BOILERPLATE를 소개합니다.우영 주
 
이클립스로 GIT 사용하기
이클립스로 GIT 사용하기이클립스로 GIT 사용하기
이클립스로 GIT 사용하기우영 주
 

More from 우영 주 (18)

스트리밍과 디지털 권리 관리
스트리밍과 디지털 권리 관리스트리밍과 디지털 권리 관리
스트리밍과 디지털 권리 관리
 
스트리밍과 플레이어
스트리밍과 플레이어스트리밍과 플레이어
스트리밍과 플레이어
 
프런트엔드개발, 지금과 다음
프런트엔드개발, 지금과 다음프런트엔드개발, 지금과 다음
프런트엔드개발, 지금과 다음
 
아재가 젊은이에게 사랑받는 마크업을 하는 방법
아재가 젊은이에게 사랑받는 마크업을 하는 방법아재가 젊은이에게 사랑받는 마크업을 하는 방법
아재가 젊은이에게 사랑받는 마크업을 하는 방법
 
Introduce Guetzli
Introduce GuetzliIntroduce Guetzli
Introduce Guetzli
 
스코프와 실행문맥
스코프와 실행문맥스코프와 실행문맥
스코프와 실행문맥
 
좋은 기능을 만드는 방법
좋은 기능을 만드는 방법좋은 기능을 만드는 방법
좋은 기능을 만드는 방법
 
서비스를 성공적으로 만드는 방법
서비스를 성공적으로 만드는 방법서비스를 성공적으로 만드는 방법
서비스를 성공적으로 만드는 방법
 
다함께, FluxUtils 한바퀴!
다함께, FluxUtils 한바퀴!다함께, FluxUtils 한바퀴!
다함께, FluxUtils 한바퀴!
 
BEM을 깨우치다.
BEM을 깨우치다.BEM을 깨우치다.
BEM을 깨우치다.
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
명세부터 깨우치는 FILEAPI
명세부터 깨우치는 FILEAPI명세부터 깨우치는 FILEAPI
명세부터 깨우치는 FILEAPI
 
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
[Toolcon2014] WebStorm에서 자바스크립트 리팩토링하기
 
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
진보한 개발 환경에서 품질 좋은 코드 생산 (WebStorm)
 
Javascript Test Double Sinon.js
Javascript Test Double Sinon.jsJavascript Test Double Sinon.js
Javascript Test Double Sinon.js
 
LESS와 EMMET
LESS와 EMMETLESS와 EMMET
LESS와 EMMET
 
HTML5 BOILERPLATE를 소개합니다.
HTML5 BOILERPLATE를 소개합니다.HTML5 BOILERPLATE를 소개합니다.
HTML5 BOILERPLATE를 소개합니다.
 
이클립스로 GIT 사용하기
이클립스로 GIT 사용하기이클립스로 GIT 사용하기
이클립스로 GIT 사용하기
 

컴포넌트 관점에서 개발하기

  • 1. 컴포넌트 관점에서 개발하기 2017 프론트엔드 트렌드&인사이트
  • 2. 주우영 프런트엔드 개발 시작하기 네이버는 이렇게 한다!, 위키북스 JavaScript Promise 한빛 eBook, 한빛미디어 페이스북 프론트엔드개발 그룹 운영 https://www.facebook.com/groups/webfrontend/ 레진엔터테인먼트 프론트엔드개발팀
  • 4. 현대 UI 개발에 있어 중요히 여기는 부분에 대해 이야기합니다.
  • 5. 현대 프레임워크의 공통된 접근법 컴포넌트 단위로 사고하고 디자인
  • 6. import {Component} from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Welcome to {{title}}</h1> `, styles: [` h1 { font-size: 4em; } `] }) export class AppComponent { title = 'app'; }
  • 7. import {Component} from 'react'; const style = { fontSize: '4em' }; class HelloMessage extends Component { static defaultProps = { title: 'React' }; render() { return ( <h1 style={style}> Welcome to {this.props.title} </h1> ); } }
  • 8. <style scoped> h1 { font-size: 4em; } </style> <template> <h1>Welcome to {{title}}</h1> </template> <script type="text/babel"> export default { data () { return { title: 'Vue' } } } </script>
  • 9. <dom-module id="hello-element"> <template> <style> h1 {font-size: 4em} </style> <h1>Welcome to {{title}}</h1> </template> <script> class HelloElement extends Polymer.Element { static get is() {return "hello-element";} constructor() { super(); this.title = "Polymer"; } } customElements.define(HelloElement.is, HelloElement); </script> </dom-module>
  • 11. 하나의 문제를 잘 해결하는 COMPONENT 프로그램
  • 12. 새로운 방법이 아닌 예로부터 모든 공학 분야의 공학자가 자주 사용해 오던 문제 해결 방법
  • 13. Unix Philosophy Write programs that do one thing and do it well. Write programs to work together. Doug Mcllroy, Unix pipeline inventor The UNIX Philosophy in 9 paramount precepts Mike Gancarz (a member of the team that designed the X Window System) Small is beautiful. Make each program do one thing well. Write programs handle text streams, because that is a universal interface.
  • 14. $ ps -ef Processes Status Report a snapshot of the current processes $ grep gradle Globally search a regular expression and print Searching plain-text data sets for lines that match a regular expression $ ps -ef | grep gradle
  • 15. 사고의 분산을 막고 하나의 문제에 집중함으로써 효율적으로 개발할 수 있다
  • 16. 설계의 오류를 쉽게 파악할 수 있고 상대적으로 테스트하기 쉽다
  • 17. 이식성을 높일 수 있고 변경에 유연하게 대체할 수 있다
  • 18. API UI는 자주적으로 동작하는 또 다른 프로그램, 그것을 API로 제어한다는 사고로 접근 자바스크립트를 개발할 때 우리는
  • 19. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); }
  • 20. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); } DOM을 직접 핸들링, 장황하고 UI의 형태를 한눈에 파악하기 힘듦
  • 21. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); } 상태를 class나 data attr에 설정 및 사용하여 전체적인 상태 흐름을 알기 힘듦
  • 22. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); } DOM API의 비용은 비쌈. 상태 변화를 위해 
 DOM API 호출이 남용됨
  • 23. _changeTabs() { const fragment = this._parseFragment(); if (fragment === null) { return; } _.each(fragment, (value, key) => { const target = $(_.find(this.$sections, i => { return $(i).dataset('type') === key); }); // 선택한 탭으로 변경한다. target.find('.cs-tab li').removeClass('is-on'); target.find('.cs-tab li') .has(`a[href='#${value}']`).addClass('is-on'); // 탭에 해당하는 목록으로 변경한다. target.find('.cs-body').removeClass('is-on'); target.find(`.cs-body#cs-${key}-${value}`) .addClass('is-on'); }); } UI 상태 변화를 위한 render 외의 부가적 메서드 다량 정의
  • 24. 프리젠테이션 로직은 크고 복잡. 테스트하고 유지보수하기 괴롭다
  • 25. Functional Programming 컴포넌트 접근법은 함수형 프로그래밍하고도 관련이 깊다 부작용(Side effect)없이 하나의 일을 잘 수행하는 함수 그러한 함수를 조합 / 구성함으로써 큰 문제를 해결 F2 F3 F4 F5F1
  • 26. {
 “type”: “oval”,
 “size”: 32
 } Functional Programming and UI Component View = Function(state)
  • 27. function Header({title, desc}) { return ( <header className="header"> <div className="header__inner"> <h1 className="header__title">{title}</h1> <p className="header__description">{desc}</p> </div> </header> ); } View = Function(state) REMEMBER
  • 28. Header({ title: 'Hello World!', desc: 'This is Awesome.' }); <header class="..."> <div class="..."> <h1 class="...">Hello World!</h1> <p class="...">This is Awesome.</p> </div> </header>
  • 29. <header class="..."> <div class="..."> <h1 class="...">Hello World!</h1> <p class="...">This is Awesome</p> </div> </header> <header class="..."> <div class="..."> <h1 class="...">Welcome</h1> <p class="...">This is Awesome</p> </div> </header> Equal?
  • 30. <header class="..."> <div class="..."> <h1 class="...">Hello World!</h1> <p class="...">This is Awesome</p> </div> </header> <header class="..."> <div class="..."> <h1 class="...">Welcome</h1> <p class="...">This is Awesome</p> </div> </header> Equal?
  • 31. <header class="..."> <div class="..."> <h1 class="...">Hello World!</h1> <p class="...">This is Awesome</p> </div> </header> <header class="..."> <div class="..."> <h1 class="...">Welcome</h1> <p class="...">This is Awesome</p> </div> </header> Equal? FAIL
  • 33. HTML(TMPL), CSS, 자바스크립트를 분리하는게 당연한 관심사의 분리라고 생각 과거 우리는.
  • 34. Templates separate technologies, not concerns. 템플릿은 기술의 분리일 뿐 관심사의 분리가 아니다. Pete Hunt, React developer 페이트 헌트, 리액트 개발자 “ ”
  • 35.
  • 36.
  • 37. KingCard Component 중요한건 해결하고자 하는 문제 같은 문제를 해결한다면 관심사는 같다
  • 38. 이때, 분리된 환경 보다 한 곳에 있는 경우가 훨씬 수월하다 관심사가 같다면 수정 시, 함께 수정해야 할 확률이 높다
  • 39. HTML, CSS를 어떻게든 셋팅한 후 자바스크립트를 이어서 테스트 UI 테스트에 대한 자원 준비 없이 곧바로 컴포넌트를 테스트
  • 40. Test IconText Component it('iconDirection 속성에 left를 지정하면 아이콘이 좌측에 배치된다.', () => { // Given // When const wrapper = shallow( <IconText label="친구초대" icon="add-friend" iconDirection="left" /> ); // Then const children = wrapper.children('.icon-text__inner').children(); expect(children.first()).to.have.className('icon-text__icon'); expect(children.last()).to.have.className('icon-text__label'); });
  • 41. "## Header $ "## Header.js $ "## Header.test.js $ %## style.scss "## TallCard $ "## TallCard.js $ "## TallCard.test.js $ %## style.scss "## KingCard $ "## KingCard.js $ "## KingCard.test.js $ %## style.scss %## StickyBar "## StickyBar.js "## StickyBar.test.js %## style.scss 따라서 관련있는 것은 최대한 가까이에 두는 구조가 현재 유행
  • 42. const Button = (props) => ( <button className={'large' in props && 'large'}> {props.children} <style jsx>{` button { padding: 20px; background: #eee; color: #999 } .large { padding: 50px } `}</style> </button> ); 또는 하나의 파일 내 모든 관심사를 작성하는 방식도 선호
  • 43. 뭘 좀 만들어 봅시다. 이런 UI를 개발해 달라고 했을때 가장 먼저 한가지 일을 수행하는 최소 단위를 분석
  • 44. 뭘 좀 만들어 봅시다. 이런 UI를 개발해 달라고 했을때 가장 먼저 한가지 일을 수행하는 최소 단위를 분석
  • 45. 뭘 좀 만들어 봅시다. 이런 UI를 개발해 달라고 했을때 가장 먼저 한가지 일을 수행하는 최소 단위를 분석
  • 46. 뭘 좀 만들어 봅시다. 이런 UI를 개발해 달라고 했을때 가장 먼저 한가지 일을 수행하는 최소 단위를 분석 <TallCard/> 를 만들어 봅시다.
  • 47. BEM(Block, Element, Modifier) 컴포넌트와 어울리게 마크업하기 Block 애플리케이션의 구성 요소로서 독립된 존재 Element 블록을 구성하는 작은 단위 또는 자식 개체 Modifier 블록이나 요소의 테마, 동작을 표현
  • 49. <div class="tall-card tall-card_badge_up"> <div class="tall-card__badge"> <i class=“tall-card__badge-up"> <span class="blind">UP</span> </i> </div> <div class="tall-card__thumbnail"> <img class="tall-card__image" src="" alt=""/> </div> <div className="tall-card__information"> <h5 className="tall-card__title">레바툰</h5> <dl class="tall-card__meta"> <dt class=“tall-card__meta-key">장르</dt> <dd class=“tall-card__meta-value">개그 / 일상</dd> <dt class=“tall-card__meta-key">작가</dt> <dd class=“tall-card__meta-value">레바</dd> </dl> </div> </div> Markup with BEM
  • 50. const TallCard = ({title, image, badge, metadata = []}) => ( <div className={`tall-card ${badge === 'up' ? ‘tall-card_badge_up' … `}> <div className="tall-card__badge"> <i className=“tall-card__badge-up”/> </div> <div className="tall-card__thumbnail"> <img className="…" src={image} alt={`${title}의 썸네일`}/> </div> <div className="tall-card__information"> <h5 className="tall-card__title">{title}</h5> {metadata.length > 0 ? ( <dl className=“tall-card__meta"> ${metadata.map(({key, value}) => ([ <dt className=“tall-card__meta-key">{key}</dt>, <dt className=“tall-card__meta-key">{value}</dt> ]))} </dl> ) : null} </div> </div> ); Create React Component
  • 51. $module: 'icon-text'; .#{$module} { &__badge { /*...*/ &__up {/*...*/} } &__thumbnail { /*...*/ &__image {/*...*/} } &__information {/*...*/} &__title {/*...*/} &__meta {/*…*/} &__meta-key {/*...*/} &__mata-value {/*...*/} } Styling with SASS SASS의 interpolation은 컴포넌트 접근법과 잘 어울린다 스타일링 영역을 문법적으로 명확히 표현할 수 있다
  • 52. "## TallCard "## TallCard.js %## TallCard.scss "## TallCard "## TallCard.js "## TallCard.html %## TallCard.scss File structure 마크업 코드를 템플릿으로 분리한 경우 마크업을 자바스크립트에 포함한 경우
  • 53. Context Free <CardGroup/><SquareCard/> type = subscriptions 상위 컴포넌트 스타일이 하위 컴포넌트 스타일에 영향을 주면 안된다 컴포넌트는 어떤 문맥에서든 자유로워야 한다
  • 54. badge = up sensational = true 만약 특정 문맥에서 컴포넌트가 변화한다면 해당 컴포넌트에 Context Free <SquareCard/> badge = new 새로운 변환자(Modifier)를 추가한다
  • 55. Context Free <CardGroup/> CardList 컴포넌트는 badge가 up인 SquareCard 컴포넌트를 자식 컴포넌트로 포함하고 있을 뿐이다 type = subscriptions
  • 56. 타인의 잣대에 얽매이면 행복할 수 없듯 컴포넌트 역시 특정 문맥에 얽매이면 행복할 수 없다