How to define a highly scalable folder structure for your Angular project
Finding a suitable folder structure for my Angular applications is something I’ve struggled with for a long time. This became a real issue in my first ever real-world Angular project — especially when the application grew in size. I ended up continuously adding new features with no real structure in place. This made it hard to locate files and making additional changes to the folder structure became time-consuming. But I did get a good understanding about do’s and don’ts when structuring an Angular app.
The goal of this article is to help other developers in a similar situation.
I want to underline that the practices used in this article is very applicable for my single use-case, and should by no means be strictly followed. The folder structure of a project will change based on a broad range of factors. But if you’re interested in a structure which focuses on a multiple-module architecture with a large focus on scaling, continue reading.
Note! The [+] indicates that the folder has additional files.
|-- app |-- modules |-- home |-- [+] components |-- [+] pages |-- home-routing.module.ts |-- home.module.ts |-- core |-- [+] authentication |-- [+] footer |-- [+] guards |-- [+] http |-- [+] interceptors |-- [+] mocks |-- [+] services |-- [+] header |-- core.module.ts |-- ensureModuleLoadedOnceGuard.ts |-- logger.service.ts | |-- shared |-- [+] components |-- [+] directives |-- [+] pipes | |-- [+] configs |-- assets |-- scss |-- [+] partials |-- _base.scss |-- styles.scss
The Angular Style Guide
The logical place to start looking for best practices in Angular is the Angular Style Guide. The guide offers an opinionated view on syntax, conventions and application structure.
The key guidelines that really stood out for me was “Structure the app such that you can locate code quickly” and “Have a near-term view of implementation and a long-term vision. Start small but keep in mind where the app is heading down the road”. This means that you shouldn’t lock yourself to one structure, since it will change a lot depending on the project.
|-- modules |-- home |-- components |-- pages | |-- home | |-- home.component.ts|html|scss|spec | |-- home-routing.module.ts |-- home.module.ts
Tom Crowley has a really interesting article on this topic (found here), where he works his way from a bare bone Angular project to a really solid folder structure. I really liked the idea of modules with designated folders for pages- and components. It’s perfect for scaling and component- and page logic are separated. So if you’re interested in the though-process behind this structure, head over there.
The Core Module
CoreModule takes on the role of the root
AppModule , but is not the module which gets bootstrapped by Angular at run-time. The
CoreModuleshould contain singleton services (which is usually the case), universal components and other features where there’s only once instance per application. To prevent re-importing the core module elsewhere, you should also add a guard for it in the core module’ constructor.
|-- core |-- [+] authentication |-- [+] footer |-- [+] guards |-- [+] http |-- [+] interceptors |-- [+] mocks |-- [+] services |-- [+] header |-- core.module.ts |-- ensureModuleLoadedOnceGuard.ts |-- logger.service.ts
authentication folder simply handles the authentication-cycle of the user (from login to logout).
|-- authentication |-- authentication.service.ts|spec.ts
header folders contains the global component-files, statically used across the entire application. These files will appear on every page in the application.
|-- header |-- header.component.ts|html|scss|spec.ts |-- footer |-- footer.component.ts|html|scss|spec.ts
http folder handles stuff like http calls from our application. I’ve also added a
api.service.ts file to keep all http calls running through our application in one single place. The folder does otherwise contain folders for interacting with the different API-routes.
|-- http |-- user |-- user.service.ts|spec.ts |-- api.service.ts|spec.ts
Angular 4.x introduced a long-awaited feature for handling http requests — the
HttpInterceptor interface. This allows us to catch and modify the requests and responses from our API calls. The
interceptors folder is a collection of interceptors I find specially useful.
|-- interceptors |-- api-prefix.interceptor.ts |-- error-handler.interceptor.ts |-- http.token.interceptor.ts
For more details about HTTP INTERCEPTOR visit this article
guards folder contains all of the guards I use to protect different routes in my applications.
|-- guards |-- auth.guard.ts |-- no-auth-guard.ts |-- admin-guard.ts
For more details about angular guards I suggest you to visit this article
Mocks are specially useful for testing, but you can also use them to retrieve fictional data until the back-end is set up. The
mocks folder contains all the mock-files of our app.
|-- mocks |-- user.mock.ts
All additional singleton services are placed in the
Before start reading about service folder, you should know what a service? so take a 1O minutes to understand all about it and here benefits just by clicking here.
|-- services |-- srv1.service.ts|spec.ts |-- srv2.service.ts|spec.ts
The Shared Module
SharedModule is where any shared components, pipes/filters and services should go. The
SharedModule can be imported in any other module when those items will be re-used. The shared module shouldn’t have any dependency to the rest of the application and should therefore not rely on any other module.
|-- shared |-- [+] components |-- [+] directives |-- [+] pipes
The components folder contains all the “shared” components. This are components like
buttons , which multiple components would benefit from.
|-- components |-- loader |-- loader.component.ts|html|scss|spec.ts |-- buttons |-- favorite-button |-- favorite-button.component.ts|html|scss|spec.ts |-- collapse-button |-- collapse-button.component.ts|html|scss|spec.ts
models folders contains the directives, pipes and models used across the application.
|-- directives |-- auth.directive.ts|spec.ts
|-- pipes |-- capitalize.pipe.ts |-- safe.pipe.ts
|-- models |-- user.model.ts |-- server-response.ts
The config folder contains app settings and other predefined values.
|-- configs |-- app-settings.config.ts |-- dt-norwegian.config.ts
The global styles for the project are placed in a
scss folder under
|-- scss |-- partials |-- _layout.vars.scss |-- _responsive.partial.scss |-- _base.scss |-- styles.scss
scss folder does only contain one folder — partials. Partial-files can be imported by other scss files. In my case,
styles.scss imports all the partials to apply their styling.
The application uses lazy-loading, which means the module isn’t loaded before the user actually accesses the route. By using the structure described in the “Modules”-section, you can easily refer each module in your main app-routing file.
In conclusion, there’s no blueprint when it comes to creating a folder-structure in Angular. The structure will change a lot depending on the project you’re working on. This article covers an explicit use-case using multiple modules, which in turn are divided into pages and a shared set of components.
Useful links :
- Angular CLI: https://github.com/OpenSourceWorkflow/front-end-cheatsheet
- Angular DIRECTIVES: https://angular.io/api/core/Directive
- Angular PIPES: https://angular.io/guide/pipes
- Angular HTTP: https://angular.io/guide/http
- Saas cheatsheet: https://devhints.io/sass
Radhouen is a skilled DevOps Engineer and Linux professional institute DevOps tools engineer Certified, with 2+ years of hands-on experience supporting, automating, and optimizing mission-critical deployments, leveraging configuration management, CI/CD, and DevOps processes.