0

我有一个 Angular 9 项目,它是应用程序套件安装程序 [Wix 安装程序] 的一部分。Angular 应用程序使用的设置之一是 API 的地址,它从某个可配置的地址获取数据。我知道我可以拥有许多角度环境文件,并且只需使用以下命令:

environment.env1.ts

export const environment = {
  production: true,
  apiAddress: "http://apiAddress1/api/",
};


ng build --prod --configuration=env1    

或者

environment.env2.ts

    export const environment = {
      production: true,
      apiAddress: "http://apiAddress2/api/",
    };

    ng build --prod --configuration=env2

这意味着对于每个潜在的 API 地址,我都需要进行新的构建并在命令之上运行。如何克服上述情况并在构建后配置输出二进制文件?

假设没有明确的方法来实现构建后的配置,我可以对生成的 main*.js 文件中的 API 地址进行“简单字符串替换”吗?会不会有什么副作用?

4

2 回答 2

2

您可以在配置文件中外包您的 api 端点。并提供一个AppInitializer使用您的配置文件。这是一个例子:

loader 函数,它通过 http from 加载配置/config/config.json并设置 api 配置:

export function loadConfig(http: HttpClient, config: ApiConfiguration): (() => Promise<boolean>) {
  return (): Promise<boolean> => {
    return new Promise<boolean>((resolve: (a: boolean) => void): void => {
      http.get('./config/config.json')
        .pipe(
          map((x: any) => {
            config.rootUrl = x.rootUrl + '/v2';
            resolve(true);
          }),
          catchError((x: { status: number }, caught: Observable<void>): ObservableInput<{}> => {
            // 404 local development, other errors are strange
            resolve(x.status === 404);
            return of({});
          })
        ).subscribe();
    });
  };
}

json 只包含一个名为rootUrl.

要使用此功能,在应用程序初始化之前,AppInitializer请在您的app.module.ts:

providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: loadConfig,
      deps: [
        HttpClient,
        ApiConfiguration
      ],
      multi: true
    }

ApiConfiguration存储 api 端点,它只是一个具有默认值的类(用于开发):

@Injectable({
  providedIn: 'root',
})
export class ApiConfiguration {
  rootUrl: string = 'localhost:8080';
}

只需在您的/dist文件夹中放置一个配置文件,它应该可以工作:)

于 2020-05-18T21:33:30.930 回答
1

构建完成后可能对生成的文件执行查找和替换,但这感觉不对。

而是创建一个configuration.json文件并将其放在您的资产文件夹中。然后在您的应用程序中,使用导入直接引用该文件。您可能必须通过在tsconfig.jsonresolveJsonModule中设置为来启用此功能。true

现在,在构建应用程序之后,可以使用简单的技术(例如在 NodeJs 中使用和)替换configuration.json中的值,而不必担心意外的副作用。fs.readFileSync(path)fs.writeFileSync(path, JSON.stringify(data))

示例 xyz.module.ts 部分

import dynamicConfig from '../assets/configuration.json';
@NgModule({
  providers: [
    {
      provide: API_BASE_URL,
      useValue: dynamicConfig.apiAddress
    }
  ]
})
export class XyzModule { }
于 2020-05-18T20:06:18.987 回答