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?
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.