Structuring an large scale angular application has always been a challenge. Extending and maintaining the application becomes a nightmare when the application grows rapidly over time and you have a large team who’s working on multiple features simultaneously destined to be delivered for the sprint.
Though the angular style guide helps you bootstrap a small application unless you have some experience how large projects are organized by going through some samples you’ll not be able to fathom how to organize your angular application.
The objective of this article is to help developers avoid pitfalls and problems when organizing a large angular project.
This is a highly opinionated view of how i would go about structuring or architecting an angular application and this is by no means a silver bullet solution for all angular applications out there. The structure of an angular application will largely depend on a wide range of factors. Therefore the following approach may be not the ideal way for structuring an angular application specific to your context.
Apparently there are four main types of module in any angular application and they are the AppModule, Core Module, Feature Modules and Shared Module.
Every angular application has one root module which is conventionally known as the AppModule. You launch your application by bootstrapping the AppModule. While a small application might contains one AppModule, most commercial application have one root module i.e. one AppModule and a number of feature modules.
In Angular every module which is not in the AppModule is technically a feature module. As a first step you should have a folder for each feature module at the root folder itself.
When creating feature folders, the following are mentioned in angular style guide which we should take notice of.
- The folder structure should facilitate developers to locate code easily
- It should help Identify code at a glance
- Feature folders should have a flat structure
- Try to be DRY ( Don’t Repeat Yourself)
There are two main ways in which angular code could be organized. The first is the convention based file organization. This is where all the service classes or model classes of the application are in one place in the folder whereas the components that use them are all over the application. So in other words code of a single feature is scattered across the entire application may be under specific folders. E.g. all the data service and model classes are packaged as a module or could be bundled together in a folder under the shared module. This approach has many downsides one of which is that we could have large number of files ending up in a folder. This could lead to performance and maintenance issues. More over it make the developers life hard by make it difficult to locate files when debugging or developing.
The recommended way would be to organize files based on features i.e. put all the files related to a feature in a single folder. This helps developers locate code files easily, such an approach also helps have minimum number of files per folder or for that matter a module. This in turn helps performance of the application by reducing the size of the module when it comes to lazy loading the application.
It’s also a good practice to have one module per feature. Now what constitutes a feature is something that will depending on the type of application you are developing. i.e. how complex or large a feature is. E.g. order list and order details could be in two different module if that suits you best.
As novice front-end developers when organizing folders by features is to gradually end up have a deep nested folder structure. E.g. have a product details feature inside the product list feature and many more. This again leads to the problems that I highlighted earlier. Hence it always best to avoid deep nested folders and have flatten folder structure.
All singleton services go here. These are shared as singleton services which are used throughout the application. E.g. services related to logging error handling and any shared data services. Those services which are not required to be shared across multiple modules can be in specific feature folders. This way the loading time of the initial page of the angular application in minimized to a great extent.
Core module should be imported and included only to the root module or rather the App module. To prevent re-importing the core module elsewhere you should also add a guard for it in the core module declaration.
Some of the other things that could end up in the core module
- shared http services or data services.
- guards — authentication guards, admin guards etc.
- interceptors — from Angular 4+. Helps intercept http requests and responses and modify them as per our requirement
- error handling — global error handling for angular application.
A colossal mistake here is to have data or HTTP services specific to a component or a feature declared in the core module. Such an approach which I’ve seen quite often only bloats the core module and degrades performance over time. I would rather suggest to have shared HTTP or data services in the core module and move all component specific HTTP/data services to their respective feature folders or rather features.
This is where all reusable components reside. This also includes any custom directives and pipes e.g. calendar component, auto complete component etc.
Shared module could be imported multiple times, should it be required so. Shared module should not have any dependency with the rest of the application. Another mistake that i frequently see with developers is that entity models which should ideally belong to a feature are created within the shared module.
Such an approach leads to the same problem that i mentioned earlier where the shared module gets bloated and leads to performance issues.
Following are good references to read up. Infact most of the information that i have presented in my article are mostly based on the assimilation of reading the following
Following are some GitHub source code link which happen to be similar to what I’ve discuss in this blog