Configuring angular production files after build

放肆的年华 提交于 2021-02-11 13:50:22

问题


I have an angular 9 project which is part of an application suite installer [Wix installer]. One of the settings used by the angular app is the address of API which it fetches its data from some configurable address. I know that I can have many angular environment files and simply use commands such as the followings:

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. How can I overcome above scenario and configure output binaries after the build?

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? Would there be any side effects?


回答1:


You can outsource your api endpoint in a config file. And provide an AppInitializer to use your config file. Here is an example:

the loader function, which loads the config via http from /config/config.json and sets the api configuration:

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.

And to use this function, before the app initializes, provide an AppInitializer in your app.module.ts:

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):

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

Just put a config file in your /dist folder and it should work :)




回答2:


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. 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.

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)).

Sample xyz.module.ts section

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


来源:https://stackoverflow.com/questions/61877574/configuring-angular-production-files-after-build

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!