рдХреЛрдгреАрдп рдкрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╡рд┐рдиреНрдпрд╛рд╕ред рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕

рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдФрд░ рд▓рдХреНрд╖реНрдпреЛрдВ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХреИрд╕реЗ рдХрд░реЗрдВ


рдЬрдм рдЖрдкрдиреЗ рдХреЛрдгреАрдп CLI рдпрд╛ Nrwl Nx рдЯреВрд▓реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдХреЛрдгреАрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдмрдирд╛рдпрд╛, рддреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╣рдореЗрд╢рд╛ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝реЛрд▓реНрдбрд░ рд╣реЛрддрд╛ рд╣реИ:


<APP_FOLDER>/src/environments/ тФФтФАтФАenvironment.ts тФФтФАтФАenvironment.prod.ts 

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк environment.prod.ts рдХрд╛ рдирд╛рдо рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЗрдВ рднреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рдХрд┐ environment.qa.ts рдпрд╛ environment.staging.ts ред


 <APP_FOLDER>/src/environments/ тФФтФАтФАenvironment.ts тФФтФАтФАenvironment.prod.ts тФФтФАтФАenvironment.qa.ts тФФтФАтФАenvironment.staging.ts 

Environment.ts рдлрд╝рд╛рдЗрд▓ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рддреА рд╣реИред рд╢реЗрд╖ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ angular.json рдХреЛ рдЦреЛрд▓рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдлрд╝рд╛рдЗрд▓ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдмрд┐рд▓реНрдб рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рд╕реЗрд╡рд╛ рдФрд░ e2e рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдмреНрд▓реЙрдХ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред


 { "architect":{ "build":{ "configurations":{ "production":{ "fileReplacements":[ { "replace":"<APP_FOLDER>/src/environments/environment.ts", "with":"<APP_FOLDER>/src/environments/environment.production.ts" } ] }, "staging":{ "fileReplacements":[ { "replace":"<APP_FOLDER>/src/environments/environment.ts", "with":"<APP_FOLDER>/src/environments/environment.staging.ts" } ] } } }, "serve":{ "configurations":{ "production":{ "browserTarget":"app-name:build:production" }, "staging":{ "browserTarget":"app-name:build:staging" } } }, "e2e":{ "configurations":{ "production":{ "browserTarget":"app-name:serve:production" }, "staging":{ "browserTarget":"app-name:serve:staging" } } } } } 

рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд╕рд╛рде рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдиреЗ рдпрд╛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрдорд╛рдВрдбреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:


 ng build --configuration=staging ng start --configuration=staging ng e2e --configuration=staging  ng build --prod     ng build --configuration=production 

рдкрд░реНрдпрд╛рд╡рд░рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдмрдирд╛рдПрдБ


 // environment-interface.ts export interface EnvironmentInterface { production: boolean; apiUrl: string; } // environment.ts export const environment: EnvironmentInterface = { production: false, apiUrl: 'https://api.url', }; 

рд╕реАрдзреЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВ, рдХреЗрд╡рд▓ рдбреАрдЖрдИ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ


рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдФрд░ рдкреНрд░рддреНрдпрдХреНрд╖ рдЖрдпрд╛рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдУрдУрдкреА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреА рдХрдХреНрд╖рд╛рдУрдВ рдХреА рдкрд░реАрдХреНрд╖рдг рдХреНрд╖рдорддрд╛ рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдРрд╕реА рд╕реЗрд╡рд╛ рдмрдирд╛рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдХреЗ рдШрдЯрдХреЛрдВ рдФрд░ рдЕрдиреНрдп рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╡рд╛рд▓реА рдРрд╕реА рд╕реЗрд╡рд╛ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


 export const ENVIRONMENT = new InjectionToken<{ [key: string]: any }>('environment'); @Injectable({ providedIn: 'root', }) export class EnvironmentService { private readonly environment: any; // We need @Optional to be able start app without providing environment file constructor(@Optional() @Inject(ENVIRONMENT) environment: any) { this.environment = environment !== null ? environment : {}; } getValue(key: string, defaultValue?: any): any { return this.environment[key] || defaultValue; } } @NgModule({ imports: [ BrowserModule, HttpClientModule, AppRoutingModule, ], declarations: [ AppComponent, ], // We declare environment as provider to be able to easy test our service providers: [{ provide: ENVIRONMENT, useValue: environment }], bootstrap: [AppComponent], }) export class AppModule { } 

рдЕрдкрдиреЗ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдФрд░ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдХреЛ рдЕрд▓рдЧ рдХрд░реЗрдВ


рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдХреЗрд╡рд▓ рдЧреБрдг рд╢рд╛рдорд┐рд▓ рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рдкрд░реНрдпрд╛рд╡рд░рдг рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдПрдкреАрдпреВрдЖрд░рдПрд▓ ред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдкрд░реНрдпрд╛рд╡рд░рдг рд╡рд┐рдиреНрдпрд╛рд╕ рдореЗрдВ рджреЛ рдЧреБрдг рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП:


 export const environment = { production: true, apiUrl: 'https://api.url', }; 

рдЗрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рднреА рдЖрдк рдбрд┐рдмрдЧреЛрдб рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ : рд╕рд╣реА рдореЛрдб рдбреАрдмрдЧ рдпрд╛ рдЖрдк рд╕рд░реНрд╡рд░ рдХрд╛ рдирд╛рдо рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдПрдирд╡рд╛рдпрд░рдирдореЗрдВрдЯ: 'рдХреНрдпреВрдП' рдЪрд▓ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдордд рднреВрд▓реЛ рдХрд┐ рдпрд╣ рдмрд╣реБрдд рдмреБрд░рд╛ рдЕрднреНрдпрд╛рд╕ рд╣реИ рдпрджрд┐ рдЖрдкрдХрд╛ рдХреЛрдб рд╕рд░реНрд╡рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдХрд╣ рд░рд╣рд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рд╡рд╣ рдЪрд▓ рд░рд╣рд╛ рд╣реИ ред


рдХрд┐рд╕реА рднреА рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдЬрд╛рдирдХрд╛рд░реА рдпрд╛ рдкрд╛рд╕рд╡рд░реНрдб рдХреЛ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рди рдХрд░реЗрдВред


рдЕрдиреНрдп рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдЬреИрд╕реЗ рдХрд┐ maxItemsOnPage рдпрд╛ GalleryAnimationSpeed рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рд╕реНрдерд╛рди рдкрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди. service.ts рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЙрдЪрд┐рдд рд╣реИ , рдЬреЛ рдХреБрдЫ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рд╕реЗ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рд╕рдВрдкрддреНрддрд┐ рдлрд╝реЛрд▓реНрдбрд░ рд╕реЗ рдмрд╕ config.json рд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


1. рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг (рдЙрдкрдпреЛрдЧ рдЬрдм рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд░рдирдЯрд╛рдЗрдо рдореЗрдВ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИ)


 // assets/config.json { "galleryAnimationSpeed": 5000 } // configuration.service.ts // ------------------------------------------------------ @Injectable({ providedIn: 'root', }) export class ConfigurationService { private configurationSubject = new ReplaySubject<any>(1); constructor(private httpClient: HttpClient) { this.load(); } // method can be used to refresh configuration load(): void { this.httpClient.get('/assets/config.json') .pipe( catchError(() => of(null)), filter(Boolean), ) .subscribe((configuration: any) => this.configurationSubject.next(configuration)); } getValue(key: string, defaultValue?: any): Observable<any> { return this.configurationSubject .pipe( map((configuration: any) => configuration[key] || defaultValue), ); } } // app.component.ts // ------------------------------------------------------ @Component({ selector: 'app-root', changeDetection: ChangeDetectionStrategy.OnPush, templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { galleryAnimationSpeed$: Observable<number>; constructor(private configurationService: ConfigurationService) { this.galleryAnimationSpeed$ = this.configurationService.getValue('galleryAnimationSpeed', 3000); interval(10000).subscribe(() => this.configurationService.load()); } } 

2. рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг (рдЙрдкрдпреЛрдЧ рдЬрдм рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд▓рдЧрднрдЧ рдХрднреА рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИ)


 // assets/config.json { "galleryAnimationSpeed": 5000 } // configuration.service.ts // ------------------------------------------------------ @Injectable({ providedIn: 'root', }) export class ConfigurationService { private configuration = {}; constructor(private httpClient: HttpClient) { } load(): Observable<void> { return this.httpClient.get('/assets/config.json') .pipe( tap((configuration: any) => this.configuration = configuration), mapTo(undefined), ); } getValue(key: string, defaultValue?: any): any { return this.configuration[key] || defaultValue; } } // app.module.ts // ------------------------------------------------------ export function initApp(configurationService: ConfigurationService) { return () => configurationService.load().toPromise(); } @NgModule({ imports: [ BrowserModule, HttpClientModule, AppRoutingModule, ], declarations: [ AppComponent, ], providers: [ { provide: APP_INITIALIZER, useFactory: initApp, multi: true, deps: [ConfigurationService] } ], bootstrap: [AppComponent], }) export class AppModule { } // app.component.ts // ------------------------------------------------------ @Component({ selector: 'app-root', changeDetection: ChangeDetectionStrategy.OnPush, templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { galleryAnimationSpeed: number; constructor(private configurationService: ConfigurationService) { this.galleryAnimationSpeed = this.configurationService.getValue('galleryAnimationSpeed', 3000); } } 

рддреИрдирд╛рддреА рдпрд╛ рд░рдирдЯрд╛рдЗрдо рдХреЗ рджреМрд░рд╛рди рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рдХреЛ рдмрджрд▓реЗрдВ


рдХрдИ рдЯреАрдореЛрдВ рдиреЗ рдирд┐рдпрдо рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддреЗ рд╣реБрдП "рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдирд┐рд░реНрдорд┐рдд рдмрд┐рд▓реНрдб рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдкреНрд░рддреНрдпреЗрдХ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдЖрд╡реЗрджрди рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдХреЗ" рдПрдХ рдмрд╛рд░ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВ, рдХрдИ рдХреЛ рддреИрдирд╛рдд рдХрд░реЗрдВ "ред


рдЕрд▓рдЧ-рдЕрд▓рдЧ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЕрд╕реЗрдВрдмрд▓реА рди рдмрдирд╛рдПрдВ, рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдХреЗрд╡рд▓ рдПрдХ рдЙрддреНрдкрд╛рджрди рдЕрд╕реЗрдВрдмрд▓реА рдФрд░ рд╡рд┐рдХрд▓реНрдк рдорд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЗ рджреМрд░рд╛рди рдпрд╛ рдХреЛрдб рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдХрд░реЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ:


рдкрд░реНрдпрд╛рд╡рд░рдг рдлрд╛рдЗрд▓реЛрдВ рдореЗрдВ рдкреНрд▓реЗрд╕рд╣реЛрд▓реНрдбрд░реНрд╕ рдХреЗ рд╕рд╛рде рдореВрд▓реНрдпреЛрдВ рдХреЛ рдмрджрд▓реЗрдВ рдЬреЛ рддреИрдирд╛рддреА рдХреЗ рджреМрд░рд╛рди рдЕрдВрддрд┐рдо рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдореЗрдВ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛


 export const environment = { production: true, apiUrl: 'APPLICATION_API_URL', }; 

рдкрд░рд┐рдирд┐рдпреЛрдЬрди рдХреЗ рджреМрд░рд╛рди, рд╕реНрдЯреНрд░рд┐рдВрдЧ APPLICATION_API_URL рдХреЛ рдПрдкреАрдЖрдИ рд╕рд░реНрд╡рд░ рдХреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрддреЗ рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред


рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдФрд░ рдбреЙрдХ рд╡реЙрд▓реНрдпреВрдо рдХреЗ рд╕рд╛рде рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЗрдВрдЬреЗрдХреНрдЯ рдХрд░реЗрдВ


 export const environment = { production: true, apiUrl: window.APPLICATION_API_URL, }; // in index.html before angular app bundles <script src="environment.js"></script> 

рд▓реЗрдЦ рдкрд░ рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореБрдЭреЗ рд░рдЪрдирд╛рддреНрдордХ рдЖрд▓реЛрдЪрдирд╛ рдФрд░ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдкрд░ рдЦреБрд╢реА рд╣реЛрдЧреАред




рдордзреНрдпрдо , рдЯреЗрд▓реАрдЧреНрд░рд╛рдо рдпрд╛ рдЯреНрд╡рд┐рдЯрд░ рдкрд░ рднреА рд╣рдорд╛рд░реЗ рд╕рдореБрджрд╛рдп рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдВред

Source: https://habr.com/ru/post/hi477214/


All Articles