jeti
jeti

Reputation: 1908

Angular CLI 6.x environment files for a library

I've created a library with the new CLI 6.x. I've also created an Angular service inside it and I would like to use different URLs for my dev and prod environment. So I created an environment.ts and an environment.prod.ts file in my library folder.

//dev
export const environment = {
  production: false,
  url: 'dev-url'
};

//prod
export const environment = {
  production: true,
  url: 'prod-url'
};

I also added the 'fileReplacements' property to the angular.json file:

"configurations": {
  "production": {
    "fileReplacements": [{
      "replace": "projects/tk-shared/src/environments/environment.ts",
      "with": "projects/tk-shared/src/environments/environment.prod.ts"
    }],
    "project": "projects/tk-shared/ng-package.prod.json"
  }
}

Compiling the library with the ng build tk-shared works and uses the dev settings, however when compiling with ng build --prod tk-shared I get the following error:

Schema validation failed with the following errors: Data path "" should NOT have additional properties(fileReplacements).

My tip is that the reason is that tk-shared has the projectType: "library" property in angular.json.
Anyway, is it possible to use environment files in a library?

Upvotes: 13

Views: 5055

Answers (1)

jeti
jeti

Reputation: 1908

Thanks, @R. Richards for pointing me to the right solution! These two sources helped me figure out how to do this injection correctly: LINK1 and LINK2.

So what I did ...

Created an InjectionToken and modified my TkSharedModule:

export const BASE_URL = new InjectionToken<string>('BASE_URL');
//...
export class TkSharedModule {
  static forRoot(host: string) {
    return {
      ngModule: TkSharedModule,
      providers: [{
        provide: BASE_URL,
        useValue: host
      }]
    }
  }
}

Provided a value for this token from the environment files in my AppModule:

import {environment} from '../environments/environment';
//...
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    TkSharedModule.forRoot(environment.url)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

And finally injected this value in my service:

//MyServiceService

import { BASE_URL } from '../tk-shared.module';

constructor(@Inject(BASE_URL) BASE_URL: string) {
  console.log('base url', BASE_URL);
}

Upvotes: 10

Related Questions