Shared Module vs Module Per Component
Recently I saw Julien Renaux posted on Twitter that whenever they work on an Angular application, there were a few things they always did in their approach to how they built the application. One of these things they did was write one module per component, this drew a response from another developer asking why they didn’t use a SharedModule instead.
So this got me thinking why would you use a module per component instead of a shared module?
Before we look at the benefits of the module per component approach, it’s worth looking at the other approaches we can take in our Angular application.
First, there is the Featured module approach, this is where we are developing a feature of our application, say user management. So we create a UserManagement module that has all the functionality associated with user management, all the components and services for that feature. This is a pretty standard approach, which we start with when getting started with Angular.
Another approach is creating a SharedModule. In this shared module we may have components or services that are going to, well, shared in several features. For example, we may have an authentication service, which checks if a user is authenticated or not. We may need this functionality throughout an application, so placing this service in a SharedModule that is included into all the sections we need makes sense.
The problem with the share module approach is that over time and in a large application this module could grow out of control. Especially if you have multiple developers working on an application, and they don’t know where to add a new service or component they are creating, which is clearly not part of a feature module. The temptation is to add it to this global shared module, which over time gets bigger and bigger. I’ve seen this happen with .Net projects. They have a shared library that became a dumping ground for services where the developer wasn’t too sure where the best place to add their new service was.
There is also another approach, the module per component approach. This is where for each component, we create a module for each component in our application. At first that sounds like a big overhead having to create this module every time we create a new component, but it does have two great benefits. One, it helps with tree-shaking. If our application is not using the component, then it’s not loaded. This reduces the load the browser needs to make, increasing the speed our application loads.
The second advantage this brings is when importing a module, we know exactly what is in that component specific module. Unlike the shared module approach where they are other components and services which are part of this shared module. The single component module approach means we know that the single component is part of the module we’re importing. It keeps our imports clean.
This approach has been used to great effect by the Angular Material team, who changed from the feature module approach to the component per module approach. Now when using Angular Material we only import the module for the components we are using. Keeping the size of the Angular Material library we add to our applications down to a minimum.
So what is the best approach? Well, with all things it depends on your circumstance and the type of application you are building. For large enterprise application, where you are building a set of Angular applications across an organisation. There maybe a need for a limited shared module that has some functionality that is needed for each application. If you have a design system for your applications that give each app the same UI then the module per component approach is extremely useful. Just as it is in Angular Material.
As Angular continues to grow and being used in more and more large enterprise applications, the best practices for how to manage and make best use modules will continue to mature. So it is still something that needs to be researched into and as Angular developers we need to document the pros and cons of these different approaches so other developers can learn from what we’ve found when they come to deciding what their approach to modules is going to be.