I recently reviewed some Angular code that uses one module. The AppModule. To manage the entire code base. And, this isn’t tiny code base. The main excuse I’ve heard for this is that the code originated during the beta cycle, prior to NgModule being added to the framework. I call it out as an excuse because once it was added, it was clear that we needed to have more than one module. The fact that this code base doesn’t have more than one module shows a disregard for doing things right over doing things fast. In the best case, it shows ignorance.
But, the larger question this code base raises for me is this: “Why are more modules better than fewer modules?” After all, using one module obviously works. Isn’t the fact that it works sufficient enough?
And here are three really good reasons to use more modules.
Avoid Component Collision
For discussion purposes, let’s say you have an application with two routes. Each route allows you to edit different kinds of content. You may be inclined to create some child components in each route to assist with your functionality. In the process of doing this, you may end up with two components that have the same name. Both as a class and as a selector. If you are including everything in one mega module, you will need to artificially give the components different names. However, if each route has its own module, you can declare the components in the declaration section of each module with the same name and each route will be able to call the appropriate component. Components aren’t shared across modules until you export the component. In that case, you would also want the component to live in a shared module where we would give it a more meaningful, generic, name that made sense as a shared module.
Once you’ve created modules for each of your routes, the next logical step in your development effort will be lazy loading the module. Lazy loading provides more advantages than just the ability to load only what you need when you need it. That’s just the most obvious gain. Lazy loading also provides a separate context for @Injectables. Once again, just like having the ability to isolate the components, by using modules in conjunction with lazy loading, we have the ability to have route specific @Injectables with the same name and each route/module will behave appropriately.
There is one caveat. You can’t provide an @Injectable in a lazy loaded module and an application level module and expect things to work correctly. And, if you are still using a framework like NgRX 2 that needs to have access to services, you’ll need to make your services globally available. This is one of many reasons why I believe you should upgrade to NgRX 4 as soon as is possible. This allows you to take full advantage of the Angular Lazy Loading capabilities and all their benefits.
Even if you’ve never seen a major application with one module, I’m sure you can imagine what a mess that module is. I don’t think I really need to say much more about this.
Other post in Angular 2
- Angular 2 – First Impressions [Compared to Angular 1] - February 25th, 2016
- Angular 2 Thoughts - October 4th, 2016
- Getting Started with Angular 2 - October 25th, 2016
- Unit Testing an Angular 2 CLI Project - November 22nd, 2016
- Adding Client Side Routing to Angular 2 - November 29th, 2016
- Angular 2 Lazy Loading - December 6th, 2016
- Reasons to use RxJS Today - December 13th, 2016
- Dissecting Angular 2 Modules - December 20th, 2016
- Awesome Angular2 Architecture Options and Opinions - December 27th, 2016
- What if Everything Was Immutable? - January 10th, 2017
- Amazing Angular2 DOM Tips, Tricks, and Warnings - January 17th, 2017
- Secrets to Styling Angular2 - January 31st, 2017
- Jedi Angular 2 Tips and Tricks - March 28th, 2017
- Unit Testing Angular(2+) with JSDOM - April 4th, 2017
- More Control with Angular Flex Layout - April 11th, 2017
- Angular(2+) Model Driven Forms Are Superior - April 18th, 2017
- Dynamically Add Components in Angular - April 25th, 2017
- Using Real World NgRX - May 9th, 2017
- Functional Reactive Angular Revealed - May 30th, 2017
- NgRX/Store Coding Sanity Epiphany - June 6th, 2017
- Real World RxJS Marble Testing Revealed - June 13th, 2017
- How to Organize an Angular Application - June 20th, 2017
- Upload an Image as a File in Angular - July 4th, 2017
- How to Implement Angular 2+ Routing - July 18th, 2017
- TypeScript Basics for Angular Developers - August 1st, 2017
- Angular Observable Secrets Revealed - August 8th, 2017
- How to Upgrade NgRX to 4.x - August 15th, 2017
- Model View Presenter, Angular, and Testing - August 29th, 2017
- This One Tweak Improved my Angular Code - September 12th, 2017
- Upgrade to Angular from... - September 26th, 2017
- Using NgRX to Cleanly Aggregate Data - October 3rd, 2017
- NgRX 4 Actions - Class vs Object Literal - October 10th, 2017
- Implementing NgRX 4 - October 24th, 2017
- What I Learned Using Angular Material - October 31st, 2017
- Angular Ionic and Angular CLI - November 14th, 2017
- How to Really Screw Up an Angular Project - December 12th, 2017
- Angular Cross Field Validation - December 19th, 2017
- Attaching an Angular Child Component's Form to a Parent - January 2nd, 2018
- Why more Angular Modules are Better than One - January 16th, 2018
- Property Based Testing in Angular with jsVerify - February 6th, 2018