0

I am using Angular 9, View Engine compiler.

I have 2 files where I store environment values:

environment.ts:

export const environment: any = {
    production: false,
};

environment.prod.ts:

export const environment: any = {
    production: true
}

Here is a part of my angular.json configuration that swaps environment.ts with environment.prod.ts when building the app for production environment:

"configurations": {
    "production": {
      "fileReplacements": [
        {
          "replace": "app/src/environments/environment.ts",
          "with": "app/src/environments/environment.prod.ts"
        }
      ]
    }
  }

I am using environment variables to configure the third-party service if it should or should not run on developer mode. However, in production (when building with --prod flag), it was not working properly. After some investigation we have found out that the third party service is getting the value from environment.ts and not from the environment.prod.ts.

Here is the trimmed down version of app.module.ts where the configuration is made:

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

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    // Google Analytics (via Angulartics2)
    Angulartics2Module.forRoot({
      developerMode: !environment.production // <-- Gets incorrect value: 'true' on production mode
    }),                                      // but should be 'false'
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor() {
    console.log(!environment.production); // <-- Logs correct value: 'false' on production mode
  }
}

Later testing at runtime that Angulartics2 third-party service indeed received the wrong value:

@Injectable({ providedIn: 'root' })
export class GoogleAnalyticsService {
  constructor(
    private angulartics2: Angulartics2
  ) {
    console.log(this.angulartics2.settings.developerMode); // Logs 'true'
  }
}

Why is the wrong environment value being received in AppModule's @NgModule decorator function, but then - the correct one in AppModule's constructor and the service that executes later at runtime? Does the @NgModule() decorator function for AppModule gets executed before the environment files get swapped by the compiler?

mcvyty
  • 13
  • 4
  • Please post your tsconfig.json. Because '@env/environment' has unclear origin. – kvetis Dec 03 '20 at 16:18
  • I have updated the code with the relative path instead – mcvyty Dec 03 '20 at 16:22
  • It should be `import { environment } from './../environments/environment'`. Does the issue persist? – kvetis Dec 03 '20 at 16:33
  • Yes, the .prod part gets removed by the compiler, I have updated the code again, sorry about that. In any case, I can assure you that the issue is not with imports – mcvyty Dec 03 '20 at 16:45
  • Well when something is miss-imported, then the problem is with import. But probably not directly in your case. Your code seems correct, though. – kvetis Dec 03 '20 at 17:02

1 Answers1

1

It seems Angular uses Webpack for file replacements specified in Angular.json. So the file replacement happens at some point in the build phase, which is probably after the code in decorators such as @NgModule gets resolved by the Angular compiler. Thus, it seems one should not use environment variables when configuring @NgModule imports.

mcvyty
  • 13
  • 4