Modularity and AngularJS

Summary

In this article I’ll describe what modularity is, why it is important in your applications, how to build modular AngularJS applications, and one way to visualise your module’s structure and dependencies.

Modularity

Modularity is the separation of a system’s functionality into a set of logically independent pieces — referred as modules or components. A modular system is easier to understand, to reason about, to maintain, to reuse and to extend. If you’re building a large web application, then you should be aiming to these, as they pose numerous challenges due to their complexity and scale.

What represents a module is deeply tight to the system’s domain and thus difficult to generally define. However, one can describe common design principles a module should follow, which relate to cohesion and coupling.

Cohesion

Cohesion measures what the modules does. Instead of addressing many different concerns, a highly cohesive module focus on a single purpose or responsibility. This is also known as Single Responsibility Principle, one of the SOLID Principles.

Coupling

Coupling measures how dependent different modules are on each other. A module should be as low coupled as possible, meaning that it should have few or no dependencies on other modules.

Modular vs. Monolithic

A modular application is an application composed by highly cohesive and low coupled modules. You can create as many modules as you want, but if they don’t have these characteristics your application is rather a monolithic system (or as Joseph Yoder brilliantly named it, a Big Ball of Mud). These systems are known to be a maintenance nightmare.

Modular applications make it easy to plug and go as they allow the development teams to build vertical slices of the applications and roll out incrementally. This means we can plug in new features as we develop them. — John Papa in AngularJS Styleguide [Style Y160]

Modularity and AngularJS.

Creating Modules

The way to create a new module in AngularJS is as follows:

angular.module(‘moduleName’, [‘oneModule’, ‘otherModule’]);

Breaking your app into smaller modules is not a new concept. In fact, many people wrote about it. However, as mentioned, those modules should be highly cohesive and low coupled. One way to do this, as described in John Papa’s famous AngularJS Styleguide, is to separate your modules into 3 categories:

Reusable Blocks: reusable inter-application blocks for common services (e.g.: exception handling, logging, diagnostics, security). [Style Y164]

reusable inter-application blocks for common services (e.g.: exception handling, logging, diagnostics, security). [Style Y164] Feature Modules: feature areas (e.g.: layout, reusable and shared services, dashboards) and app specific features (e.g.: customers, admin, sales). [Style Y163]

feature areas (e.g.: layout, reusable and shared services, dashboards) and app specific features (e.g.: customers, admin, sales). [Style Y163] App Module: thin module only used for pulling together the application. It becomes a manifest that describes which modules help define the application. [Style Y161]

John Papa maintains an example application which follows this guidelines here. Don’t just blindly follow John’s advices, though. Think wether or not they make sense to your application. Don’t be afraid to add more categories if you feel the need for it. Remember: create modules that do one thing and one thing well (cohesive) and that depend on few or no other modules (low coupled).

John Papa’s AngularJS Styleguide advices you to divide your app into three categories.

Visualising Modularity

If you’re developing a modular application, it is a good idea to keep an up-to-date overview of your app “pieces” and their inter-relationships. One way to do it automatically is using grunt-angular-modules-graph (disclaimer: I’m now maintaining this project).

It generates two types of diagrams for you:

a diagram containing all modules and their relationships

Diagram containing all the modules of the application

a diagram, for each of your modules, containing the modules controllers, services, factories, etc.

Diagram for the app.avengers module

Conclusion

I hope this article you find this article useful. I’m also looking forward to receive more feature requests and contributions to grunt-angular-architecture-graph.

[Shameless plug here] I just co-founded Aditus — the accessibility tool for your team. Chances are, if you enjoy tools in the web development space, you’ll find it interesting.