Compile-time vs. Runtime configuration of your Angular App
Tags: angular, webdev, javascript
Published: 2019-07-30 09:02:16

---
title: Compile-time vs. Runtime configuration of your Angular App
canonical_url: 'https://juristr.com/blog/2018/01/ng-app-runtime-config'
published: true
description: Learn how to setup compile time vs runtime configuration for your Angular application
cover_image: 'https://juristr.com/blog/assets/imgs/angular-cli-compiletime-config.png'
tags: Angular, webdev, javascript
---

_When you develop a bigger application, chances are quite high that you need some kind of configuration. That can range from simply visualizing the app's version number to injecting custom themes etc. In Angular you have different kind of approaches: compile-time and runtime configurations. Let's take a look at both of them._



## Compile-time configuration

[(Click to open Egghead lesson)](https://egghead.io/lessons/angular-configure-an-angular-app-at-compile-time-with-the-angular-cli)


**What is compile-time configuration?** It basically means that you compile your configuration into your app, at the time when you compile and bundle it. If you're using the Angular CLI there's already a preconfigured setup for having such compile-time configuration options.

![](https://juristr.com/blog/assets/imgs/angular-cli-compiletime-config.png)

Inside the `environments` folder you have a `environment.ts` and `environment.prod.ts` file. 

```javascript
// environment.ts
export const environment = {
  production: false
};
```

```javascript
// environment.prod.ts
export const environment = {
  production: true
};
```

Since these are just plain JavaScript objects, you can add your environment specific properties on them.  
The default `main.ts` file that is responsible for bootstrapping our Angular application uses those environment files to determine whether the app is running production mode, in order to apply some runtime optimizations such as calling `enableProdMode()`.

```javascript
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.log(err));
```

You can arbitrarily get a reference to that `environment` object by simply importing `environment.ts` into your file.

```javascript
import { environment } from '../environment/environment';

// do something meaningful with `environment`
console.log(environment);
```

Note, we're always importing `environment.ts` and never an environment specific file such as `environment.prod.ts`. The reason is that at compile time, the **Angular CLI will take care of renaming the environment specific configuration file into `environment.ts`** and to compile it into your app accordingly.

You can also create new files, say for your "staging" environment. Just create a new `environment.staging.ts` and make sure to configure it in your `angular.json` file:

```json
{
  // ...
  "projects": {
    "demo": {
      //...
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          // ...
          "configurations": {
            "staging": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.staging.ts"
                }
              ],
              //...
            },
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              //...
            }
          }
        },
        //...
      }
    }
  }
}
```

Finally, we need to tell the CLI which environment we're building for, s.t. it is able to pick up the proper configuration file. That happens in the scripts section of our `package.json`:

```json
{
  ...
  "scripts": {
    "ng": "ng",
    "build": "ng build --prod",
    "build:staging": "ng build --prod --env=staging"
  },
  ...
}
```

Note, we're passing in the `--env=<your-environment>` flag. the `--prod` is a built-in command which automatically uses the production configuration already, if not specified otherwise. Moreover it also **enables the AOT compilation**.


## Runtime configuration

[(Click to open Egghead lesson)](https://egghead.io/lessons/angular-configure-an-angular-app-at-runtime)

If however you need to be able to change your app's configuration settings or maybe you even expose them via an API, then you need to use **a runtime configuration approach**. Normally you simply have some JSON file - say `appConfig.json` that contains the necessary configuration options which you then deploy with your app on your server. When your app runs, you execute an HTTP request to that JSON file and read the settings.

What you want however, is to start your app only after your settings have been loaded and applied. A naive approach could be as follows. In your `app.component.ts` you simply add an `*ngIf` guard:

```javascript
@Component({
    selector: 'app-root',
    template: `
        <div *ngIf="configLoaded">

        </div>
    `
})
export class AppComponent implements OnInit {
    configLoaded = false;

    ngOnInit() {
        this.http.get('./assets/appConfig.json')
            .subscribe(config => {
                // do something with your configuration
                ...

                this.configLoaded = true;
            });
    }
}
```

That way your other components wouldn't start unless the `configLoaded` is true and consequently the `<div>` is being shown.

While this would work, there's a more elegant way of doing things: we can hook into Angular's bootstrapping phase by using the `APP_INITIALIZER` token. We first **create an Angular service that handles the fetching of our remote configuration**...

[Read more &raquo;](https://juristr.com/blog/2018/01/ng-app-runtime-config?utm_source=devto&utm_medium=crosspost)