简体   繁体   English

构建后配置 angular 生产文件

[英]Configuring angular production files after build

I have an angular 9 project which is part of an application suite installer [Wix installer].我有一个 angular 9 项目,它是应用程序套件安装程序 [Wix 安装程序] 的一部分。 One of the settings used by the angular app is the address of API which it fetches its data from some configurable address. angular 应用程序使用的设置之一是 API 的地址,它从某个可配置的地址获取其数据。 I know that I can have many angular environment files and simply use commands such as the followings:我知道我可以有很多 angular 环境文件,只需使用如下命令:

environment.env1.ts

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


ng build --prod --configuration=env1    

or或者

environment.env2.ts

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

    ng build --prod --configuration=env2

This means for every potential API address I need to do a new build and run above command.这意味着对于每个潜在的 API 地址,我需要进行新的构建并运行以上命令。 How can I overcome above scenario and configure output binaries after the build?如何克服上述情况并在构建后配置 output 二进制文件?

Assuming there is no clear way of achieving the after-built configuration, can I do 'simple string replace' for the address of API in the generated main*.js files?假设没有明确的方法来实现构建后的配置,我可以对生成的 main*.js 文件中的 API 的地址进行“简单字符串替换”吗? Would there be any side effects?会不会有什么副作用?

You can outsource your api endpoint in a config file.您可以在配置文件中外包您的 api 端点。 And provide an AppInitializer to use your config file.并提供一个AppInitializer来使用您的配置文件。 Here is an example:这是一个例子:

the loader function, which loads the config via http from /config/config.json and sets the api configuration:加载程序 function,它通过 http 从/config/config.json加载配置并设置 Z8A38A952ED12647247C

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();
    });
  };
}

The json contains only one string named rootUrl . json 仅包含一个名为rootUrl的字符串。

And to use this function, before the app initializes, provide an AppInitializer in your app.module.ts :并且要使用这个 function,在应用程序初始化之前,在你的app.module.ts AppInitializer

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

ApiConfiguration stores the api endpoint which is just a class with a default value (for devlopment): ApiConfiguration存储 api 端点,它只是一个 class 具有默认值(用于开发):

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

Just put a config file in your /dist folder and it should work:)只需在您的/dist文件夹中放置一个配置文件,它应该可以工作:)

It is probably possible to perform a find and replace on the generated files after the build completes, but that just feels wrong.构建完成后可能对生成的文件执行查找和替换,但这感觉不对。

Instead create a configuration.json file and put it in your assets folder.而是创建一个configuration.json文件并将其放在您的资产文件夹中。 Then in your application, reference the file directly by using an import.然后在您的应用程序中,使用导入直接引用该文件。 You might have to enable this functionality by setting resolveJsonModule to true in your tsconfig.json .您可能必须通过在tsconfig.json 中将 resolveJsonModule resolveJsonModuletrue来启用此功能。

Now, after the application is built, the value can be replaced in configuration.json without fear of unintended side effects by using simple techniques such as in NodeJs with fs.readFileSync(path) and fs.writeFileSync(path, JSON.stringify(data)) .现在,在构建应用程序后,可以在configuration.json中使用简单的技术替换该值,而不必担心意外的副作用,例如在 NodeJs 中使用fs.readFileSync(path)fs.writeFileSync(path, JSON.stringify(data))

Sample xyz.module.ts section示例 xyz.module.ts 部分

import dynamicConfig from '../assets/configuration.json';
@NgModule({
  providers: [
    {
      provide: API_BASE_URL,
      useValue: dynamicConfig.apiAddress
    }
  ]
})
export class XyzModule { }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM