Created
June 12, 2013 08:56
-
-
Save lemonskip/5763826 to your computer and use it in GitHub Desktop.
As we move forward modularising our apps and building components into one file. We may find that a lot of these components will share the same modules (e.g. third party libs ... jQuery, Backbone etc ). This introduces a problem ... how can we manage these cross deps without complicating the developers workflow and build process of a component. T…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define(function(){ | |
/** Almond JS:START */ | |
var requirejs,require,define;(function(e){function c(e,t){return f.call(e,t)}function h(e,t){var n,r,i,s,o,a,f,l,c,h,p=t&&t.split("/"),d=u.map,v=d&&d["*"]||{};if(e&&e.charAt(0)==="."){if(t){p=p.slice(0,p.length-1);e=p.concat(e.split("/"));for(l=0;l<e.length;l+=1){h=e[l];if(h==="."){e.splice(l,1);l-=1}else if(h===".."){if(l===1&&(e[2]===".."||e[0]==="..")){break}else if(l>0){e.splice(l-1,2);l-=2}}}e=e.join("/")}else if(e.indexOf("./")===0){e=e.substring(2)}}if((p||v)&&d){n=e.split("/");for(l=n.length;l>0;l-=1){r=n.slice(0,l).join("/");if(p){for(c=p.length;c>0;c-=1){i=d[p.slice(0,c).join("/")];if(i){i=i[r];if(i){s=i;o=l;break}}}}if(s){break}if(!a&&v&&v[r]){a=v[r];f=l}}if(!s&&a){s=a;o=f}if(s){n.splice(0,o,s);e=n.join("/")}}return e}function p(t,r){return function(){return n.apply(e,l.call(arguments,0).concat([t,r]))}}function d(e){return function(t){return h(t,e)}}function v(e){return function(t){s[e]=t}}function m(n){if(c(o,n)){var r=o[n];delete o[n];a[n]=true;t.apply(e,r)}if(!c(s,n)&&!c(a,n)){throw new Error("No "+n)}return s[n]}function g(e){var t,n=e?e.indexOf("!"):-1;if(n>-1){t=e.substring(0,n);e=e.substring(n+1,e.length)}return[t,e]}function y(e){return function(){return u&&u.config&&u.config[e]||{}}}var t,n,r,i,s={},o={},u={},a={},f=Object.prototype.hasOwnProperty,l=[].slice;r=function(e,t){var n,r=g(e),i=r[0];e=r[1];if(i){i=h(i,t);n=m(i)}if(i){if(n&&n.normalize){e=n.normalize(e,d(t))}else{e=h(e,t)}}else{e=h(e,t);r=g(e);i=r[0];e=r[1];if(i){n=m(i)}}return{f:i?i+"!"+e:e,n:e,pr:i,p:n}};i={require:function(e){return p(e)},exports:function(e){var t=s[e];if(typeof t!=="undefined"){return t}else{return s[e]={}}},module:function(e){return{id:e,uri:"",exports:s[e],config:y(e)}}};t=function(t,n,u,f){var l,h,d,g,y,b=[],w;f=f||t;if(typeof u==="function"){n=!n.length&&u.length?["require","exports","module"]:n;for(y=0;y<n.length;y+=1){g=r(n[y],f);h=g.f;if(h==="require"){b[y]=i.require(t)}else if(h==="exports"){b[y]=i.exports(t);w=true}else if(h==="module"){l=b[y]=i.module(t)}else if(c(s,h)||c(o,h)||c(a,h)){b[y]=m(h)}else if(g.p){g.p.load(g.n,p(f,true),v(h),{});b[y]=s[h]}else{throw new Error(t+" missing "+h)}}d=u.apply(s[t],b);if(t){if(l&&l.exports!==e&&l.exports!==s[t]){s[t]=l.exports}else if(d!==e||!w){s[t]=d}}}else if(t){s[t]=u}};requirejs=require=n=function(s,o,a,f,l){if(typeof s==="string"){if(i[s]){return i[s](o)}return m(r(s,o).f)}else if(!s.splice){u=s;if(o.splice){s=o;o=a;a=null}else{s=e}}o=o||function(){};if(typeof a==="function"){a=f;f=l}if(f){t(e,s,o,a)}else{setTimeout(function(){t(e,s,o,a)},4)}return n};n.config=function(e){u=e;if(u.deps){n(u.deps,u.callback)}return n};define=function(e,t,n){if(!t.splice){n=t;t=[]}if(!c(s,e)&&!c(o,e)){o[e]=[e,t,n]}};define.amd={jQuery:true}})(); | |
/** Almond JS:END */ | |
/** Compiled Modules of the Component:START */ | |
define('app/internal_mod', ['jquery'], function($){ | |
function TestMod( foo ){ | |
this.foo = foo; | |
} | |
TestMod.prototype.displaySomething = function (str) { | |
document.querySelector('body').innerHTML = str | |
}; | |
return TestMod; | |
}); | |
define('app/main', function(){ | |
function MainPlugin() {} | |
return MainPlugin; | |
}); | |
/** Compiled Modules of the Component:END */ | |
/** | |
* Boilerplate code that all components must expose | |
*/ | |
return { | |
getRequire: function() { return require; }, | |
setRequire: function( decorated_require ){ require = decorated_require; }, | |
main: 'app/main' // needed because we may have multiple instances of the same plugin | |
}; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define([ | |
'underscore', | |
'when' | |
], function( _, when ){ | |
function noop() {} | |
//@TODO: needs further though/work to handle amd plugin notation ! | |
function shouldHandle( dep, reservedNamespace ) { | |
var path_parts = dep.split('/'); | |
if( reservedNamespace.indexOf( path_parts[0] ) === -1 ) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
/** | |
* componentRequire - almondjs require from within the plugin | |
* reservedNamespace - array of strings (path prefixes that should not be passed through the global require) | |
*/ | |
function decorateRequire( componentRequire, reservedNamespace ){ | |
return function( deps ){ | |
if( typeof deps === 'string' ) { | |
/** synchronous require */ | |
if( shouldHandle(deps, reservedNamespace) ) { | |
/** | |
* try catch because the error (if any) | |
* needs to be flagged by the componentRequire (makes debugging easier) | |
*/ | |
try{ | |
return require(deps); | |
} catch( e ) {} | |
} | |
return componentRequire.apply(false, arguments ); | |
} else { | |
/** | |
* async require - need to require each dep independantly so we can handle | |
* list of mixed deps - some from the global require and some from | |
* the pluginRequire modules loaded from console | |
*/ | |
var success = arguments[1] || noop; | |
var failure = arguments[1] || noop; | |
var defers = []; | |
_.each(deps, function( dep ){ | |
var defer = when.defer(); | |
if( shouldHandle(dep, reservedNamespace) ) { | |
require([dep], function( module ){ | |
defer.resolve( module ); | |
}, function( error ) { | |
/** | |
* hmmm not our problem! we tried let the foreingRequire do it | |
* We will not catch the error here because its not our concern | |
*/ | |
componentRequire([dep], function( module ){ | |
defer.resolve( module ); | |
}); | |
}); | |
} else { | |
componentRequire([dep], function( module ){ | |
defer.resolve( module ); | |
}); | |
} | |
defers.push( defer.promise ); | |
}); | |
when.all( defers ).then(function( modules ){ | |
/** hey all resolved :) */ | |
success.apply( false, modules ); | |
}, function(){ | |
/** hey something did not resolve */ | |
failure.apply( false, modules ); | |
}); | |
} | |
} | |
} | |
return decorateRequire; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment