Using RequireJS with CakePHP

30
USING REQUIREJS WITH CAKE PHP Stephen Young @young_steveo Sr. Software Engineer - Zumba Fitness

description

CakeFest 2013 presentation

Transcript of Using RequireJS with CakePHP

Page 1: Using RequireJS with CakePHP

USINGREQUIREJS

WITH CAKEPHPStephen Young @young_steveo

Sr. Software Engineer - Zumba Fitness

Page 2: Using RequireJS with CakePHP

WHAT'S THE POINT?

Page 3: Using RequireJS with CakePHP

The Javascript layer of a typical MVC app starts simple.

...like a jQuery Zen garden.

$(function(){ /* animate the blog title */ $('.title').slideDown();});

Page 4: Using RequireJS with CakePHP

As the project matures, things get a little more tricky.$(function(){ /* animate the blog title */ $('.title').slideDown(350, function(){ $.get('/stats/count').done(function(data){ $('.statsCount') .html(data.count) .addClass('green'); }); });});

Still maintainable... -ish

Page 5: Using RequireJS with CakePHP

...before long

Page 6: Using RequireJS with CakePHP

/* mega_file.js */$(function(){ if (window.isBlogPage && typeof window.App !== 'undefined') { var app = new App(); /* animate the blog title */ $('.title').slideDown(350, function(){ $.get('/stats/count').done(function(data){ $('.statsCount').html(data.count).addClass('green'); $.getScript('/js/superAwesomePlugin', function(){ $.get('/posts/someData').done(function(data){ if(data.posts){ doSomeCoolStuff(data.posts); } }); }); }); });

} else if (window.isCategory) {

/* oh, god, please, stop! */

Page 7: Using RequireJS with CakePHP

Don't forget the layout file...

Page 8: Using RequireJS with CakePHP

<script src="js/box2d/common/b2Settings.js"></script><script src="js/box2d/common/math/b2Vec2.js"></script><script src="js/box2d/common/math/b2Mat22.js"></script><script src="js/box2d/common/math/b2Math.js"></script><script src="js/box2d/collision/b2AABB.js"></script><script src="js/box2d/collision/b2Bound.js"></script><script src="js/box2d/collision/b2BoundValues.js"></script><script src="js/box2d/collision/b2Pair.js"></script><script src="js/box2d/collision/b2PairCallback.js"></script><script src="js/box2d/collision/b2BufferedPair.js"></script><script src="js/box2d/collision/b2PairManager.js"></script><script src="js/box2d/collision/b2BroadPhase.js"></script><script src="js/box2d/collision/b2Collision.js"></script><script src="js/box2d/collision/Features.js"></script><script src="js/box2d/collision/b2ContactID.js"></script><script src="js/box2d/collision/b2ContactPoint.js"></script><script src="js/box2d/collision/b2Distance.js"></script>

Page 9: Using RequireJS with CakePHP

THERE IS A BETTER WAY.

Page 10: Using RequireJS with CakePHP

WHAT IS REQUIREJS?javascript module & file loader

AMD (asynchronous module definition)

optimization tool

http://requirejs.org

Page 11: Using RequireJS with CakePHP

WHAT'S SO GREAT ABOUTAMD?

Encapsulation

Dependency Management

Page 12: Using RequireJS with CakePHP

AMD EXAMPLEDefine your modules:

/* define(id?, dependencies?, factory); */define("SomeModule", ["dependency"], function(dependency) { var SomeModule = function(){}; SomeModule.prototype.init = function(){ dependency.doStuff(); }; /* etc. */ return SomeModule;});

Page 13: Using RequireJS with CakePHP

AMD EXAMPLELoad your modules and use them:

/* require(dependencies, callback); */require(["ModuleA", "ModuleB"], function(ModuleA, ModuleB) { var module = new ModuleA(); ModuleA.init(); /* etc. */});

Page 14: Using RequireJS with CakePHP

REQUIRE()OR

DEFINE() ?Use `define` to declare a module for use elsewhere.

Use `require` to pre-load dependencies and/or do somestuff.

Page 15: Using RequireJS with CakePHP

WHAT IS CAKEPHP?(just kidding)

Page 16: Using RequireJS with CakePHP

HELLO WORLD/* app/Views/Layouts/someLayout.ctp */echo $this->Html->script("require.js", [ "data-main" => "/js/bootstrap"]);

/* app/webroot/js/bootstrap.js */requirejs.config({ paths : { jquery : 'js/vendor/jquery.min' }});require(['js/libs/blogs']);

/* app/webroot/js/libs/blogs.js */require(['jquery'], function($){ $(function(){ /* etc. */ });});

Page 17: Using RequireJS with CakePHP

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."

Page 18: Using RequireJS with CakePHP

TIPSKeep your modules focused; remember the singleresponsibility principle.

Define a solid directory structure, and stick to it.(like your CakePHP /app directory)

Think "automagic" and document your conventions./js/README.md

Page 19: Using RequireJS with CakePHP

GOING BEYOND"HELLO WORLD"

i.e. What if your project contains LOTS of javascript?

Page 20: Using RequireJS with CakePHP

DISCLAIMER

This works for us, and we like it, but feel free to tweak it tomeet your needs.

image from gifsoup.com

Page 21: Using RequireJS with CakePHP

IDENTIFY SECTIONS FORYOUR PROJECT

1. Break the project down into sections, and create amodule for each section (e.g. blog.js, shop.js, etc).

2. Identify any functionality that would be shared acrossmultiple sections, and put them into common modules.

Page 22: Using RequireJS with CakePHP

CHANGE THE LAYOUTBEFORE:

/* (data-main does the heavy lifting) */echo $this->Html->script("require.js", [ "data-main" => "/js/bootstrap"]);

AFTER:/* no more data-main */echo $this->Html->script("require.js");

<script>

require(['/js/bootstrap.js'], function(){ require(['modules/<?php echo $javascriptModule; ?>']); });

</script>

Page 23: Using RequireJS with CakePHP

MODIFY THEAPPCONTROLLER

public function beforeRender(){ $this->set(array( 'javascriptModule' => $this->javascriptModule ));} public function beforeFilter() { /* just a nice convention, you could use a default file too */ if (!$this->javascriptModule){ $moduleName = Inflector::underscore($this->name); $this->javascriptModule = $moduleName; }}

Page 24: Using RequireJS with CakePHP

NEW BOOTSTRAP.JS FILErequirejs.config({ paths : { jquery : 'js/vendor/jquery', someLib : 'js/libs/someLib', anotherLib : 'js/libs/anotherLib' }, shim : { anotherLib : ['jquery', 'someLib'] }});

Page 25: Using RequireJS with CakePHP

OPTIMIZATION

Page 26: Using RequireJS with CakePHP

R.JSRequireJS 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 notgoing to cover that today)

Page 27: Using RequireJS with CakePHP

CONCATENATEDEPENDENCIES

r.js will combine modules that are specified asdependencies in your module definitions

Page 28: Using RequireJS with CakePHP

CONFIGURATION FILE{ "modules": [ { "name" : "bootstrap", "include" : [ "underscore", "backbone", "jquery" ] }, { "name" : "blogs", exclude: ['bootstrap'] }, { "name" : "shops", exclude: ['bootstrap'] }, { "name" : "profiles", exclude: ['bootstrap'] }, /* etc. */

Page 29: Using RequireJS with CakePHP

THAT'S IT!QUESTIONS?

Page 30: Using RequireJS with CakePHP

EXAMPLE REPOgithub.com/young-steveo/require_cake