TA L K

Zombie Code

Zombie Code how to survive a Javascript Zombiecodeapocalypse

First things first my name is @cedmax

cedmax @ Shazam

cedmax @ Shazam Flav Umar Luca Beer ced

Basically Zombies?

Basically Zombies?

Zombies! “Brains, BRAINS, BRains, brains, BRAINS. BRaiNS, brains, Brains, BRAINS, BRains, brains, BRAINS. BRAINS, BRains, brains, BRAINS, brains.” Ryan Mecum

ZOMBIE CODE?

it’s not dead code http://alfasin.com/i-see-dead-code-homage-for-intellij-idea/

It may seems harmless http://couchpotatofiles.wordpress.com/2012/03/20/the-walking-dead-ups-the-death-count-and-the-ratings/

http://couchpotatofiles.wordpress.com/2012/03/20/the-walking-dead-ups-the-death-count-and-the-ratings/ but it’s NOT

and it will, eventually http://imgur.com/r/SRDBroke/JimqK CODE

during estimation

during debugging

during development

It is dumb code  that makes you dumb as well

Hopefully it’s not too late http://tacticaltshirts.com/shop/shirt-zombies-eat-brains/

How to identify  Zombie CODE ?

What's that smell? Zombies smell worse than anything you can imagine Lilith Saintcrow, Strange Angels

3 tips

TIp #1  Code should be appealing

function validate ( options ) {

// if nothing is selected, return nothing; can't chain anyway

if ( ! this . length ) {

if ( options && options.debug &&

window . console ) {

console .warn ( "Nothing selected, can't validate, returning nothing." ); }

return ; }

// check if a validator for this form was already created var validator

$ . data ( this [ 0 ], "validator" );

if ( validator ) {

return validator; }

// Add novalidate tag if HTML5.

this .attr( "novalidate" , "novalidate" ); validator

new

$ .validator( options, this [ 0 ] );

$ . data ( this [ 0 ], "validator" , validator );

if ( validator.settings.onsubmit ) {

this .validateDelegate( ":submit" , "click" , function( event ) {

if ( validator.settings.submitHandler ) { validator.submitButton

event . target ; }

// allow suppressing validation by adding a cancel class to the submit button

if ( $ ( event . target ).hasClass( "cancel" ) ) { validator.cancelSubmit

true ; }

// allow suppressing validation by adding the html5 formnovalidate attribute to the submit button

if ( $ ( event . target ).attr( "formnovalidate" ) !==

undefined ) { validator.cancelSubmit

true ; } });

// validate the form on submit

this . submit ( function( event ) {

if ( validator.settings.debug ) {

// prevent form submit to be able to see console output

event .preventDefault(); } function handle () { var hidden;

if ( validator.settings.submitHandler ) {

if ( validator.submitButton ) {

// insert a hidden input as a replacement for the missing submit button hidden

$ ( "<input type='hidden'/>" ).attr( "name" , validator.submitButton. name ).val( $ (validator.submitButton).val() ).appendTo(validator.currentForm); }

                    validator.settings.submitHandler.

call ( validator, validator.currentForm, event );

if ( validator.submitButton ) {

// and clean up afterwards; thanks to no-block-scope, hidden can be referenced hidden. remove (); }

return

false ; }

return

true ; }

// prevent submit for invalid forms or custom submit handlers

if ( validator.cancelSubmit ) { validator.cancelSubmit

false ;

return handle(); }

if ( validator. form () ) {

if ( validator.pendingRequest ) { validator.formSubmitted

true ;

return

false ; }

return handle(); } else { validator.focusInvalid();

return

false ; } }); }

return validator; }

HOW LONG IS THAT?

function validate ( options ) {

// if nothing is selected, return nothing; can't chain anyway

if ( ! this . length ) {

if ( options && options.debug &&

window . console ) {

console .warn ( "Nothing selected, can't validate, returning nothing." ); }

return ; }

// check if a validator for this form was already created var validator

$ . data ( this [ 0 ], "validator" );

if ( validator ) {

return validator; }

// Add novalidate tag if HTML5.

this .attr( "novalidate" , "novalidate" ); validator

new

$ .validator( options, this [ 0 ] );

$ . data ( this [ 0 ], "validator" , validator );

if ( validator.settings.onsubmit ) {

this .validateDelegate( ":submit" , "click" , function( event ) {

if ( validator.settings.submitHandler ) { validator.submitButton

event . target ; }

// allow suppressing validation by adding a cancel class to the submit button

if ( $ ( event . target ).hasClass( "cancel" ) ) { validator.cancelSubmit

true ; }

// allow suppressing validation by adding the html5 formnovalidate attribute to the submit button

if ( $ ( event . target ).attr( "formnovalidate" ) !==

undefined ) { validator.cancelSubmit

true ; } });

// validate the form on submit

this . submit ( function( event ) {

if ( validator.settings.debug ) {

// prevent form submit to be able to see console output

event .preventDefault(); } function handle () { var hidden;

if ( validator.settings.submitHandler ) {

if ( validator.submitButton ) {

// insert a hidden input as a replacement for the missing submit button hidden

$ ( "<input type='hidden'/>" ).attr( "name" , validator.submitButton. name ).val( $ (validator.submitButton).val() ).appendTo(validator.currentForm); } validator.settings.submitHandler. call ( validator, validator.currentForm, event );

if ( validator.submitButton ) {

// and clean up afterwards; thanks to no-block-scope, hidden can be referenced hidden. remove (); }

return

false ; }

return

true ; }

// prevent submit for invalid forms or custom submit handlers

if ( validator.cancelSubmit ) { validator.cancelSubmit

false ;

return handle(); }

if ( validator. form () ) {

if ( validator.pendingRequest ) { validator.formSubmitted

true ;

return

false ; }

return handle(); } else { validator.focusInvalid();

return

false ; } }); }

return validator; }

14 (FOURTEEN!) ifs

function validate ( options ) {

// if nothing is selected, return nothing; can't chain anyway

if ( ! this . length ) {

if ( options && options.debug &&

window . console ) {

console .warn ( "Nothing selected, can't validate, returning nothing." ); }

return ; }

// check if a validator for this form was already created var validator

$ . data ( this [ 0 ], "validator" );

if ( validator ) {

return validator; }

// Add novalidate tag if HTML5.

this .attr( "novalidate" , "novalidate" ); validator

new

$ .validator( options, this [ 0 ] );

$ . data ( this [ 0 ], "validator" , validator );

if ( validator.settings.onsubmit ) {

this .validateDelegate( ":submit" , "click" , function( event ) {

if ( validator.settings.submitHandler ) { validator.submitButton

event . target ; }

// allow suppressing validation by adding a cancel class to the submit button

if ( $ ( event . target ).hasClass( "cancel" ) ) { validator.cancelSubmit

true ; }

// allow suppressing validation by adding the html5 formnovalidate attribute to the submit button

if ( $ ( event . target ).attr( "formnovalidate" ) !==

undefined ) { validator.cancelSubmit

true ; } });

// validate the form on submit

this . submit ( function( event ) {

if ( validator.settings.debug ) {

// prevent form submit to be able to see console output

event .preventDefault(); } function handle () { var hidden;

if ( validator.settings.submitHandler ) {

if ( validator.submitButton ) {

// insert a hidden input as a replacement for the missing submit button hidden

$ ( "<input type='hidden'/>" ).attr( "name" , validator.submitButton. name ).val( $ (validator.submitButton).val() ).appendTo(validator.currentForm); } validator.settings.submitHandler. call ( validator, validator.currentForm, event );

if ( validator.submitButton ) {

// and clean up afterwards; thanks to no-block-scope, hidden can be referenced hidden. remove (); }

return

false ; }

return

true ; }

// prevent submit for invalid forms or custom submit handlers

if ( validator.cancelSubmit ) { validator.cancelSubmit

false ;

return handle(); }

if ( validator. form () ) {

if ( validator.pendingRequest ) { validator.formSubmitted

true ;

return

false ; }

return handle(); } else { validator.focusInvalid();

return

false ; } }); }

return validator; }

are comments a bad thing?

TIp #2  Code should talk to you

_ $

= ( function (_) {

return {

pub : function (a, b, c, d) {

for (d =- 1 , c

[].concat(_[a]); c[ ++ d];) cd },

sub : function (a, b) { ([a] || ([a]

[])).push(b) } } })({})

_ $

= ( function (_) {

return {

pub : function (a, b, c, d) {

for (d =- 1 , c

[].concat(_[a]); c[ ++ d];) cd },

sub : function (a, b) { ([a] || ([a]

[])).push(b) } } })({}) #140bytes

_ $

= ( function () {

var registered

{};

return {

pub : function (event, memo) {

if (registered[event] instanceof Array){

var handlers

[].concat(registered[event]);

for ( var i

0 , handler; (handler

handlers[i]); i ++ ){ handler.call(this, memo); } } },

sub : function (event, handler) {

if ( typeof registered[event]

"undefined" ){ registered[event]

[]; } registered[event].push(handler); } }; })();

don’t use comments as an excuse to write bad code

//used translate3d to trigger hardware acceleration in webViews //http://www.youtube.com/watch?v=IKl78ZgJzm4 .animated { translate: translate 3 d( 0 , 0 , 0 ) } /**

  • Returns a unique ID for use in HTML id attribute.
  • @param {String/Number} nr A name or number of the ID.
  • @param {String} [prefix="id-"] The prefix for the ID.
  • @return {String} the new ID */ function

createId (nr, prefix){

//TODO implementation }

//used translate3d to trigger hardware acceleration in webViews //http://www.youtube.com/watch?v=IKl78ZgJzm4 .animated { translate: translate 3 d( 0 , 0 , 0 ) } /**

  • Returns a unique ID for use in HTML id attribute.
  • @param {String/Number} nr A name or number of the ID.
  • @param {String} [prefix="id-"] The prefix for the ID.
  • @return {String} the new ID */ function

createId (nr, prefix){

//TODO implementation } un-avoidable hacks explanation

//used translate3d to trigger hardware acceleration in webViews //http://www.youtube.com/watch?v=IKl78ZgJzm4 .animated { translate: translate 3 d( 0 , 0 , 0 ) } /**

  • Returns a unique ID for use in HTML id attribute.
  • @param {String/Number} nr A name or number of the ID.
  • @param {String} [prefix="id-"] The prefix for the ID.
  • @return {String} the new ID */ function

createId (nr, prefix){

//TODO implementation } un-avoidable hacks explanation AUTOMATED DOC GENERATION

//used translate3d to trigger hardware acceleration in webViews //http://www.youtube.com/watch?v=IKl78ZgJzm4 .animated { translate: translate 3 d( 0 , 0 , 0 ) } /**

  • Returns a unique ID for use in HTML id attribute.
  • @param {String/Number} nr A name or number of the ID.
  • @param {String} [prefix="id-"] The prefix for the ID.
  • @return {String} the new ID */ function

createId (nr, prefix){

//TODO implementation } un-avoidable hacks explanation AUTOMATED DOC GENERATION TODOs

TIp #3  Code should have 
 personal boundaries

Define 
 boundaries

Single responsibility principle your best tool against Zombie Code

No global pollution http://leosabanganii.blogspot.co.uk/2012/10/zombie-dressed-activists-protest.html

No coupling http://leosabanganii.blogspot.co.uk/2012/10/zombie-dressed-activists-protest.html http://ajandcharli.blogspot.co.uk/2011/05/we-dont-do-dead-people.html

code-sense is the key Writing clean code requires the disciplined use of a myriad little techniques applied through a painstakingly acquired sense of "cleanliness". Robert C. Martin

worst case smell

worst case smell Long methods

worst case smell Long methods Deep Level of Indentation

worst case smell Long methods Deep Level of Indentation Hard to tell what it does

worst case smell Long methods Deep Level of Indentation Hard to tell what it does Lack of portability

worst case smell Long methods Deep Level of Indentation Hard to tell what it does Lack of portability Hardcoded style/templating

worst case smell Long methods Deep Level of Indentation Hard to tell what it does Lack of portability Hardcoded style/templating Logic block duplication

worst case smell Long methods Deep Level of Indentation Hard to tell what it does Lack of portability Hardcoded style/templating Logic block duplication Callback hell

And now what?

Play cool!

Basically Quarantine

Basically Quarantine

QUARANTINE Most teams are trying to stop further spread only through quarantines. It's a good short-term solution , but it won't prevent long-term population loss. http://cdmx.it/quarantinequote

The broken window

“Don't leave "broken windows" (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered.” Jeff Atwood 
 http://www.codinghorror.com/blog/2005/06/the-broken-window-theory.html The broken window

“Programming is insanely detail oriented, and perhaps this is why: if you're not on top of the details, the perception is that things are out of control, and it's only a matter of time before your project spins out of control.” Jeff Atwood 
 http://www.codinghorror.com/blog/2005/06/the-broken-window-theory.html The broken window

Maybe we should be sweating the small stuff. Jeff Atwood 
 http://www.codinghorror.com/blog/2005/06/the-broken-window-theory.html The broken window

Isolate the

Zombies

define style guidelines

function

Zombie (personName) {

function

do_something () { console.log(personName +

" just ate a brain!" ); }

return { doSomethingZombiesDo: do_something }; } var adam

new Zombie( "Adam" ); adam.doSomethingZombiesDo();

function

Zombie (personName) {

function

do_something () { console.log(personName +

" just ate a brain!" ); }

return { doSomethingZombiesDo: do_something }; } var adam

new Zombie( "Adam" ); adam.doSomethingZombiesDo();

function

Zombie (personName) {

function

do_something () { console.log(personName +

" just ate a brain!" ); }

return { doSomethingZombiesDo: do_something }; } var adam

new Zombie( "Adam" ); adam.doSomethingZombiesDo();

function

Zombie (personName) {

function

do_something () { console.log(personName +

" just ate a brain!" ); }

return { doSomethingZombiesDo: do_something }; } var adam

new Zombie( "Adam" ); adam.doSomethingZombiesDo();

start linting your code

Inversion of control freakness AM I A CONTROL FREAK?

start testing your code

Unit or Functional?

Do both

As long as it can be automated share identify build make it

continuous

Make it part of the process Make it part of the process

Make it part of the process http://rosarioconsulting.net/inspiredtoeducate/?p=706 http://powerbuilder.us / Estimate testing http://malyn.edublogs.org/2011/10/16/process-tools-people/

Make it part of the process Do code review http://rosarioconsulting.net/inspiredtoeducate/?p=706 http://powerbuilder.us / http://malyn.edublogs.org/2011/10/16/process-tools-people/

Make it part of the process http://rosarioconsulting.net/inspiredtoeducate/?p=706 http://powerbuilder.us / Involve people http://malyn.edublogs.org/2011/10/16/process-tools-people/

Fear the living? DON’T

The team

DEVOPS PRODUCT OWNER qa

QA

QA Crucial role in the process

QA Crucial role in the process Quality should be your goal too

QA Crucial role in the process Quality should be your goal too Get help for functional test coverage not to screw up refactoring

Devops

Devops The tough guy

Devops The tough guy It could be hard to deal with

Devops The tough guy It could be hard to deal with Get help setting up the automated process

Product owner

Product owner The less interested in code itself

Product owner The less interested in code itself Bring numbers, not theories

Product owner The less interested in code itself Bring numbers, not theories Get help not wasting time, staying focused on functionalities

Others in the company

juniors external lobbyist

Juniors

Juniors Pair with them, code review their (and your) code

Juniors Pair with them, code review their (and your) code Involve them during the whole process definition

Juniors Pair with them, code review their (and your) code Involve them during the whole process definition Get help keeping things easy and accessible

Learn to say NO!

Learn to say NO! Lobbyists will slow you down, your brain will be more prone to be eaten

Learn to say NO! Lobbyists will slow you down, your brain will be more prone to be eaten Redirect them to the product owner

Basically KILL ‘EM ALL (AGAIN?)

Basically KILL ‘EM ALL (AGAIN?)

KILL ‘EM ALL (AGAIN?) “Nothing is impossible to kill.”

Mira Grant, Feed

but

“Without requirements or design, programming is the art of adding bugs to an empty text file” Louis Srygley Design for your goal

Design for your goal

ā k āś e

 sanskrit for "in the sky"/"to the sky"  https://github.com/cedmax/akase

Modular Architecture

Scalable JavaScript Application  Architecture by Nicholas Zakas

core.register( "module-name" , function (sandbox){

return {

init : function (){

    },
    

destroy : function (){

    }
};

});

core.register( "module-name" , function (sandbox){

return {

init : function (){

    },
    

destroy : function (){

    }
};

});

core.register( "module-name" , function (sandbox){

return {

init : function (){

    },
    

destroy : function (){

    }
};

});

core.register( "module-name" , function (sandbox){

return {

init : function (){

var user

sandbox.getUser(); },

destroy : function (){

    }
};

});

core.register( "module-name" , function (sandbox){

return {

init : function (){

var user

sandbox.getUser(); },

destroy : function (){

    }
};

});

core.register( 'module-name' , function (sandbox){

return {

init : function (config){ console.log(config.id); } }; }); core.configure( 'module-name' , { id: 'container' , }); core.start( 'module-name' ); core.stop( 'module-name' );

core.register( 'module-name' , function (sandbox){

return {

init : function (config){ console.log(config.id); } }; }); core.configure( 'module-name' , { id: 'container' , }); core.start( 'module-name' ); core.stop( 'module-name' );

core.register( 'module-name' , function (sandbox){

return {

init : function (config){ console.log(config.id); } }; }); core.configure( 'module-name' , { id: 'container' , }); core.start( 'module-name' ); core.stop( 'module-name' );

core.register( 'module-name' , function (sandbox){

return {

init : function (config){ console.log(config.id); } }; }); core.configure( 'module-name' , { id: 'container' , }); core.start( 'module-name' ); core.stop( 'module-name' );

core.register( 'module-name' , function (sandbox){

return {

init : function (config){ console.log(config.id); } }; }); core.configure( 'module-name' , { id: 'container' , }); core.start( 'module-name' ); core.stop( 'module-name' );

core.register( 'module-name' , function (sandbox){

return {

init : function (config){ console.log(config.id); } }; }); core.configure( 'module-name' , { id: 'container' , }); core.start( 'module-name' ); core.stop( 'module-name' );

Event Driven Pattern

core.register( "module-name" , function (sandbox){

return {

init : function (){ sandbox.layer( "an error occured" ); } }; });

core.register( "module-name" , function (sandbox){

return {

init : function (){ sandbox.layer( "an error occured" ); } }; });

sandbox.layer( "an error occured" );

sandbox.publish( "error" , { msg: "an error occured" });

sandbox.publish( "error" , { msg: "an error occured" }); core.register( "errManager" , function(sandbox){

return {

init : function(){ sandbox.subscribe( "error" , function(err) {

console .log (err.msg) }); } }; });

sandbox.publish( "error" , { msg: "an error occured" }); core.register( "errManager" , function(sandbox){

return {

init : function(){ sandbox.subscribe( "error" , function(err) {

console .log (err.msg) }); } }; });

sandbox.publish( "error" , { msg: "an error occured" }); core.register( "errManager" , function(sandbox){

return {

init : function(){ sandbox.subscribe( "error" , function(err) {

console .log (err.msg) }); } }; });

sandbox.publish( "error" , { msg: "an error occured" }); core.register( "errManager" , function(sandbox){

return {

init : function(){ sandbox.subscribe( "error" , function(err) {

console .log (err.msg) }); } }; });

sandbox.publish( "error" , { msg: "an error occured" }); core.register( "errManager" , function(sandbox){

return {

init : function(){ sandbox.subscribe( "error" , function(err) {

console .log (err.msg) }); } }; });

sandbox.publish( "error" , { msg: "an error occured" }); core.register( "errManager" , function(sandbox){

return {

init : function(){ sandbox.subscribe( "error" , function(err) {

console .log (err.msg) }); } }; });

sandbox.publish( "error" , { msg: "an error occured" }); core.register( "errManager" , function(sandbox){

return {

init : function(){ sandbox.subscribe( "error" , function(err) {

console .log (err.msg) }); } }; });

sandbox.publish( "error" , { msg: "an error occured" }); core.register( "errManager" , function(sandbox){

return {

init : function(){ sandbox.subscribe( "error" , function(err) {

console .log (err.msg) }); } }; });

sandbox.subscribe( "error" , function (payload){ console.log(payload.msg); }); Advantages

sandbox.subscribe( "error" , function (payload){ console.log(payload.msg); }); Advantages SEMANTIC

sandbox.subscribe( "error" , function (payload){ console.log(payload.msg); }); Advantages SEMANTIC flexibility

Advantages DECOUPLING

“The key is to acknowledge from the start that you have no idea how this will grow. When you accept that you don’t know everything, you begin to design the system defensively.” Nicholas Zakas Overengineering?

AMD

//API: define(id?, dependencies?, factory) ; define( "My-Module" , [ "Another-Module" ], function (AnotherModule){

// Do Something }); one define to rule them all

//API: define(id?, dependencies?, factory) ; define( "My-Module" , [ "Another-Module" ], function (AnotherModule){

// Do Something }); one define to rule them all

//app/config.js define([], function () {

return { url: "http://whatever.it/is/" , debug: true }; });

//app/config.js define([], function () {

return { url: "http://whatever.it/is/" , debug: true }; });

//app/config.js define([], function () {

return { url: "http://whatever.it/is/" , debug: true }; });

//app/myProduct.js define([ "app/config" ], function (config) {

return

function (id){

return {

getProductUrl : function (){

var prodPath

config.url +

"product/"

id;

if (config.debug){ console.log(prodPath) }

return prodPath; } }; }; });

//app/myProduct.js define([ "app/config" ], function (config) {

return

function (id){

return {

getProductUrl : function (){

var prodPath

config.url +

"product/"

id;

if (config.debug){ console.log(prodPath) }

return prodPath; } }; }; });

//app/myProduct.js define([ "app/config" ], function (config) {

return

function (id){

return {

getProductUrl : function (){

var prodPath

config.url +

"product/"

id;

if (config.debug){ console.log(prodPath) }

return prodPath; } }; }; });

//app/myProduct.js define([ "app/config" ], function (config) {

return

function (id){

return {

getProductUrl : function (){

var prodPath

config.url +

"product/"

id;

if (config.debug){ console.log(prodPath) }

return prodPath; } }; }; });

//app/myProduct.js define([ "app/config" ], function (config) {

return

function (id){

return {

getProductUrl : function (){

var prodPath

config.url +

"product/"

id;

if (config.debug){ console.log(prodPath) }

return prodPath; } }; }; });

//app/myProduct.js define([ "app/config" ], function (config) {

return

function (id){

return {

getProductUrl : function (){

var prodPath

config.url +

"product/"

id;

if (config.debug){ console.log(prodPath) }

return prodPath; } }; }; });

//app/myProduct.js define([ "app/config" ], function (config) {

return

function (id){

return {

getProductUrl : function (){

var prodPath

config.url +

"product/"

id;

if (config.debug){ console.log(prodPath) }

return prodPath; } }; }; });

//app/myProduct.js define([ "app/config" ], function (config) {

return

function (id){

return {

getProductUrl : function (){

var prodPath

config.url +

"product/"

id;

if (config.debug){ console.log(prodPath) }

return prodPath; } }; }; });

//app/myProduct.js define([ "app/config" ], function (config) {

return

function (id){

return {

getProductUrl : function (){

var prodPath

config.url +

"product/"

id;

if (config.debug){ console.log(prodPath) }

return prodPath; } }; }; });

<script data-main= "app/main" src= "require.js" ></script>

<script data-main= "app/main" src= "require.js" ></script>

//app/main.js require([ "jQuery" , "app/myProduct" ], function ( $ , Product) {

$ ( ".product" ).on( "click" , function (){

var prodID

$ (this).data( "id" );

var prod

new Product(prodID); document.location.href

prod.getProductUrl(); }) });

<script data-main= "app/main" src= "require.js" ></script>

//app/main.js require([ "jQuery" , "app/myProduct" ], function ( $ , Product) {

$ ( ".product" ).on( "click" , function (){

var prodID

$ (this).data( "id" );

var prod

new Product(prodID); document.location.href

prod.getProductUrl(); }) });

<script data-main= "app/main" src= "require.js" ></script>

//app/main.js require([ "jQuery" , "app/myProduct" ], function ( $ , Product) {

$ ( ".product" ).on( "click" , function (){

var prodID

$ (this).data( "id" );

var prod

new Product(prodID); document.location.href

prod.getProductUrl(); }) });

<script data-main= "app/main" src= "require.js" ></script>

//app/main.js require([ "jQuery" , "app/myProduct" ], function ( $ , Product) {

$ ( ".product" ).on( "click" , function (){

var prodID

$ (this).data( "id" );

var prod

new Product(prodID); document.location.href

prod.getProductUrl(); }) });

<script data-main= "app/main" src= "require.js" ></script>

//app/main.js require([ "jQuery" , "app/myProduct" ], function ( $ , Product) {

$ ( ".product" ).on( "click" , function (){

var prodID

$ (this).data( "id" );

var prod

new Product(prodID); document.location.href

prod.getProductUrl(); }) });

Pulling all together

define( function (){

'use strict' ;

return

function (sandbox){

//the logic of the module

function

doSomething (){

//do something }

return {

init : function (config){

//the initialization code sandbox.subscribe( 'myEventName' , doSomething) },

destroy : function (){

//optional destroy method } }; }; });

define( function (){

'use strict' ;

return

function (sandbox){

//the logic of the module

function

doSomething (){

//do something }

return {

init : function (config){

//the initialization code sandbox.subscribe( 'myEventName' , doSomething) },

destroy : function (){

//optional destroy method } }; }; });

define( function (){

'use strict' ;

return

function (sandbox){

//the logic of the module

function

doSomething (){

//do something }

return {

init : function (config){

//the initialization code sandbox.subscribe( 'myEventName' , doSomething) },

destroy : function (){

//optional destroy method } }; }; });

define( function (){

'use strict' ;

return

function (sandbox){

//the logic of the module

function

doSomething (){

//do something }

return {

init : function (config){

//the initialization code sandbox.subscribe( 'myEventName' , doSomething) },

destroy : function (){

//optional destroy method } }; }; });

define( function (){

'use strict' ;

return

function (sandbox){

//the logic of the module

function

doSomething (){

//do something }

return {

init : function (config){

//the initialization code sandbox.subscribe( 'myEventName' , doSomething) },

destroy : function (){

//optional destroy method } }; }; });

require([ "akase" ], function (core) { core.start( "module1" ); core.start( "module2" , { config: { debug: true } }); core.start( "module3" , { event: "audio:stop" }); });

require([ "akase" ], function (core) { core.start( "module1" ); core.start( "module2" , { config: { debug: true } }); core.start( "module3" , { event: "audio:stop" }); });

require([ "akase" ], function (core) { core.start( "module1" ); core.start( "module2" , { config: { debug: true } }); core.start( "module3" , { event: "audio:stop" }); });

require([ "akase" ], function (core) { core.start( "module1" ); core.start( "module2" , { config: { debug: true } }); core.start( "module3" , { event: "audio:stop" }); });

require([ "akase" ], function (core) { core.start( "module1" ); core.start( "module2" , { config: { debug: true } }); core.start( "module3" , { event: "audio:stop" }); });

ā k āś e

 sanskrit for "in the sky"/"to the sky"  https://github.com/cedmax/akase

2 years later…

require = { baseUrl: '/assets/js/module' , shim: { 'magnificpopup' : { deps: [ 'jquery' ] }, 'timezone' : { exports: 'jstz' }, 'facebook' : { exports: 'FB' } }, paths: { 'templates' : '../../templates' , 'widget' : '../widget' , 'core' : '../core' , 'packages' : '../packages' , 'jquery' : 'js/vendor/jquery-2.0.0.min.js' , 'magnificpopup' : 'js/vendor/mpopup-0.9.2.min.js' , 'modernizr' : 'js/vendor/modernizr.min.js' , 'fastclick' : 'js/vendor/fastclick-1.0.2.min.js' , 'timezone' : 'js/vendor/timezone-1.0.4.min.js' , 'typeahead' : 'js/vendor/typeahead-0.9.3.min.js' }, waitSeconds:30 };

var $ = require( "jquery" ); // Do Something var myscript = require( "myscript" ); var anotherDep = require( "anotherDep" ); // Do Something else COMMON JS require([ "jquery" , "myscript" , "anotherDep" , ], function ($, myscript, anotherDep ){

// Do Something }); REQUIRE JS

import $ from

'jquery' ; import myscript from

'myscript' ; import anotherDep from

'anotherDep' ; // Do Something ES6

No such thing!

Basically Happy Endings?

Basically Happy Endings?

“If you want a happy ending, that depends, of course, on where you stop your story.” Orson Wells Happy ending

You can run, you can hide

You are going to 

SHITTY code  anyway write

You are going to  write Zombie code  anyway

Embrace it! http://drezner.foreignpolicy.com/posts/2009/08/18/theory_of_international_politics_and_zombies

Don’t improvise

Learn how to deal with it

Until you master it

in any case just  remember to

Aim for the head http://halloween.squidoo.com/get-spooked/aim-for-the-head

marco@fromthefront.it http://cedmax.com @cedmax any question?