Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to modularize AngularJS applications / plugins

I have a couple of (software-)architecture questions regarding a migration from Grails (REST-API, parts of AngularJS, MongoDB, Tomcat, Spock, several plugins) to Node.js + Angular.js. I probably have to explain the structure of the Grails project fist, so here we go:

There is a main Grails application (beside a couple of other applications), which is built on several plugins. Each of these plugins is able to get executed by itself - that means it has its own UI, individual templates, services, controllers, routes, tests etc. It is also hosted on different repositories. This is done by the Grails plugin mechanisms. The benefits are less testing-efforts, less compiling time, modularization, single responsibilities and so on.

But still, the time to compile and test are too expensive. Also I don't like the fact that the API delivers parts of the templates/views. I would like to have the backend APIs "just to be backend APIs" and the frontend "just to be the frontend". So each AngularJS application/plugin will provide its own view, routes, service etc. But they might also depend on other plugins.

So what I would like to achieve is as follow:

  • One main AngularJS application, which includes several plugins (a plugin can be something like a report-generator, a guestbook or whatsoever, speaking of a single independent part of an application, either with a specific route, or just a small part of the page).
  • Each plugin must be a stand-alone AngularJS application (probably executable during development via grunt or so). So that the UI developer does not need to start the whole backend application, further that we may run functional tests only with JavaScript
  • Communication only via REST, The frontend must retrieve all it's data from the APIs
  • Each plugin must be testable on its own
  • A Plugin might require other plugins to work
  • The main index.html (and app.js?) might be provided by a Nginx server, which is decoupled from the rest of the backend (API)

Though I have a specific picture in my head, I am struggling in how to setup this architecture.

In Grails the plugin mechanisms are somehow merging the plugin dependant settings (like URL mappings, dependencies, etc) to the main application in which they get included/injected - this is what I want to achieve with AngularJS as well. So:

  • Are there some kind of same mechanisms for AngularJS?
  • How may I provide/merge the routes of each plugin into the main application?
  • How can I declare application- and plugin-dependencies?
  • What tools might be usefull for the build process?
  • How to establish lazy-retrievments of the plugin-resources (css/less files, views, services etc)?
  • Prevent the application to provide all resources of the plugins on startup (I guess the routes are required on startup though)

Since this is not just a how-to-do-this-or-that question I excuse myself if I am missing important parts or if some parts are not clear enough. Just ask me and I will answer each question in depths.

like image 559
Christopher Will Avatar asked Jan 24 '14 17:01

Christopher Will


1 Answers

** This answer is incomplete **

I want to make sure I understand you before I dig into this.

Here's a quick implementation of a Loader module to manage lazy loading (plugins, vendor assets, admin stuff etc).

Does this help?

angular.module('Bizcoin.loader')
.service('Loader', Loader);

function Loader($injector, $ocLazyLoad, User) {
  var Loader = {
    load: load,
    get: get,
    plugins: {},
    flags: {}
  };

  init();

  return Loader;

  function init() {
    load('vendors');
    if (userIsAdmin)
      load('admin');
  }

  function load(plugin) {
    Loader.plugins[plugin] = Loader[plugin] || $ocLazyLoad.load('path/to/'+plugin+'.js');
    return Loader.plugins[plugin].then(setFlag);

    function setFlag() {
      return Loader.flags[plugin] = true;
    }
  }

  function get(plugin) {
    return load(plugin).then(function() {
      return $injector.get(plugin);
    });
  }

}
like image 162
goldylucks Avatar answered Oct 02 '22 10:10

goldylucks