Run on-demand apps in angular projects in local development
Tags: angular, angularrouting, runondemandapps
Published: 2022-02-26 10:25:30

 
I was working on a large-scale project that was developed in the Angular framework.  There are multiple library projects created (almost 100+) for every module.  These libraries are imported as lazy-loaded modules in route.module.ts.
 
Below is a sample route module.

```
const routes: Routes = [
  { path: 'login', component: LoginComponent },
  { path: 'home', component: HomeComponent },
  { path: 'applications/app1', loadChildren: () => 
   	import('./applications/app1/app.module').then(m => m.AppModule)
  },
  { path: 'applications/app2', loadChildren: () => 
   	import('./applications/app2/app.module').then(m => m.AppModule)
  },
  { path: 'applications/app3', loadChildren: () => 
   	import('./applications/app3/app.module').then(m => m.AppModule)
  },
  
  ….
  ….
  
  { path: 'applications/app50', loadChildren: () => 
   	import('./applications/app1/app.module').then(m => m.AppModule)
  }
];
```
 
When I run “ng serve’’, it took more time (almost it took 20-30 mins) to serve the application.
 
As a developer, I am going to work on a few applications (mostly one or two apps at a time) during my development. Here serving the entire application is a tedious process and even doing the little code changes in the library project would take more time to compile and reflect the changes.
 
To avoid this waiting time to serve, I have created a separate routing module for development and configuration (in angular.json). The dev routing module only contains the required apps/libraries that I am going to work on. By doing this we can reduce the considerable amount of time in serving the angular application
 
Let’s see what the configurations I have created are:
 
## Development version of Routing Module

Create a new routing module (you could name it as your wish) in the same folder where you have route.module.ts. I named it route.dev.module.ts.
 
Copy the required imports and routing paths from the main route module and paste them in the dev.routing.module.
 
This file is the same as the main routing module but it contains only the required (on-demand) routing paths that I am going to work on.
 
## Development version of tsconfig.json
 
Create a development version of tsconfig.json. I named this file tsconfig.dev.json.  This new file would extend the existing tsconfig.json. But here we add include properly that contains the required project folders to be compiled. 

```
{
   "extends": "./tsconfig.json",
   "include": [
      "src/main.ts",
      "src/polyfills.ts",
      "src/app/applications/app1",
      "src/app/applications/app2"
   ]
}
```

**Note**: We need to add main.ts and polyfills.ts files to the include array. If we don’t add it, we will be getting the below error when you do ng serve.

Error: ./src/main.ts
Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error:  ..\..\..\src\main.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.
at 
Error: ./src/polyfills.ts
Module build failed (from ./node_modules/@ngtools/webpack/src/ivy/index.js):
Error: ..\..\..\src\polyfills.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.

## Creating a new configuration in angular.json
 
Now we have to create a new configuration that will make use of the development version of both typescript configuration (tsconfig.dev.json) and routing module (route.dev.module).
 
In angular.json add a new configuration under **architect -> build -> configurations**. I named this configuration **my-dev-apps**. Below is a sample configuration:

```
"my-dev-apps": {
   "tsConfig": "src/tsconfig.dev.json",
   "fileReplacements": [
      {
         "replace": "src/environments/environment.ts",
         "with": "src/environments/environment.dev.ts"
      },
      {
         "replace": "src/app/route.module.ts",
         "with": "src/app/route.dev.module.ts"
      }
   ],
   "optimization": false,
   "sourceMap": true,
   "namedChunks": true,
   "aot": false,
   "extractLicenses": false,
   "vendorChunk": false,
   "buildOptimizer": false,
   "scripts": []
}
```
 
The main things to be noted in this configuration are **tsConfig** and **fileReplacements** properties. 

The value of the **tsConfig** property is the path of **tsconfig.dev.json**. 
In the **fileReplacements** array, I replace route.module.ts with **route.dev.module.ts**.
 
Then we have to add configuration under **architect -> serve**. The new configuration will be used as browseTarget.

```
"dev-my-apps": {
   "browserTarget": "main:build:dev-my-apps"
},
``` 
Finally, we have to use this new configuration while serving the application. I created an npm script to use this configuration. Below is the sample npm script.

```
"my-dev-apps": "ng serve -c my-dev-apps"
```

You can call this script in your terminal as npm run my-dev-apps.
 
After running this script, you can see the ng serve is finished quickly based on the apps that you included in the configuration. This will reduce a lot of waiting time to finish the serve command.

We can change the required apps in the routing.dev.module and tsconfig.dev.json based on your development activities.

**Note:**
- These configurations are only for local development.  Don't use this for production.
- These new configurations may not be required for smaller applications.