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

Using Require.js with CakePHP

Using Require.js with CakePHP

The CakePHP framework provides excellent tools to structure and organize server code -- making development fun and maintainable. Combining these tools with a solid Require.js implementation can elevate the often haphazard front-end development experience to the same level of excellence.

This talk will give a very brief overview of Require.js and it's benefits. It will outline a typical Require.js "Hello World" implementation. This will be followed by a more robust implementation for projects that are backed by CakePHP and have thousands of lines of javascript.

The talk will end with notes on configuring the Require.js optimizer to combine and minify the source for deployment.

Zumba Technology

August 31, 2013
Tweet

More Decks by Zumba Technology

Other Decks in Programming

Transcript

  1. The Javascript layer of a typical MVC app starts simple.

    ...like a jQuery Zen garden. $ ( f u n c t i o n ( ) { / * a n i m a t e t h e b l o g t i t l e * / $ ( ' . t i t l e ' ) . s l i d e D o w n ( ) ; } ) ;
  2. As the project matures, things get a little more tricky.

    $ ( f u n c t i o n ( ) { / * a n i m a t e t h e b l o g t i t l e * / $ ( ' . t i t l e ' ) . s l i d e D o w n ( 3 5 0 , f u n c t i o n ( ) { $ . g e t ( ' / s t a t s / c o u n t ' ) . d o n e ( f u n c t i o n ( d a t a ) { $ ( ' . s t a t s C o u n t ' ) . h t m l ( d a t a . c o u n t ) . a d d C l a s s ( ' g r e e n ' ) ; } ) ; } ) ; } ) ; Still maintainable... -ish
  3. / * m e g a _ f i l

    e . j s * / $ ( f u n c t i o n ( ) { i f ( w i n d o w . i s B l o g P a g e & & t y p e o f w i n d o w . A p p ! = = ' u n d e f i n e d ' ) { v a r a p p = n e w A p p ( ) ; / * a n i m a t e t h e b l o g t i t l e * / $ ( ' . t i t l e ' ) . s l i d e D o w n ( 3 5 0 , f u n c t i o n ( ) { $ . g e t ( ' / s t a t s / c o u n t ' ) . d o n e ( f u n c t i o n ( d a t a ) { $ ( ' . s t a t s C o u n t ' ) . h t m l ( d a t a . c o u n t ) . a d d C l a s s ( ' g r e e n ' ) ; $ . g e t S c r i p t ( ' / j s / s u p e r A w e s o m e P l u g i n ' , f u n c t i o n ( ) { $ . g e t ( ' / p o s t s / s o m e D a t a ' ) . d o n e ( f u n c t i o n ( d a t a ) { i f ( d a t a . p o s t s ) { d o S o m e C o o l S t u f f ( d a t a . p o s t s ) ; } } ) ; } ) ; } ) ; } ) ; } e l s e i f ( w i n d o w . i s C a t e g o r y ) { / * o h , g o d , p l e a s e , s t o p ! * /
  4. < s c r i p t s r c

    = " j s / b o x 2 d / c o m m o n / b 2 S e t t i n g s . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o m m o n / m a t h / b 2 V e c 2 . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o m m o n / m a t h / b 2 M a t 2 2 . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o m m o n / m a t h / b 2 M a t h . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 A A B B . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 B o u n d . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 B o u n d V a l u e s . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 P a i r . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 P a i r C a l l b a c k . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 B u f f e r e d P a i r . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 P a i r M a n a g e r . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 B r o a d P h a s e . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 C o l l i s i o n . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / F e a t u r e s . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 C o n t a c t I D . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 C o n t a c t P o i n t . j s " > < / s c r i p t > < s c r i p t s r c = " j s / b o x 2 d / c o l l i s i o n / b 2 D i s t a n c e . j s " > < / s c r i p t >
  5. WHAT IS REQUIREJS? javascript module & file loader AMD (asynchronous

    module definition) optimization tool http://requirejs.org
  6. AMD EXAMPLE Define your modules: / * d e f

    i n e ( i d ? , d e p e n d e n c i e s ? , f a c t o r y ) ; * / d e f i n e ( " S o m e M o d u l e " , [ " d e p e n d e n c y " ] , f u n c t i o n ( d e p e n d e n c y ) { v a r S o m e M o d u l e = f u n c t i o n ( ) { } ; S o m e M o d u l e . p r o t o t y p e . i n i t = f u n c t i o n ( ) { d e p e n d e n c y . d o S t u f f ( ) ; } ; / * e t c . * / r e t u r n S o m e M o d u l e ; } ) ;
  7. AMD EXAMPLE Load your modules and use them: / *

    r e q u i r e ( d e p e n d e n c i e s , c a l l b a c k ) ; * / r e q u i r e ( [ " M o d u l e A " , " M o d u l e B " ] , f u n c t i o n ( M o d u l e A , M o d u l e B ) { v a r m o d u l e = n e w M o d u l e A ( ) ; M o d u l e A . i n i t ( ) ; / * e t c . * / } ) ;
  8. REQUIRE() OR DEFINE() ? Use `define` to declare a module

    for use elsewhere. Use `require` to pre-load dependencies and/or do some stuff.
  9. HELLO WORLD / * a p p / V i

    e w s / L a y o u t s / s o m e L a y o u t . c t p * / e c h o $ t h i s - > H t m l - > s c r i p t ( " r e q u i r e . j s " , [ " d a t a - m a i n " = > " / j s / b o o t s t r a p " ] ) ; / * a p p / w e b r o o t / j s / b o o t s t r a p . j s * / r e q u i r e j s . c o n f i g ( { p a t h s : { j q u e r y : ' j s / v e n d o r / j q u e r y . m i n ' } } ) ; r e q u i r e ( [ ' j s / l i b s / b l o g s ' ] ) ; / * a p p / w e b r o o t / j s / l i b s / b l o g s . j s * / r e q u i r e ( [ ' j q u e r y ' ] , f u n c t i o n ( $ ) { $ ( f u n c t i o n ( ) { / * e t c . * / } ) ; } ) ;
  10. IT IS THAT SIMPLE. IS IT THAT SIMPLE? IT NEVER

    IS, IS IT? Even with RequireJS, things can get out of hand. As with many great tools, RequireJS gives you plenty of "rope."
  11. TIPS Keep your modules focused; remember the single responsibility principle.

    Define a solid directory structure, and stick to it. (like your CakePHP /app directory) Think "automagic" and document your conventions. / j s / R E A D M E . m d
  12. DISCLAIMER This works for us, and we like it, but

    feel free to tweak it to meet your needs.
  13. IDENTIFY SECTIONS FOR YOUR PROJECT 1. Break the project down

    into sections, and create a module for each section (e.g. b l o g . j s , s h o p . j s , etc). 2. Identify any functionality that would be shared across multiple sections, and put them into common modules.
  14. CHANGE THE LAYOUT BEFORE: / * ( d a t

    a - m a i n d o e s t h e h e a v y l i f t i n g ) * / e c h o $ t h i s - > H t m l - > s c r i p t ( " r e q u i r e . j s " , [ " d a t a - m a i n " = > " / j s / b o o t s t r a p " ] ) ; AFTER: / * n o m o r e d a t a - m a i n * / e c h o $ t h i s - > H t m l - > s c r i p t ( " r e q u i r e . j s " ) ; < s c r i p t > r e q u i r e ( [ ' / j s / b o o t s t r a p . j s ' ] , f u n c t i o n ( ) { r e q u i r e ( [ ' m o d u l e s / < ? p h p e c h o $ j a v a s c r i p t M o d u l e ; ? > ' ] ) ; } ) ; < / s c r i p t >
  15. MODIFY THE APPCONTROLLER p u b l i c f

    u n c t i o n b e f o r e R e n d e r ( ) { $ t h i s - > s e t ( a r r a y ( ' j a v a s c r i p t M o d u l e ' = > $ t h i s - > j a v a s c r i p t M o d u l e ) ) ; } p u b l i c f u n c t i o n b e f o r e F i l t e r ( ) { / * j u s t a n i c e c o n v e n t i o n , y o u c o u l d u s e a d e f a u l t f i l e t o o * / i f ( ! $ t h i s - > j a v a s c r i p t M o d u l e ) { $ m o d u l e N a m e = I n f l e c t o r : : u n d e r s c o r e ( $ t h i s - > n a m e ) ; $ t h i s - > j a v a s c r i p t M o d u l e = $ m o d u l e N a m e ; } }
  16. NEW BOOTSTRAP.JS FILE r e q u i r e

    j s . c o n f i g ( { p a t h s : { j q u e r y : ' j s / v e n d o r / j q u e r y ' , s o m e L i b : ' j s / l i b s / s o m e L i b ' , a n o t h e r L i b : ' j s / l i b s / a n o t h e r L i b ' } , s h i m : { a n o t h e r L i b : [ ' j q u e r y ' , ' s o m e L i b ' ] } } ) ;
  17. R.JS RequireJS ships with a great minification/concatenation tool It runs

    in Node.js, Java with Rhino, or a browser It is configurable Bonus: it can minify CSS files for you too (but I'm not going to cover that today)
  18. CONFIGURATION FILE { " m o d u l e

    s " : [ { " n a m e " : " b o o t s t r a p " , " i n c l u d e " : [ " u n d e r s c o r e " , " b a c k b o n e " , " j q u e r y " ] } , { " n a m e " : " b l o g s " , e x c l u d e : [ ' b o o t s t r a p ' ] } , { " n a m e " : " s h o p s " , e x c l u d e : [ ' b o o t s t r a p ' ] } , { " n a m e " : " p r o f i l e s " , e x c l u d e : [ ' b o o t s t r a p ' ] } , / * e t c . * /