Ronin
Ronin

Reputation: 7970

Dev/Prod environments for different customer configurations

The Build Config Section of the Angular Workspace Configuration Guide discusses how various configurations can be managed within the same app.

In my case, I decided to create a config for each customer:

// angular.json excerpt
"architect": {
    "build": {
        "configurations": {
            "customer-1": {
                "fileReplacements": [
                    {
                    "replace": "src/environments/environment.ts",
                    "with": "src/environments/environment.customer-1.ts"
                    }
                ]
            },
            "customer-2": {
                "fileReplacements": [
                    {
                    "replace": "src/environments/environment.ts",
                    "with": "src/environments/environment.customer-2.ts"
                    }
                ]
            },
        }
    },
    "serve": {
        "builder": "@angular-devkit/build-angular:dev-server",
        "configurations": {
            "customer-1": {
                "browserTarget": "my-app:build:customer-1"
            },
            "customer-2": {
                "browserTarget": "my-app:build:customer-2"
            },
}

I use the environment files to manage various customer-specific settings and a production flag:

// environment.customer-1.ts excerpt
const environment = {
  production: true,
  customer: "Customer 1",
};


// environment.customer-2.ts excerpt
const environment = {
  production: true,
  customer: "Customer 2",
};

Finally, I need a way to determine whether the app was started using the ng serve or the ng build command, in order to import some mocked providers in the app module.

I tried using the environment.production flag but obviously it would always be true:

import { environment } from '../environments/environment';

@NgModule({
  providers: [
    environment.production // is always true since I've set the flag in all customer-specific environment.ts files
       ? []
       : nonProductionProviders,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

The only way I came up with to support this scenario is to create separate environment.ts files as well as matching configs, e.g.

// angular.json excerpt
"architect": {
    "build": {
        "configurations": {
            "customer-1-dev": {
                "fileReplacements": [
                    {
                    "replace": "src/environments/environment.ts",
                    "with": "src/environments/environment.customer-1-dev.ts"
                    }
                ]
            },
            // etc.

Is there a better way to do this? Passing an additional flag or at least the ability to extend configurations would be nice.

Upvotes: 0

Views: 230

Answers (1)

David
David

Reputation: 34465

I think what you have for now is the best way. Environment files are for configurations that are already known at compile time, which is exactly your scenario

You could also have a script that modifies a value in the src/environments/environment.customer-XX.ts file just before running use ng serve, but you'd risk commiting that modified file onto git by mistake.

You could also have some dynamic json config (modified post build), that you would retrieve through an http call before bootstrapping your app to see if build or serve was used, but it may be overkill for your case.

There is currently no way to extend configurations from the angular.json file. There is this feature request thatwould probably please a lot of people, but I don't think it's being worked on yet.

Upvotes: 0

Related Questions