Working in reasonably big companies for the last years I’ve come across big Angular projects. As you would expect these were modular projects consisting of a bunch of modules. One of the things I never took in consideration was ‘tree shaking’.

Tree Shaking

Tree shaking is a step in a build process that removes unused code so the application becomes smaller. It can be visualised as shaking a physical tree causing dead branches and leaves to fall off. 

One of the primary ways tree shaking looks for code is by import paths. If a class or function is imported, it is used and can not be removed. Now consider services in Angular 5 and how they are provided in the module.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AccountComponent } from './account.component';
import { SharedService } from './shared.service';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule
  ],
  declarations: [AccountComponent],
  bootstrap: [AccountComponent],
  providers: [SharedService]
})
export class AccpountModule { }

As you can see the service is imported and is put into the providers section of the module to register it in the dependency injection system. This way of registering is challenging for tree shaking to determine if the code of the service is used or not.

Tree Shakeable Providers

As of Angular 6 there is another way of registering services with the module which is tree shakable for we do not import the service class. It uses the providedIn property as you can see here:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class SharedService {
  constructor() { }
}

By default, this syntax registers it to the root injector which will make our service an application wide singleton. If you still need to control the number of instance of a service the regular providers API is still available on Angular Modules and Components.