If I was dealing with 40+ diverse services that I needed anywhere within various JavaScript apps, I'd probably write some kind of mediating service broker:
var App = new YouNow();
var Bcast = App.Api('BroadcastService');
Bcast.Api.send(msg).then(cb);
Your code doesn't have to care about where the services come from, it just has to comply with the services' APIs.
Thinking about your code structure as backend-provided services gives you the flexibility to do a Require.JS-style async dependency loading approach if needed. Imagine the following defined in api/services/BroadcastService/index.js:
service.define('BroadcastService',
['MessagingService',
'VideoTranscodingService'],
function(MS, VTS) {
// do stuff with services,
// return a promise
}
);
A style like this allows you to mix and match a bunch of different interesting architectural approaches, with relative ease, and the safety of decoupled software components.
As usual your sticking points with this kind of hierarchical component system will be caching and out-of-band (component-to-component) messaging and state changes. For instance: what happens to the notion of a global 'Session' object?
You should not be worrying about object size. Write libraries in a way that makes sense for your problem, then use Closure compiler to strip the unused code from each application.
Cheers for mentioning the closure compiler; I'll look into it. I haven't noticed much literature on its use in current build systems; I guess r.js gets all the fame due to its easier api.
Require.js doesn't remove unused code like the closure compiler does.
That feature is critical for building general purpose libraries because it allows you to organize on conceptual boundaries without worrying so much about code size.
I've been exploring both Alt. 2 and Alt. 3. 2 with AngularJS and 3 with Backbone+Marionette. Evental communication within Models, which are entities, to views and controllers is easy and fun. A model is essentially a service anyway, so methods are more intuitive to name.
Interesting. Something else that I should have included as a con for 3 is that Backbone would then be a requirement for the model-based solution. It sacrifices flexibility for smaller projects that need services.
Thinking about your code structure as backend-provided services gives you the flexibility to do a Require.JS-style async dependency loading approach if needed. Imagine the following defined in api/services/BroadcastService/index.js:
A style like this allows you to mix and match a bunch of different interesting architectural approaches, with relative ease, and the safety of decoupled software components.As usual your sticking points with this kind of hierarchical component system will be caching and out-of-band (component-to-component) messaging and state changes. For instance: what happens to the notion of a global 'Session' object?