I would go with the following approach using CommonJS modules. These sub applications or modules cant be started or stopped, but they provide a nice separation.
app.js
var Marionette = require('backbone.marionette');
var _ = require('underscore');
module.exports = Marionette.Application.extend({
initialize: function() {
this._modules = [];
},
addModule: function(name, klass ,options) {
var module = new klass(options);
this._modules[name] = module;
}
});
layout.js
var Marionette = require('backbone.marionette');
module.exports = Marionette.LayoutView.extend({
el: '#app',
regions: {
header: '[data-region="header"]',
main: '[data-region="main"]'
}
});
groups/index.js
var Marionette = require('backbone.marionette');
var Router = require('./router');
var Group = require('./model/group');
var GroupCollection = require('./model/group_collection');
var GroupListView = require('./list/collection_view');
var GroupDetailView = require('./detail/group_view');
module.exports = Marionette.Object.extend({
initialize: function(options) {
this.container = options.container;
this.router = new Router({
controller: this
});
this.groups = new GroupCollection();
},
groupList: function() {
var groupListView = new GroupListView({
collection: this.groups
});
this.groups.fetch();
this.container.show(groupListView);
},
groupDetail: function(id) {
var groupDetailView = new GroupDetailView({
model: this.groups.findWhere({id: id})
});
this.container.show(groupDetailView);
}
});
groups/router.js
var Marionette = require('backbone.marionette');
module.exports = Marionette.AppRouter.extend({
appRoutes: {
'groups': 'groupList',
'groups/:id': 'groupDetail'
}
});
main.js
var Backbone = require('backbone');
var Application = require('./app');
var MainLayout = require('./layout');
var HeaderApp = require('./header');
var GroupsApp = require('./groups');
var app = new Application();
var layout = new MainLayout();
app.addModule('header', HeaderApp, {
container: layout.getRegion('header')
});
app.addModule('groups', GroupsApp, {
container: layout.getRegion('main')
});
app.start();
Backbone.history.start({
pushState: true
});
I omitted the models, collections and views from this example, but i hope you get the gist.
Your app is an extended Marionette application where you can register modules on.
Each module lives in it's own folder with an index.js file that serves as the entry point for the module. In this file you build a Marionette object that serves as the controller for your module.
Each module has it's own router with the Marionette object in the index.js file as it's controller.
Add models, collections, views and templates as you please. For communication between modules you could use Backbone.Radio.
Finally you bootstrap your app, main layout and modules in main.js, and build it with browserify or webpack.
Disclaimer
I didn't invent this architecture myself, but at the moment I don't remember the original source.