'NX + NestJS: Sharing NX environment variables

I read an old thread where it is recommended to share NX environment variables like the following:

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

@Module({
    providers: [
        {
            provider: 'someProviderName',
            useValue: environment.someEnvironmentValue
        }
    ],
    MyService
})
class AppModule {
}

Then, you access them like:

@Injectable()
class MyService {
    constructor(@Inject('someProviderName') someEnvironmentValue: someType) {
    }
}

The justifications are that:

  1. It keeps your libs env independent.
  2. It allows you to build libs once, without knowing the apps they are used by or the env they ran in.

This is fine if you just need access to the environment variables from AppModule, but how can you share these environment variables with imported library modules? Especially library modules whose source does not reside within the same project as the environment.ts files?

Does every library module that need access to environment variables need to be a dynamic module (as well as all its parent modules) in order to take advantage of environment variables this way? And as such, do you need to chain down forRoot calls to get to any module that needs to access these variables?

Ex:

                            AppModule: DynamicModule
                                    |
                            CoreModule: DynamicModule
                                |           |
     SomeFeatureModule: DynamicModule     SomeOtherFeatureModule: NestModule
  1. AppModule (Needs ENV so it becomes a DynamicModule with ForRoot)
  2. CoreModule (Needs env from AppModule so it becomes a DynamicModule with ForRoot
  3. SomeFeatureModule needs env from CoreModule so it becomes a DynamicModule with forRoot)
  4. ... so on and so forth.

Also what would making all modules that need environment values into DynamicModule do to performance?

Example:

@Module({})
export class MyLibModule {
  static forRoot(providers: Provider[]): DynamicModule {
    return {
      module: MyLibModule ,
      providers: [...providers],
    };
  }
}
const ENV_VALUE_PROVIDERS: ValueProvider[] = [
  {
    provide: 'PRODUCTION',
    useValue: environment.production,
  },
];
@Module({
  providers: ENV_VALUE_PROVIDERS,
  imports: [MyLibModule.register(ENV_VALUE_PROVIDERS)],
})
export class AppModule {}

Why does NestJS force any lib modules to be dynamic to access these type of environment variables in this case given these variables are available at compile-time?

The only other solution I have thought of is to create a Library Module that gets imported by every module that needs environment variables. This module would be initialized in the AppModule using forRoot with the environment variables to be exported. The problem with this solution is that many libraries would then have a direct dependency on this module.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source