Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Towards AngularJS2, with Webpack and ES6

Towards AngularJS2, with Webpack and ES6

Bucharest AngularJS meetup #2.

Alexandru Badiu

May 28, 2015
Tweet

More Decks by Alexandru Badiu

Other Decks in Technology

Transcript

  1. IN THIS PRESENTATION Why we settled on Webpack How can

    you make your transition to AngularJS 2 easier
  2. GRUNT Grunt with Yeoman The “classic” structure Put as much

    as we could inside Bower / c o n t r o l l e r s / s e r v i c e s / f i l t e r s / d i r e c t i v e s / v i e w s
  3. GULP Gulp and Browserify A “component” based structure Worked pretty

    well / s e a r c h / a u t h / m i s c / c o r e
  4. BUT... Lazy loading? Polymer, Web components Component directives Self contained

    modules Bundle the assets, templates and CSS as well?
  5. BUT... Browserify can't do that But it's ecosystem can OSCON

    2014: How Instagram.com Works; Pete Hunt Webpack!
  6. WEBPACK REQUIRE ALL THE THINGS! r e q u i

    r e ( ' . / t e m p l a t e . h t m l ' ) ; r e q u i r e ( ' . / t e m p l a t e . j a d e ' ) ; r e q u i r e ( ' . / c o m p o n e n t . s c s s ' ) ; r e q u i r e ( ' . / l o g o . i m g ' ) ; r e q u i r e ( ' . / j s m o d u l e ' ) ; r e q u i r e ( ' . / j s m o d u l e . e s 6 ' ) ;
  7. WEBPACK One or more entry points Dependency graph Extensible via

    loaders One or more bundles Lazy loading
  8. WEBPACK e n t r y : " . /

    a p p / m a i n . j s " , o u t p u t : { p a t h : p a t h . r e s o l v e ( _ _ d i r n a m e , ' . / b u i l d ' ) , f i l e n a m e : ' [ n a m e ] . j s ' } , m o d u l e : { l o a d e r s : [ { t e s t : / \ . j s $ / , l o a d e r : ' b a b e l - l o a d e r ' } , { t e s t : / \ . s c s s $ / , l o a d e r : ' s t y l e - l o a d e r ! c s s - l o a d e r ! a u t o p r e f i x e r - l o a d e r ! s a s s - l o a d e r ' } , { t e s t : / \ . p n g $ / , l o a d e r : ' u r l - l o a d e r ? l i m i t = 1 0 0 0 0 0 & m i m e t y p e = i m a g e / p n g ' } ] } , r e s o l v e : { m o d u l e s D i r e c t o r i e s : [ ' n o d e _ m o d u l e s ' , ' a p p / v e n d o r ' ] , a l i a s : { l o d a s h : p a t h . r e s o l v e ( _ _ d i r n a m e , ' . / a p p / v e n d o r / l o d a s h ' ) } } , p l u g i n s : [ n e w w e b p a c k . P r o v i d e P l u g i n ( { _ : ' l o d a s h ' } ) ]
  9. WEBPACK ' u s e s t r i c

    t ' ; r e q u i r e ( ' . / f o o . s c s s ' ) ; v a r m o d = a n g u l a r . m o d u l e ( ' b a r . f o o ' , [ r e q u i r e ( ' . . / c o m p o n e n t s / h e a d e r ' ) . n a m e , r e q u i r e ( ' . . / c o m p o n e n t s / f o o t e r ' ) . n a m e , r e q u i r e ( ' . . / c o m p o n e n t s / s e a r c h ' ) . n a m e , r e q u i r e ( ' . . / c o m p o n e n t s / s e a r c h - u i ' ) . n a m e ] ) ; r e g i s t e r ( m o d . n a m e ) . c o n t r o l l e r ( ' F o o C o n t r o l l e r ' , r e q u i r e ( ' . / f o o . j s ' ) ) ; m o d u l e . e x p o r t s = m o d ;
  10. WEBPACK ' u s e s t r i c

    t ' ; r e q u i r e ( ' . / b a r . s c s s ' ) ; r e q u i r e ( ' u i . b o o t s t r a p / s r c / d r o p d o w n / d r o p d o w n ' ) ; v a r m o d = a n g u l a r . m o d u l e ( ' f o o . b a r ' , [ ' u i . b o o t s t r a p . d r o p d o w n ' ] ) ; r e g i s t e r ( m o d . n a m e ) . d i r e c t i v e ( ' b a r ' , r e q u i r e ( ' . / b a r . j s ' ) ) ; m o d u l e . e x p o r t s = m o d ;
  11. STRUCTURE Inspired by Google's / i n d e x

    . j a d e / m a i n . j s / s t a t e 1 / / s t a t e 2 / / c o m p o n e n t s /
  12. STRUCTURE Components / c o r e / i n

    d e p e n d e n t _ m o d u l e 1 / i n d e p e n d e n t _ m o d u l e 2 / u i / / u i / h e a d e r / / u i / s e a r c h - b o x /
  13. LAZY LOADING r e q u i r e .

    e n s u r e ( ) ; . s t a t e ( ' f o o ' , { r e s o l v e : / * @ n g I n j e c t * / f u n c t i o n ( $ q , $ o c L a z y L o a d ) { r e q u i r e . e n s u r e ( [ ] , f u n c t i o n ( ) { v a r m o d = r e q u i r e ( ' . / f o o ' ) ; } ) ; } } ) . s t a t e ( ' b a r ' , { r e s o l v e : / * @ n g I n j e c t * / f u n c t i o n ( $ q , $ o c L a z y L o a d ) { r e q u i r e . e n s u r e ( [ ] , f u n c t i o n ( ) { v a r m o d = r e q u i r e ( ' . / b a r ' ) ; } ) ; } } )
  14. LAZY LOADING We'll use ocLazyLoad . s t a t

    e ( ' f o o ' , { r e s o l v e : / * @ n g I n j e c t * / f u n c t i o n ( $ q , $ o c L a z y L o a d ) { v a r d e f e r r e d = $ q . d e f e r ( ) ; r e q u i r e . e n s u r e ( [ ] , f u n c t i o n ( ) { v a r m o d = r e q u i r e ( ' . / f o o ' ) ; $ o c L a z y L o a d . l o a d ( { n a m e : m o d . n a m e } ) ; d e f e r r e d . r e s o l v e ( m o d . c o n t r o l l e r ) ; } ) ; r e t u r n d e f e r r e d . p r o m i s e ; } } )
  15. LAZY LOADING Webpack does the async loading ocLazyLoad registers the

    new module Support for Webpack in ocLazyLoad 1.2
  16. NO MORE $SCOPE Use c o n t r o

    l l e r A s and b i n d T o C o n t r o l l e r t h i s . t e m p l a t e = r e q u i r e ( ' . / s e a r c h - b o x . j a d e ' ) ; t h i s . r e s t r i c t = ' E ' ; t h i s . r e p l a c e = t r u e ; t h i s . c o n t r o l l e r = S e a r c h B o x C o n t r o l l e r ; t h i s . c o n t r o l l e r A s = ' c t r l ' ; t h i s . b i n d T o C o n t r o l l e r = t r u e ; t h i s . s c o p e = { p r e f i x : ' = ' , m o d e l : ' = n g M o d e l ' } ;
  17. NO MORE $SCOPE In AngularJS 1.4 t h i s

    . t e m p l a t e = r e q u i r e ( ' . / s e a r c h - b o x . j a d e ' ) ; t h i s . r e s t r i c t = ' E ' ; t h i s . r e p l a c e = t r u e ; t h i s . c o n t r o l l e r = S e a r c h B o x C o n t r o l l e r ; t h i s . c o n t r o l l e r A s = ' c t r l ' ; t h i s . b i n d T o C o n t r o l l e r = { p r e f i x : ' = ' , m o d e l : ' = n g M o d e l ' } ;
  18. NO MORE $SCOPE Can't get rid of $scope completly now

    $ w a t c h , $ d i g e s t etc Treat it like any other service and inject it when needed $ s c o p e . $ w a t c h ( ( ) = > { r e t u r n t h i s . e f i l t e r ; } , ( n e w V a l ) = > { t h i s . u p d a t e F i l t e r ( n e w V a l ) ; } ) ;
  19. TYPESCRIPT AND ES6 We can use ES6 today b a

    b e l - l o a d e r TypeScript too
  20. WHY? They are still in their infancy One man /

    woman projects Support? Lots of magic Training new people
  21. IN THAT CASE... How can we use ES 6 classes?

    r e g i s t e r . j s : A small library that anyone can understand in 5 minutes that allows registering classes as directives, controllers etc Exploring ES6 Classes In AngularJS 1.x
  22. REGISTER.JS r e g i s t e r (

    ' a p p ' ) . c o n t r o l l e r ( ' M y C o n t r o l l e r ' , r e q u i r e ( ' . / m y - a n g u l a r - c o n t r o l l e r ' ) ) . s e r v i c e ( ' m y S e r v i c e ' , r e q u i r e ( ' . / m y - a n g u l a r - s e r v i c e ' ) ) . p r o v i d e r ( ' m y O t h e r S e r v i c e ' , r e q u i r e ( ' . / m y - a n g u l a r - p r o v i d e r ' ) ) . f a c t o r y ( ' m y F a c t o r y ' , r e q u i r e ( ' . / m y - a n g u l a r - f a c t o r y ' ) ) . d i r e c t i v e ( ' m y D i r e c t i v e ' , r e q u i r e ( ' . / m y - a n g u l a r - d i r e c t i v e ' ) ) ;
  23. ES6 c l a s s M y D i

    r e c t i v e { / * @ n g I n j e c t * / c o n s t r u c t o r ( $ i n t e r v a l ) { t h i s . t e m p l a t e = ' < d i v > I \ ' m a d i r e c t i v e ! < / d i v > ' ; t h i s . r e s t r i c t = ' E ' ; t h i s . s c o p e = { } ; t h i s . $ i n t e r v a l = $ i n t e r v a l ; } c o m p i l e ( t E l e m e n t ) { t E l e m e n t . c s s ( ' p o s i t i o n ' , ' a b s o l u t e ' ) ; } l i n k ( s c o p e , e l e m e n t ) { t h i s . $ i n t e r v a l ( ( ) = > t h i s . m o v e ( e l e m e n t ) , 1 0 0 0 ) ; } m o v e ( e l e m e n t ) { e l e m e n t . c s s ( ' l e f t ' , ( M a t h . r a n d o m ( ) * 5 0 0 ) + ' p x ' ) ; e l e m e n t . c s s ( ' t o p ' , ( M a t h . r a n d o m ( ) * 5 0 0 ) + ' p x ' ) ; } }
  24. ES6 c l a s s M y D i

    r e c t i v e { / * @ n g I n j e c t * / c o n s t r u c t o r ( ) { / / . . . t h i s . s c o p e = { t i t l e : ' = ' } ; t h i s . c o n t r o l l e r = ' M y D i r e c t i v e C o n t r o l l e r ' ; t h i s . c o n t r o l l e r A s = ' c t r l ' ; t h i s . b i n d T o C o n t r o l l e r = t r u e ; } } c l a s s M y D i r e c t i v e C o n t r o l l e r { / * @ n g I n j e c t * / c o n s t r u c t o r ( $ w i n d o w ) { t h i s . $ w i n d o w = $ w i n d o w ; c o n s o l e . l o g ( t h i s . t i t l e ) ; } } m o d u l e . e x p o r t s = M y D i r e c t i v e ;
  25. INJECTION M y D i r e c t i

    v e C o n t r o l l e r . $ i n j e c t = [ ' $ w i n d o w ' ] ; Do it automatically with n g - a n n o t a t o r . c l a s s M y D i r e c t i v e C o n t r o l l e r { / * @ n g I n j e c t * / c o n s t r u c t o r ( $ w i n d o w ) { } } r e s o l v e : / * @ n g I n j e c t * / f u n c t i o n ( $ q , $ o c L a z y L o a d ) { }
  26. THE FINAL STACK Gulp Webpack and webpack-dev-server Superstatic and BrowserSync

    ES6 and eslint Jade SASS and Bourbon Karma and Protractor, local or remote via SauceLabs Mocha, Chai, Sinon, Istanbul Bamboo