Angular project structure

Angular folder structure best practice:

Follow LIFT principle: Do structure the app such that you can Locate code quickly, Identify the code at a glance, keep the Flattest structure you can, and Try to be DRY.

Folders and files inside of the "app" folder:

|- core
   |- components
      |- navbar
         |- navbar.component.html|scss|ts
      |- page-not-found
         |- page-not-found.component.html|scss|ts
   |- constants
   |- enums
   |- utils
   |- guards
      |- auth.guard.ts
   |- pipes
   |- interceptors
      |- error.interceptor.ts
      |- token.interceptor.ts
   |- services
   |- core.module.ts
|- feature-a (for example: users, posts, etc)
   |- components
      |- scoped-component-a
         |- scoped-component-a.component.html|scss|ts
      |- scope-component-b
         |- scoped-component-b.component.html|scss|ts
   |- models
      |- scoped-model-a.model.ts
      |- scoped-model-b.model.ts
   |- services
      |- scoped-service-a.service.ts
      |- scoped-service-b.service.ts
   |- feature-a-routing.module.ts
   |- feature-a.module.ts
   |- feature-a.component.html|scss|ts
|- shared
   |- components
   |- models
   |- services
   |- pipes
   |- shared.module.ts

CoreModule

All services which have to have one and only one instance per application (singleton services) should be implemented here. Typical example can be authentication service or user service.
A Core Module is an NgModule containing code that will be used to instantiate your app and load some core functionality.
In the Core Module we commonly place our singleton services and modules that will be used across the app but only need to be imported once. Examples are an Authentication Service or LocalStorage Service, but also modules like HttpClientModule , StoreModule.forRoot(…), TranslateModule.forRoot(…) . The CoreModule is then imported into the AppModule .

In short, when using a Core Module:

  • DO import modules that should be instantiated once in your app.
  • DO place services in the module, but do not provide them.
  • DO NOT declare components, pipes, directives.
  • DO NOT import the CoreModule into any modules other than the AppModule.

SharedModule - https://angular.io/guide/sharing-ngmodules

All the “dumb” components and pipes should be implemented here. These components don’t import and inject services from core or other features in their constructors. They should receive all data though attributes in the template of the component using them. This all sums up to the fact that SharedModule doesn’t have any dependency to the rest of our application. It is also the perfect place to import and re-export Angular Material components.

The SharedModule contains classes and resources which are used in more than one dynamically loaded module. By always loading with the application the shared components are ready whenever a module requests them.

The shared module is a good place to import and export the FormsModule and the ReactiveFormsModule. It is also good for the FontAwesomeModule and any other resource used by some modules some of the time.

In short, when using a Shared Module:

  • DO declare components, pipes, directives, and export them.
  • DO import FormsModule, ReactiveFormsModule and other (3rd-party) modules you need.
  • DO import the SharedModule into any other Feature Modules.
  • DO NOT provide app-wide singleton services in your SharedModule. Instead move these to the CoreModule.
  • DO NOT import the SharedModule into the AppModule.

FeatureModule

We are going to create multiple feature modules for every independent feature of our application. Feature modules should only import services from CoreModule. If feature module A needs to import service from feature module B consider moving that service into core.

Rule of thumb is to try to create features which don’t depend on any other features just on services provided by CoreModule and components provided by SharedModule.

This will keep our code clean, easy to maintain and extend with new features. It also reduces effort needed for refactoring. If followed properly, we will be confident that changes to one feature can’t affect or break the rest of our application.

LazyLoading

We should lazy load our feature modules whenever possible. Theoretically only one feature module should be loaded synchronously during the app startup to show initial content. Every other feature module should be loaded lazily after user triggered navigation.

Folders and files inside of the "assets" folder:

|- images
|- icons
|- styles
   |- styles.scss

These instructions are to install this directory structure to a brand new ng version 10 or above created application. Before you can execute these instructions you must remove the comments from the tsconfig.json file and other json files because comments in a json file are not valid json:

ng generate module Core
ng generate module Shared
ng generate module Data
mkdir src/app/layout
ng generate component layout/main
ng generate component layout/header
ng generate component layout/nav
ng generate component layout/footer
mkdir assets/styles && mkdir assets/images

Leave a Reply

Your email address will not be published. Required fields are marked *