엔진( 당분간) 을 사용하는 그래서 Javascript 을 주언어로 사용 ( 비교적) 가볍고, 빠르며, 다양한 환경에서 동작하는 프레임워크 비동기(Asynchronous) I/O via libuv 이벤트- 드리븐(Event-driven) 그리고 넌블럭킹(Non-Blocking) I/O 엄청나게 활발한 커뮤니티의 은혜. Node 파운데이션과 NPM Packages 3
인터프린터) 독립적으로 구현되어 다른 프로젝트와 결합 가능. Node.js, MongoDB, Electron 등 V8 엔진 업데이트와 함께 Javascript 의 여러가지 기능 추가. ES2015 추가 스펙 (ECMAScript 2015 stage-x) 2017 년 여러 엔진 사용가능 예상. ( 마이크로소프트 Edge 브라우저의 ChakraCore) 4
i a t e ( ( ) = > c o n s o l e . l o g ( " 1 " ) ) ; s e t T i m e o u t ( ( ) = > c o n s o l e . l o g ( " 2 " ) , 0 ) ; P r o m i s e . r e s o l v e ( ) . t h e n ( ( ) = > c o n s o l e . l o g ( ' 3 ' ) ) ; s e t T i m e o u t ( ( ) = > c o n s o l e . l o g ( " 4 " ) , 0 ) ; ( ( ) = > c o n s o l e . l o g ( ' 5 ' ) ) ( ) ; P r o m i s e . r e s o l v e ( ) . t h e n ( ( ) = > c o n s o l e . l o g ( ' 6 ' ) ) ; p r o c e s s . o n ( ' b e f o r e E x i t ' , ( ) = > { c o n s o l e . l o g ( ' 7 ' ) ; } ) ; Question?: 이벤트 일어나는 순서를 추측해보세요 1: 3 5 6 1 2 4 7 2: 5 3 6 1 2 4 7 3: 3 5 6 2 4 1 7 4: 5 3 6 2 4 1 7 16
을 사용한 Node 설치 Node 프로젝트 생성과 NPM 사용 기본 사용법 모듈 (module) 로딩 이벤트 처리: 콜백(Callback), 프라미스(Promise) 핸들링 에러, 예외(Exception) 처리 기본 API 사용법: Net / HTTP / File System / Stream 20
r s i o n s c a n b e i n s t a l l a b l e n v m l s - r e m o t e # i n s t a l l n o d e n v m i n s t a l l v 6 . 9 . 1 n v m i n s t a l l - - l t s # g e t v e r s i o n s i n s t a l l e d n v m l s # u s e a v e r s i o n n v m u s e v 6 . 9 . 1 21
패키지를 설치해서 사용. 그 정보들을 package.json 에 저장 # i n i t p r o j e c t y a r n i n i t o r n p m i n i t # i n s t a l l p a c k a g e s o f t h e p r o j e c t y a r n i n s t a l l o r n p m i n s t a l l # i n s t a l l n e w p a c k a g e t o d e p e d e n c i e s y a r n a d d P A C K A G E _ N A M E o r n p m i n s t a l l — s a v e P A C K A G E _ N A M E # i n s t a l l n e w p a c k a g e t o d e v d e p e d e n c i e s y a r n a d d - - d e v P A C K A G E _ N A M E o r n p m i n s t a l l — s a v e - d e v P A C K A G E _ N A M E # r u n s c r i p t s y a r n s t a r t o r n p m s t a r t y a r n t e s t o r n p m t e s t y a r n r u n m y - c o m m a n d o r n p m r u n m y - c o m m a n d 22
a l m o d u l e c o n s t f s = r e q u i r e ( ' f s ' ) ; / / i n s t a l l e d m o d u l e a t n o d e _ m o d u l e s c o n s t l i b = r e q u i r e ( ' l i b ' ) ; / / u s e r m o d u l e c o n s t f o o = r e q u i r e ( ' . / f o o ' ) ; / / d e s t r u c t u r i n g i n E S 2 0 1 5 c o n s t { a p p } = r e q u i r e ( ' e l e c t r o n ' ) ; / / i n a w a y o f E S 2 0 1 5 , n o t y e t l a n d i n g , u s i n g t r a n s f i l e r l i k e b a b e l . j s c o n s t e l e c t r o n , { a p p } i m p o r t ' e l e c t r o n ' ; 23
, u s i n g n o d e ' s m o d u l e s s y s t e m m o d u l e . e x p o r t s = f u n c t i o n l i b ( ) { r e t u r n ' e x p o r t e d ' ; } / / E S 2 0 1 5 , n o t y e t l a n d i n g , u s i n g t r a n s f i l e r l i k e b a b e l . j s e x p o r t d e f a u l t f u n c t i o n l i b ( ) { r e t u r n ' e x p o r t e d i n a n e w w a y ' ; } 24
low-level APIs 에서 기본으로 사용되는 방법 Error First Callback c o n s t f s = r e q u i r e ( ' f s ' ) ; f s . s t a t ( ' . ' , ( e r r , s t a t s ) = > { i f ( e r r ) { c o n s o l e . l o g ( e r r ) ; r e t u r n ; } c o n s o l e . l o g ( s t a t s ) ; } ) ; 25
t f s = r e q u i r e ( ' f s ' ) ; f u n c t i o n f s S t a t P r o m i s e ( p a t h ) { r e t u r n n e w P r o m i s e ( ( r e s o l v e , r e j e c t ) = > { f s . s t a t ( p a t h , ( e r r , s t a t s ) = > { i f ( e r r ) { r e s j e c t ( e r r ) ; } r e s o l v e ( s t a t s ) ; } ) ; } ) ; } f s S t a t P r o m i s e ( ' . ' ) . t h e n ( s t a t s = > { c o n s o l e . l o g ( s t a t s ) ; } ) . c a t c h ( e r r = > { c o n s o l e . l o g ( e r r ) ; } ) ; 26
E v e n t E m i t t e r = r e q u i r e ( ' e v e n t s ' ) ; c l a s s H T T P 3 e x t e n d s E v e n t E m i t t e r { r e q u e s t ( m s g ) { i f ( ! m s g ) { t h i s . e m i t ( ' r e q u e s t ' , n e w E r r o r ( ' n o m e s s a g e ' ) ) ; r e t u r n ; } t h i s . e m i t ( ' r e q u e s t ' , n u l l , m s g ) ; } } c o n s t h t t p 3 = n e w H T T P 3 ( ) ; h t t p 3 . o n ( ' r e q u e s t ' , ( e r r , m s g ) = > { i f ( e r r ) { t h r o w e r r ; } c o n s o l e . l o g ( ' d o n e w i t h ' , m s g ) ; } ) ; h t t p 3 . r e q u e s t ( ' m s g ' ) ; h t t p 3 . r e q u e s t ( ) ; / / w i l l c a u s e e r r o r 27
a d d - - d e v p i f y How to use c o n s t f s = r e q u i r e ( ' f s ' ) ; c o n s t p i f y = r e q u i r e ( ' p i f y ' ) ; c o n s t f s p = p i f y ( f s ) ; f s p . s t a t ( ' . ' ) . t h e n ( s t a t s = > { c o n s o l e . l o g ( s t a t s ) ; } ) . c a t c h ( e r r = > { c o n s o l e . e r r o r ( e r r ) ; } ) ; 28
s t n e t = r e q u i r e ( ' n e t ' ) ; c o n s t s e r v e r = n e t . c r e a t e S e r v e r ( s = > { c o n s o l e . l o g ( ' c l i e n t c o n n e c t e d ' ) ; / / h a n d l e c l o s i n g c o n n e c t i o n s . o n ( ' e n d ' , ( ) = > { c o n s o l e . l o g ( ' c l i e n t d i s c o n n e c t e d ' ) ; } ) ; / / w r i t e w e l c o m e m e s s a g e s . w r i t e ( ' h e l l o \ n \ n ' ) ; / / e c h o m e s s a g e c o m e f r o m c l i e n t s . p i p e ( s ) ; } ) . o n ( ' e r r o r ' , e r r = > { t h r o w e r r ; } ) ; / / t o c o n n e c t , t e l n e t 0 . 0 . 0 . 0 8 0 8 0 s e r v e r . l i s t e n ( { p o r t : 8 0 8 0 } , ( ) = > { c o n s o l e . l o g ( ' S e r v e r h a s b e e n s t a r t e d ' , s e r v e r . a d d r e s s ( ) ) ; } ) ; 30
s t h t t p = r e q u i r e ( ' h t t p ' ) ; c o n s t i n d e x H T M L = ` < h t m l > < h e a d > < / h e a d > < b o d y > < d i v > H e l l o < / d i v > < / b o d y > < / h t m l > ` ; c o n s t s e r v e r = h t t p . c r e a t e S e r v e r ( ( r e q , r e s ) = > { r e s . w r i t e H e a d ( 2 0 0 , { ' C o n t e n t - T y p e ' : ' t e x t / h t m l ' } ) ; r e s . e n d ( i n d e x H T M L ) ; } ) ; s e r v e r . o n ( ' c l i e n t E r r o r ' , ( e r r , s ) = > { s o c k e t . e n d ( ' H T T P / 1 . 1 4 0 0 B a d R e q u e s t \ r \ n \ r \ n ' ) ; } ) ; / / t o v i e w , t y p e l o c a l h o s t : 8 0 8 0 o n w e b b r o w s e r o r c u r l 0 . 0 . 0 . 0 : 8 0 8 0 s e r v e r . l i s t e n ( 8 0 8 0 , ( ) = > { c o n s o l e . l o g ( ' S e r v e r h a s b e e n s t a r t e d ' , s e r v e r . a d d r e s s ( ) ) ; } ) ; 31
를 한 연결처리(pipelining) 하지만 사용하기 구현하기 다소 귀찮음 v a r s t r e a m = r e q u i r e ( ' s t r e a m ' ) ; v a r l i n e r = n e w s t r e a m . T r a n s f o r m ( { o b j e c t M o d e : t r u e } ) ; l i n e r . _ t r a n s f o r m = f u n c t i o n ( c h u n k , e n c o d i n g , d o n e ) { / / a f t e r p r o c e s s i n g d o n e ( ) } ; 33
프로세싱1 - 포스트 프로세싱2 - 쓰기 형태의 연결처리 가능 f s . c r e a t e R e a d S t r e a m ( ' b i g f i l e . t x t ' ) / / p i p e t o p o s t p r o c e s s 1 . p i p e ( t h r o u g h 2 ( f u n c t i o n ( c h u n k , e n c , d o n e ) { c h u n k = p r o c e s s ( c h u n k ) ; t h i s . p u s h ( c h u n k ) ; / / p i p e t o n e x t s t r e a m d o n e ( ) ; } ) ) / / p i p e t o w r i t e s t r e a m . p i p e ( f s . c r e a t e W r i t e S t r e a m ( ' o u t . t x t ' ) ) . o n ( ' f i n i s h ' , f u n c t i o n ( ) { d o S o m e t h i n g S p e c i a l ( ) ; } ) ; 34
r / b i n / e n v n o d e / / p a r s e a r g u m e n t a n d o p t i o n s c o n s t a r g v = p r o c e s s . a r g v . s l i c e ( 2 ) ; d o _ w o r k ( a r g v ) ; / / o p t i o n a l , i f n o j o b i n t a s k / / p r e v e n t t o p r o c e s s e x i t i m m e d i a t e l y p r o c e s s . s t d i n . r e s u m e ( ) ; 36
npm 개발자 등록 # m a k i n g d i r e c t o r y m k d i r [ Y O U R I D ] & & c d [ Y O U R I D ] # c r e a t a n d c o d e u p a t i n d e x . j s t o u c h i n d e x . j s & & t o u c h t e s t . j s # i n i t p r o j e c t a n d i n p u t ` p a c k a g e n a m e ` , ` m a i n ` , g i t a d d r e s s , a n d m o r e n p m i n i t # g i t i n i t , c o m m i t a n d p u s h g i t i n i t & & g i t r e m o t e a d d o r i g i n [ Y O U R - R E P O ] g i t a d d - A & & g i t c o m m i t - a - m ' i n i t ' & & g i t p u s h o r i g i n m a s t e r # p u b l i s h ( o r v e r s i o n u p ) n p m p u b l i s h 38
l l w i t h y e o m a n n p m i n s t a l l - - g y o g e n e r a t o r - n m # S c a f f o l d i n g n o d e m o d u l e w i t h c l i o p t i o n y o n m - - c l i 39
Node.js Foundation 프로젝트로 편입 기본적인 웹서버 기능에 충실 라우팅(routing), HTTP 헬퍼 APIs, Static file 서빙 에러처리, DB 처리등 미들웨어(Middleware) 를 사용하여 기능확장에 용이 그 외로, Koa, Next.js, Loopback 41
O D S [ g e t | p o s t | p u t | d e l e t e ] ( ' / ' , ( r e q , r e s ) = > { r e s . s e n d ( ' r o u t i n g / ' ) ; } ) ; Static file a p p . u s e ( ' / s t a t i c ' , e x p r e s s . s t a t i c ( p a t h . j o i n ( _ _ d i r n a m e , ' p u b l i c ' ) ) ) ; 43
a n d ( ) a r e s u b s e t s o f t h e i r r e g u l a r e x p r e s s i o n c o u n t e r p a r t s a p p . g e t ( / @ . * / , ( r e q , r e s ) = > { r e s . s e n d ( r e q . o r i g i n a l U r l . r e p l a c e ( / ^ \ / @ / , ' ' ) ) ; } ) ; / / r o u t e w i t h p a r a m s t o g e t u s e r i n f o a p p . g e t ( ' / u s e r s / : u s e r I d ' , ( r e q , r e s ) = > { r e s . s e n d ( r e q . p a r a m s ) ; } ) ; 44
o n s t r o u t e r = e x p r e s s . R o u t e r ( ) ; / / m i d d l e w a r e t h a t i s s p e c i f i c t o t h i s r o u t e r r o u t e r . u s e ( ( r e q , r e s , n e x t ) = > { c o n s o l e . l o g ( ` [ L O G : $ { D a t e . n o w ( ) } ] : $ { r e q . o r i g i n a l U r l } ` ) ; n e x t ( ) ; } ) ; r o u t e r . g e t ( ' / u s e r s / : u s e r I d ' , ( r e q , r e s ) = > { r e s . s e n d ( r e q . p a r a m s ) ; } ) ; m o d u l e . e x p o r t s = r o u t e r ; 45
를 이용하는 (handsaking) 연결지향적인(TCP) 이며 양방향 커뮤니케이션(Full-duplex) 이 가능한 프로토콜 웹서버, 브라우저에서 이용가능 실시간 커뮤니케이션에 사용. 채팅, 알림등 Install: y a r n a d d - - d e v s o c k e t . i o 47
관리 Scaffolding: Boilerplate code, files for projects Building: Compile, transform, transpiler, bundling, packaging Deploying: Automatic deployment Testing: Lint, TDD, End to End 개발 과정의 반복과 지루함을 제거해서 개발 퍼포먼스 향상 ( 별만큼) 많은 도구들이 개발되고 사용되고 다시 대체되어짐 트렌드는 계속 변화중 48
패키지의 버전 충돌로 파편화가 심해짐 오버- 툴링이 뉴비들의 러닝커브를 급상승 시킴. 2016 년에 자바스크립트를 배우는 기분 점차 프레임워크에서 자체적으로 개발, 구성한 도구 제공 React: create-react-app AngularJS 2: Angular CLI Polymer: Polymer CLI Vue.js: Vue CLI 사용되는 툴들의 종류, 버전 그리고 플러그인을 직접관리 -> 프레임워크 레벨에서 주도권을 가지고 관 리가능 생성된 프로젝트에선 npm scripts 로 사용 -> node 환경에서 일관되고 쉬운 사용법 하지만 뚜껑을 열면? 51
- g v u e - c l i # i n i t w i t h w e b p a c k t e m p l a t e v u e i n i t w e b p a c k m y - a p p c d m y - a p p y a r n i n s t a l l y a r n r u n d e v 54
/ A p p . j s i m p o r t R e a c t , { C o m p o n e n t } f r o m ' r e a c t ' ; c l a s s A p p e x t e n d s C o m p o n e n t { c o n s t r u c t o r ( ) { s u p e r ( . . . a r g u m e n t s ) ; t h i s . s t a t e = { u s e r I d : t h i s . p r o p s . u s e r I d | | ' L o a d i n g . . . ' } ; } c o m p o n e n t D i d M o u n t ( ) { f e t c h ( ' h t t p : / / l o c a l h o s t : 8 0 8 0 / u s e r s / r a g i n g w i n d ' ) . t h e n ( r e s = > r e s . j s o n ( ) ) . t h e n ( u s e r I d = > t h i s . s e t S t a t e ( u s e r I d ) ) . c a t c h ( e r r = > c o n s o l e . l o g ( e r r ) ) ; } r e n d e r ( ) { r e t u r n ( < h 2 > U s e r I D : { t h i s . s t a t e . u s e r I d } < / h 2 > ) } } e x p o r t d e f a u l t A p p ; 56
node, 웹 관련 기술을 모두 사용가능 크로스 플랫폼 지원, Auto update, App store, ARM device 와 플랫폼 기능들 추가 중 오픈소스, 훌륭한 에코 시스템[1], [2]과 활발한 개발 Latest Chromium and Node npm 패키지 (거의 대부분) 그대로 사용가능 개발되는 많은 사용/ 오픈 어플리케이션들, Atom, Slack, VSCode, Wordpress 등 개발도구 지원이 훌륭 Devtron(Debug), Spectron(Test) 58
u p p r o j e c t a n d i n s t a l l p r e b u i l t e l e c t r o n . y a r n i n i t & & y a r n a d d - - d e v e l e c t r o n 2. Configure package.json { . . . " m a i n " : " m a i n . j s " " s c r i p t s " : { " s t a r t " : " e l e c t r o n . " } } 66
{ a p p , B r o w s e r W i n d o w } = r e q u i r e ( ' e l e c t r o n ' ) ; l e t m a i n W i n d o w ; a p p . o n ( ' r e a d y ' , ( ) = > { m a i n W i n d o w = n e w B r o w s e r W i n d o w ( { w i d t h : 8 0 0 , h e i g h t : 6 0 0 } ) ; m a i n W i n d o w . l o a d U R L ( ` f i l e : / / $ { _ _ d i r n a m e } / i n d e x . h t m l ` ) ; m a i n W i n d o w . o n ( ' c l o s e d ' , ( ) = > { m a i n W i n d o w = n u l l } ) ; } ) ; a p p . o n ( ' w i n d o w - a l l - c l o s e d ' , ( ) = > { i f ( p r o c e s s . p l a t f o r m ! = = ' d a r w i n ' ) { a p p . q u i t ( ) } } ) ; 4. index.html, for main view in renderer. and say Hello < h 1 > H e l l o ! < h 1 > < u l i d = " f i l e s " > < / u l > < s c r i p t t y p e = " t e x t / j a v a s c r i p t " s r c = " r e n d e r e . j s " > < / s c r i p t > 67
f s = r e q u i r e ( ' f s ' ) ; f s . r e a d d i r ( ' . ' , ( e r r , f i l e s ) = > { c o n s t u l = d o c u m e n t . q u e r y S e l e c t o r ( ' # f i l e s ' ) ; u l . i n n e r H T M L = f i l e s . m a p ( f = > { r e t u r n ` < l i > $ { f } < / l i > ` ; } ) . j o i n ( ' \ n ' ) ; } ) ; 6. run electron y a r n s t a r t 68
p r o j e c t a n d i n s t a l l p r e b u i l t e l e c t r o n . y a r n i n i t & & y a r n a d d - - d e v e l e c t r o n Configure package.json { . . . " m a i n " : " m a i n . j s " " s c r i p t s " : { " s t a r t " : " e l e c t r o n . " } } 69
l l w i t h y e o m a n n p m i n s t a l l - - g l o b a l y o g e n e r a t o r - e l e c t r o n # S c a f f o l d i n g e l e c t r o n a p p y o e l e c t r o n 70
Smart Ready, Smart, Classic 로 구분 최근 스펙은 4.2, Low-power IP(IPv6/LoWPAN) / Gateway for HTTP Proxy for RESTful Advertise: 특정 디바이스를 지정하지 않고 적은 바이트(31 byte) 를 일정 인터벌 동안 주변 디바이스 에게 시그널 방송(Broadcast), Advertiser 와 Observer 로 구분 Connection: Central 과 Peripheral 사이에 1:1 연결을 맺어 데이터를 타이밍에 맞게 전송 GATT (Generic Attribute Profile): BLE 데이터 커뮤니케이션을 담당, Read, Write 를 지원 RSSI (Received Signal Strength Indication): 수신 신호의 ( 총) 세기 (dBm) 74
peripherals sandeepmistry/node-bleacon: A Node.js library for iBeacons sandeepmistry/node-eddystone-beacon-scanner: Scanning Eddystone beacons using Node.js don/node-eddystone-beacon: Create an Eddystone Beacon using Node.js 78
l l n p m i n s t a l l - g e d d y s t o n e - b e a c o n - e m u l a t o r # a d v e r t i s i n g e d d y s t o n e - b e a c o n - e m u l a t o r - - u r i = h t t p : / / g o o . g l / e d d y s t o n e 79
d d y s t o n e B e a c o n S c a n n e r = r e q u i r e ( ' e d d y s t o n e - b e a c o n - s c a n n e r ' ) ; E d d y s t o n e B e a c o n S c a n n e r . o n ( ' f o u n d ' , f u n c t i o n ( b e a c o n ) { c o n s o l e . l o g ( ' f o u n d E d d y s t o n e B e a c o n : \ n ' , J S O N . s t r i n g i f y ( b e a c o n , n u l l , 2 ) ) ; } ) ; E d d y s t o n e B e a c o n S c a n n e r . o n ( ' u p d a t e d ' , f u n c t i o n ( b e a c o n ) { c o n s o l e . l o g ( ' u p d a t e d E d d y s t o n e B e a c o n : \ n ' , J S O N . s t r i n g i f y ( b e a c o n , n u l l , 2 ) ) ; } ) ; E d d y s t o n e B e a c o n S c a n n e r . o n ( ' l o s t ' , f u n c t i o n ( b e a c o n ) { c o n s o l e . l o g ( ' l o s t E d d y s t o n e b e a c o n : \ n ' , J S O N . s t r i n g i f y ( b e a c o n , n u l l , 2 ) ) ; } ) ; E d d y s t o n e B e a c o n S c a n n e r . s t a r t S c a n n i n g ( t r u e ) ; 80