Angular CLI 6.x环境文件用于库

13

我使用新的CLI 6.x版本创建了一个库。我还在其中创建了一个Angular服务,并希望在开发和生产环境中使用不同的URL。因此,我在我的库文件夹中创建了一个environment.ts文件和一个environment.prod.ts文件。

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

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

我还在angular.json文件中添加了'fileReplacements'属性:

"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"
  }
}

使用 ng build tk-shared 编译库并使用 dev 设置可以正常工作,但是当使用 ng build --prod tk-shared 编译时,会出现以下错误:

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

我的建议是,原因在于angular.json中的tk-shared具有 projectType: "library"属性。
不管怎样,是否可以在库中使用环境文件?


6
这似乎是一个不好的想法。你的库不应该管理配置;使用库的应用程序应该传递库所需的内容。从这个意义上说,库应该有点愚蠢,但足够聪明,知道它需要的配置未被提供。 - R. Richards
@R.Richards,我喜欢你的想法。你能展示一下如何实现吗? - jeti
1
你可以在这里找到一个如何实现它的例子;这是针对Firebase的。具体来说,看看他们如何实现/使用他们的initializeApp函数。所有细节都在他们的代码中。玩得开心! - R. Richards
@R.Richards 感谢您的提示,我成功地解决了问题。这是一个优雅的解决方案! - jeti
1个回答

10

感谢 @R. Richards 指出正确的解决方案!这两个来源帮助我弄清楚了如何正确进行注入:LINK1LINK2

所以我所做的是...

创建了一个 InjectionToken 并修改了我的 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
      }]
    }
  }
}

在我的AppModule中,从environment文件中为此令牌提供一个值:

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

最后把这个值注入到我的服务中:

//MyServiceService

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

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


如果您想在库模块/项目的NgModule装饰器中使用传递到forRoot方法中的内容,那么这种方法是否可行? - Jake Smith
你是指 environment.url 的值吗?如果是的话,那么是的,因为在库的服务中,BASE_URL 将具有 environment.url 的值。 - jeti
但我说的是在 NgModule 装饰器中使用它,而不是库的内部服务。 - Jake Smith
@JakeSmith,有没有找到如何做到那个的方法? - tylerjgarland
@jeti:使用 Angular 12,需要声明 forRoot 返回类型:static forRoot(host: string): ModuleWithProviders<TkSharedModule> { - makeroo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接