We've not got a plugin architecture as such, but I'll explain how we are keeping our client code loosely coupled, and maybe it will give you some ideas.
We are using asp.net. We deliver a main.aspx page which first includes a mediator javascript file. It defines a global object - call it mediator - which is the only global object that we define.
The mediator exposes a simple interface with publish and subscribe messages:
mediator.subscribe(messageName, callback);
mediator.publish(messageName);
After the mediator.js file, the main page includes a number of other javaScript files, each of which consists of an immediate function which registers it's functionality with the mediator.
More about this pattern can be found here, or see a previous question of mine here.
You could follow a similar approach - define a single global object (say pluginFramework) which offers an interface for plugins to register their functionality. When you build the html page to deliver to the client, first include the pluginFramework file and then dynamically include the desired JavaScript plugin files, which could depend on the user or the device (e.g. different plugins if the device is touch enabled?). These plugin files would add their functionality to the pluginFramework with an immediate function.
Here is an example of how to allow plugins to add functionality to a menu in the UI:
pluginFramework.js:
var pluginFramework = (function() {
var menuItems = [];
function addMenuItemPrivate(itemName, callback) {
// e.g. add itemName and callback to menuItems
}
return {
addMenuItem: addMenuItemPrivate;
}
})());
photoPlugin.js:
(function() {
function addPhoto() {
//...
}
pluginFramework.addMenuItem('add photo', addPhoto)
})());
Hope this was in some way helpful!