자바스크립트 라이브러리 
개발/운영 경험기 
전용우 / NHN NEXT
CONTENTS 
1. 사용자 
1-1. 기능이 부족해요 VS 너무 많아요 
1-2. 업그레이드 
2. 개발 
2-1. 유연함은 중요하다 
2-2. 라이브러리간 의존 관계
https://www.flickr.com/photos/pictureperfectpose/76138988
1. 사용자(User)
1-1. 기능이 부족해요 
VS 
너무 많아요
다 같은 사용자는 아니더라 
https://www.flickr.com/photos/zsrlibrary/14254359634
https://www.flickr.com/photos/rwp-roger/6772861500 
압축도구를 바꿔 볼까? 
어떤 도구를 써도 5%이상 차이 안남 
https://www.flickr.com/photos/maitreyoda/9771070802
라이브러리의 사용률? 
8 
https://www.flickr.com/photos/ores2k/394359583
과연… 얼마나 사용할까? 
gzip 크기(%) 
100 
75 
50 
25 
0 
core A B C D 
비교적 많이 사용하는 서비스 
40%
골라서 쓰자 
https://www.flickr.com/photos/igal/7901479448
선택 내려받기
Core의 메서드 100여개 
! 
서비스 코드에서 찾기란 쉽지 않다 
https://www.flickr.com/photos/ronbrinkmann/6542592269/
function 
foo(sId){ 
$Element(sId).addClass("on"); 
} 
function 
bar(){ 
$A($$("li")).forEach(function(v){ 
$Element(v).toggleClass("selected"); 
}); 
} 
Rhino 
Engine 
RegExp 
service 
code 
$Element 
addClass 
$A 
$$ 
… 
※ Esprima가 보다 안정적임.
$Element 
addClass 
$A 
$$ 
… 
{ 
meta_2.1.0.js 
"jindo.$A.prototype.forEach": 
{ 
"key": 
"ae10", 
"dependency": 
["av1"] 
} 
} 
+ 
core_2.1.0_custom.js 
jindo.$Element 
= 
function(){....}; 
jindo.$Element.prototype.addClass 
= 
function(){...}; 
jindo.$Element.prototype.toggleClass 
= 
function(){...}; 
jindo.$$ 
= 
function(){}; 
jindo.$A 
= 
function(){}; 
jindo.$A.prototype.forEach=function(){}
15 
30~40%
이슈는 있다. 
! 
1. 각 페이지 별로 core가 다를 수 있다. 
2. 추가된 메서드가 있을 때 다시 배포해야 한다. 
사용자는 개선됐지만, 
! 
개발자는 여전히 새로운 기능을 
추가하는건 비용이 커서 쉽지 않음.
1-2. 업그레이드(Upgrade)
자. 이제 만들었어요. 
2.X.X로 업그레이드 하시면 되요. 
업그레이드하기엔 부담되네요. 
https://www.flickr.com/photos/dharder9475/14322980596
https://www.flickr.com/photos/bswise/4424374169 
서비스는 안정성
20 
업그레이드가 필요하다면, 
최대한 쉽게 하자.
21 
https://www.flickr.com/photos/djou/362370161 
1. 버저닝(Versioning)
기존의 버저닝 규칙 
X.Y.Z 
! 
1. 특별한 규칙을 가지고 있지 않음. 
2. 개발자가 많이 변경된 것 같다고 생각하면 좀 많은 버전을 올림.
Semantic Versioning 
X.Y.Z 
! 
1. 기존 버전과 호환되지 않게 API가 바뀌면 X(major)을 올린다. 
2. 기존 버전과 호환되지만 API 추가된 경우 Y(minor)을 올린다. 
3. API 변경 없어 버그만 수정된 경우 Z(patch)을 올린다. 
[http://semver.org/] 
아쉬운 점 
1. 크기를 알기 힘들다. (10개 수정 == 1개 수정) 
2. 버저닝의 규칙만으로 결과를 확인하기 어렵다.
여전히 업그레이드는 걱정 
버전간 차이가 크면 릴리즈 노트는 큰 도움이 안됨 
https://www.flickr.com/photos/samstanton/3541463682
가보지 않은 길은 막막하다 
Q&A 
https://www.flickr.com/photos/samstanton/3541463682
26 
2. 업데이터(Updater)
function 
foo(sId){ 
$Element(sId).addClass("on"); 
} 
function 
bar(){ 
$A($$("li")).forEach(function(v){ 
$Element(v).toggleClass("selected"); 
}); 
} 
Rhino 
Engine 
RegExp 
service 
code 
$Element 
addClass 
$A 
$$ 
…
$Element 
addClass 
$A 
$$ 
… 
+ 
changelog_2.1.0.js 
[{ 
"method": 
[jindo.$A.prototype.forEach"], 
"coverage": 
[ 
"mobile","desktop" 
], 
"type": 
"1","level": 
"2", 
"desc": 
"forEach 
첫번째 
인자가 
역순으로 
나옴" 
}] 
result 
| 파일명 | 줄 번호 | 진도 메서드 | 타입 | 레벨 | 버전 | 변경 내용 | 
| service.js | 4 | $A#forEach | 버그 | 패치 | 2.0.1 | forEach 첫번째 인자가 역순으로 나옴|
얼마나 업그레이드 할까? 
Q&A 
100% 
75% 
50% 
25% 
0%
업그레이드 비율이 높아지진 않음 
! 
1. 기존의 업그레이드할 때 보다 안정적으로 업그레이드를 진행. 
2. 업그레이드에 대한 질문은 많이 없어짐.
2. 개발(Development)
2-1. 유연함은 중요하다
완성도는 SnapShoot과 같다. 
나도 성장하고 주위도 성장한다 
환경은 변한다 
미래는 예측할 수 없다 
https://www.flickr.com/photos/adulau/12533795583
모바일용 컴포넌트 만들 당시 
Component Mobile Component
환경도 변한다. 
Flicking 
slide 
cover 
cube 
! 
1. 많은 요구 사항으로 기능이 늘어남. 
2. 유지보수가 힘듬 
Flicking 
SlideFlicking CoverFlicking CubeFlicking
변화에 기민하게 대응하는게 중요 
테스트는 좋은 안전 장치다. 
https://www.flickr.com/photos/jo_mur/4478000841
테스트 케이스 상황 
단위 테스트 케이스 테스트 케이스 
Core 500여개 - 
Component 개당 20~30 개당 20~30 
Mobile 
Component 개당 20~30 개당 20~30
Core - 테스트
Core - 테스트 
Cloud 환경은 제외 
- 빠르게 확인 안됨 
JSTestDriver 
- 자체 도구에 맞게 Adapter 구현이 안됨 
필요한 기능만 개발 
- 그냥 쉽고 빠르게 응답받는 걸 만들자
Core - 테스트 
file write 
Ajax polling 
result 
$Ajax 
$Element 
$A 
$H
Core - 테스트 
Testem [https://github.com/airportyh/testem] 
Karma [http://karma-runner.github.io/0.12/index.html] 
Adapter의 방식이 Event로 되어 있어 타 단위 테스트 라이브러리와 연동이 잘됨
Component (Mobile) - 테스트 
단위 테스트 테스트 케이스 
! 
1. 단위 테스트는 크게 문제가 되지 않는다 
2. 사람이 직접 테스트해야 하는 테스트 케이스 경우 비용이 크다
밀도있게 하자 
어떻게 하면 줄일 수 있을까? 
1. 대부분의 문제는 수치화 안되는 상황 
2. 실제 사용자 이벤트가 필요한 경우 
3. 퀄리티와 직결되는 이슈 
https://www.flickr.com/photos/ores2k/394359583
기능별로 구분할까? 
테스트 케이스 테스트 케이스 테스트 케이스 
A컴포넌트 B컴포넌트 C컴포넌트 
A기능 B기능 C기능 D기능
테스트 리팩토링 
테스트 케이스 
겹치는 테스트 케이스 
- 비슷한 동작을 하는 경우 하나로 
40% 
비슷한 기기의 통합
46 
운영하는데 유연성은 중요 
테스트 케이스가 좋은 장치 
단위 테스트 케이스 - 도구를 활용 
테스트 케이스 - 밀도가 중요
2-2. 라이브러리간 의존관계
JindoJS의 구조 
Core 
Component 
Mobile 
Component 
Component Core 
Core 버전이 변경되면? 
서비스와 다르게 컴포넌트는 
서비스에서 사용하는 
Core의 버전을 모름
문제들 
! 
1. 새로운 Core의 기능을 사용할 수 없음. 
2. 이미 Core에서 수정된 이슈를 서비스에서 어떤 Core의 버전을 사용하는지 알 수 없어 
별도로 가지고 있어야 함.
테스트를 잘하자 
기하급수로 늘어난다
Core 버전 * 컴포넌트 버전 
Core Component 
1.4.0 
1.4.1 
1.5.0 
… 
2.0.1 
2.0.2 
1.2.0 
1.2.1 
1.3.0 
… 
1.4.1 
1.5.1 
n k
고민된다 #1 
1. Core의 의존도가 높으면 전체적으로 개선되나 
사용자의 Core가 제각각이다. 
-> 의존도를 낮추자 
2. Core의 의존도를 낮추면 Core비슷한 걸 
만들게 된다. 
-> Core을 사용하자.
고민된다 #2 
1. 네이티브의 발전은 지속적이고 빠르다. 
-> 모두 다하기에는 벅차다. 
2. 지금 방식에 만족하자. 
-> 근데 예전 방식이다.
54 
1. 최소한의 의존관계 
2. 손쉽게 발전할 수 있을까?
Core기능 
1. 좀 더 사용자가 쉽게 개발 
2. 크로스 브라우징
분리하는게 좋겠다 
Core 
Core 
polyfill
분리하는게 좋겠다 
jindo.$Fn.prototype.bind 
= 
function() 
{ 
if(Function.prototype.bind){ 
//bind가 
있는 
경우 
}else{ 
//bind가 
없는 
경우 
} 
}; 
if 
(!Function.prototype.bind) 
{ 
Function.prototype.bind 
= 
function 
(target) 
{ 
// 
bind가 
없는 
경우 
}; 
} 
! 
jindo.$Fn.prototype.bind 
= 
function() 
{ 
// 
bind가 
있는 
경우 
};
분리하는게 좋겠다 
Core 
Component 
Mobile 
Component 
Component Core 
polyfill 
Core 
Component Mobile 
Component 
Component Core
진행중 
! 
1. polyfill의 지원은 잘되어 있는 편이라 보다 쉽게 간접적으로 외부지원을 받는다. 
2. 생각보다 많은 작업이라 한번에 진행하긴 힘들고 천천히 진행중이였다. 
가장 많이 사용하는 core 최신 Component 
최신 core 전 버전 Component 
최신 core 최신 Component
60 
http://dev.naver.com/projects/jindo
Q&A
THANK YOU

[1A4]자바스크립트 라이브러리 개발 운영 경험기