Angular Azure 插槽部署存在 2 个配置问题
Angular 2 configuration issues with Azure Slot deployments
我在使用 Angular 环境变量和 Azure Slots
时遇到问题
我们想使用提供静态 Angular 文件的应用服务,我们还想使用 Azure 插槽来使我们的部署更安全。
我们要使用插槽的原因是:
- 确保代码在生产环境中正常工作,然后才能完全供所有人使用
- 将停机时间减少到几乎为零,因为在 "go-live" 阶段没有部署构建
我们的 Angular 站点仅提供静态文件,这意味着插槽部署需要不同的构建来为每个插槽填充不同的 env.json 环境设置。
我们正在考虑采用的解决方案是在同一个 Angular 网站中创建一个端点,然后从 Angular 站点调用返回其源以获取其配置。通过这种方式,可以在 Azure 的暂存和生产槽中设置不同的配置,并且只需要一个 Angular 构建。
我们需要一些服务器端代码来获取这些 Azure 应用程序设置并在站点的端点中提供它们。我们尚未就用于创建该端点的技术做出决定 - 我们目前正在考虑 .Net Core 或 NodeJs,因为它们似乎非常适合 Angular 产品和开发团队。
有没有人有插入服务器端组件为以前静态的 Angular 网站提供配置的经验?
为了达到您的要求,您只需将以下 PHP 文件放入您的站点根文件夹即可。然后通过您的 Angular 应用向端点 http://<websitename>.azurewebsites.net/appSettings.php
发送 GET 请求。这将为您提供一个 JSON 对象,其中包含所有 应用程序设置 。
appSettings.php
<?php
$appSettings = [];
foreach ($_SERVER as $key => $value) {
if(preg_match('/^APPSETTING_/', $key)) {
$appSettings[str_replace('APPSETTING_', '', $key)] = $value;
}
}
header('Content-Type: application/json');
echo json_encode($appSettings);
也许有人还需要它。我建议更接近所选技术并公开 node.js api 类似于之前的 php 答案。
我创建在 Azure AppService 中公开的端点 http://<websitename>.azurewebsites.net/app-settings
,如下所示:
将 index.js 文件添加到 Angular 代码中的 src 目录中:
var http = require('http');
var server = http.createServer(function (request, response) {
response.writeHead(200, { "Content-Type": "application/json" });
var result = {};
result.someAppSetting = process.env.SomeApplicationSetting;
var jsonResult = JSON.stringify(result);
response.end(jsonResult);
});
var port = process.env.PORT || 1337;
server.listen(port);
console.log("Server exposing api for reading application settings running at http://localhost:%d", port);
因此,响应包含 json 以及 process.env.SomeApplicationSetting
从环境变量中检索到的 SomeApplicationSetting
应用程序设置。当然,您可以采用其他策略来公开变量,例如仅向 json 或任何其他内容添加一些前缀设置。
将 index.js 添加到 angular.json 中的资产:
"assets": [
"src/favicon.ico",
"src/assets",
"src/web.config",
"src/index.js"
],
然后在web.config中添加如下重写规则:
<rule name="Read app settings" stopProcessing="true">
<match url="app-settings" />
<action type="Rewrite" url="index.js"/>
</rule>
我查看了所有解决方案并创建了一个在 Azure 和本地计算机 (localhost) 上运行的解决方案。这取决于构建 - prod
(从 Azure 读取)或 dev
(从本地资产文件夹读取)Azure 插槽。
也许对某人有帮助。
首先,您需要像 Aaron Chen
提到的那样添加这个小 php 文件。
在 src
文件夹下的 Angular 结构中:
src/appSettings.php
$appSettings = [];
foreach ($_SERVER as $key => $value) {
if(preg_match('/^APPSETTING_/', $key)) {
$appSettings[str_replace('APPSETTING_', '', $key)] = $value;
}
}
header('Content-Type: application/json');
echo json_encode($appSettings, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
需要修改angular.json
文件。您需要将 assets
添加到 "src/appSettings.php"
"assets": [
"src/favicon.ico",
"src/assets",
"src/appSettings.php"
],
此解决方案从 http://<websitename>.azurewebsites.net/appSettings.php
link 中的 azure 获取所有配置。
这仅适用于 Azure(需要身份验证)。对于本地开发,您需要创建一个 Json 文件 包含 src/assets
文件夹下的所有 Azure 插槽。
`assets/config/backend.json`;
要加载配置 Json 需要创建
src/app/app.config.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpBackend } from '@angular/common/http';
import { AppSettings } from './models/AppSettings.model';
import { environment } from 'src/environments/environment';
@Injectable()
export class AppConfig {
static appSettings: AppSettings;
private http: HttpClient;
constructor( handler: HttpBackend) {
this.http = new HttpClient(handler);
}
public load() {
let backendConfigUrl: string;
if (environment.production) {
backendConfigUrl = window.location.origin + '/appsettings.php';
} else {
backendConfigUrl = `assets/config/backend.json`;
}
console.log(backendConfigUrl);
return new Promise<void>((resolve, reject) => {
this.http.get<AppSettings>(backendConfigUrl).toPromise().then((response: AppSettings) => {
AppConfig.appSettings = response;
resolve();
}).catch((response: any) => {
reject(`Could not load file ${backendConfigUrl}: ${JSON.stringify(response)}`);
});
});
}
}
然后修改src/app/app.module.ts
在应用启动前加载配置
export function initializeApp(appConfig: AppConfig) {
return () => appConfig.load().then(() => {
console.log(AppConfig.appSettings)
});
}
providers: [
AppConfig,
{
provide: APP_INITIALIZER,
useFactory: initializeApp,
deps: [AppConfig],
multi: true
},
]
To ng build
从本地 assets
文件夹加载配置。 To ng build --prod
从 Azure 读取配置。与 ng serve
和 ng serve --prod
相同
我在使用 Angular 环境变量和 Azure Slots
时遇到问题我们想使用提供静态 Angular 文件的应用服务,我们还想使用 Azure 插槽来使我们的部署更安全。
我们要使用插槽的原因是:
- 确保代码在生产环境中正常工作,然后才能完全供所有人使用
- 将停机时间减少到几乎为零,因为在 "go-live" 阶段没有部署构建
我们的 Angular 站点仅提供静态文件,这意味着插槽部署需要不同的构建来为每个插槽填充不同的 env.json 环境设置。
我们正在考虑采用的解决方案是在同一个 Angular 网站中创建一个端点,然后从 Angular 站点调用返回其源以获取其配置。通过这种方式,可以在 Azure 的暂存和生产槽中设置不同的配置,并且只需要一个 Angular 构建。
我们需要一些服务器端代码来获取这些 Azure 应用程序设置并在站点的端点中提供它们。我们尚未就用于创建该端点的技术做出决定 - 我们目前正在考虑 .Net Core 或 NodeJs,因为它们似乎非常适合 Angular 产品和开发团队。
有没有人有插入服务器端组件为以前静态的 Angular 网站提供配置的经验?
为了达到您的要求,您只需将以下 PHP 文件放入您的站点根文件夹即可。然后通过您的 Angular 应用向端点 http://<websitename>.azurewebsites.net/appSettings.php
发送 GET 请求。这将为您提供一个 JSON 对象,其中包含所有 应用程序设置 。
appSettings.php
<?php
$appSettings = [];
foreach ($_SERVER as $key => $value) {
if(preg_match('/^APPSETTING_/', $key)) {
$appSettings[str_replace('APPSETTING_', '', $key)] = $value;
}
}
header('Content-Type: application/json');
echo json_encode($appSettings);
也许有人还需要它。我建议更接近所选技术并公开 node.js api 类似于之前的 php 答案。
我创建在 Azure AppService 中公开的端点 http://<websitename>.azurewebsites.net/app-settings
,如下所示:
将 index.js 文件添加到 Angular 代码中的 src 目录中:
var http = require('http');
var server = http.createServer(function (request, response) {
response.writeHead(200, { "Content-Type": "application/json" });
var result = {};
result.someAppSetting = process.env.SomeApplicationSetting;
var jsonResult = JSON.stringify(result);
response.end(jsonResult);
});
var port = process.env.PORT || 1337;
server.listen(port);
console.log("Server exposing api for reading application settings running at http://localhost:%d", port);
因此,响应包含 json 以及 process.env.SomeApplicationSetting
从环境变量中检索到的 SomeApplicationSetting
应用程序设置。当然,您可以采用其他策略来公开变量,例如仅向 json 或任何其他内容添加一些前缀设置。
将 index.js 添加到 angular.json 中的资产:
"assets": [
"src/favicon.ico",
"src/assets",
"src/web.config",
"src/index.js"
],
然后在web.config中添加如下重写规则:
<rule name="Read app settings" stopProcessing="true">
<match url="app-settings" />
<action type="Rewrite" url="index.js"/>
</rule>
我查看了所有解决方案并创建了一个在 Azure 和本地计算机 (localhost) 上运行的解决方案。这取决于构建 - prod
(从 Azure 读取)或 dev
(从本地资产文件夹读取)Azure 插槽。
也许对某人有帮助。
首先,您需要像 Aaron Chen
提到的那样添加这个小 php 文件。
在 src
文件夹下的 Angular 结构中:
src/appSettings.php
$appSettings = [];
foreach ($_SERVER as $key => $value) {
if(preg_match('/^APPSETTING_/', $key)) {
$appSettings[str_replace('APPSETTING_', '', $key)] = $value;
}
}
header('Content-Type: application/json');
echo json_encode($appSettings, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
需要修改angular.json
文件。您需要将 assets
添加到 "src/appSettings.php"
"assets": [
"src/favicon.ico",
"src/assets",
"src/appSettings.php"
],
此解决方案从 http://<websitename>.azurewebsites.net/appSettings.php
link 中的 azure 获取所有配置。
这仅适用于 Azure(需要身份验证)。对于本地开发,您需要创建一个 Json 文件 包含 src/assets
文件夹下的所有 Azure 插槽。
`assets/config/backend.json`;
要加载配置 Json 需要创建
src/app/app.config.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpBackend } from '@angular/common/http';
import { AppSettings } from './models/AppSettings.model';
import { environment } from 'src/environments/environment';
@Injectable()
export class AppConfig {
static appSettings: AppSettings;
private http: HttpClient;
constructor( handler: HttpBackend) {
this.http = new HttpClient(handler);
}
public load() {
let backendConfigUrl: string;
if (environment.production) {
backendConfigUrl = window.location.origin + '/appsettings.php';
} else {
backendConfigUrl = `assets/config/backend.json`;
}
console.log(backendConfigUrl);
return new Promise<void>((resolve, reject) => {
this.http.get<AppSettings>(backendConfigUrl).toPromise().then((response: AppSettings) => {
AppConfig.appSettings = response;
resolve();
}).catch((response: any) => {
reject(`Could not load file ${backendConfigUrl}: ${JSON.stringify(response)}`);
});
});
}
}
然后修改src/app/app.module.ts
在应用启动前加载配置
export function initializeApp(appConfig: AppConfig) {
return () => appConfig.load().then(() => {
console.log(AppConfig.appSettings)
});
}
providers: [
AppConfig,
{
provide: APP_INITIALIZER,
useFactory: initializeApp,
deps: [AppConfig],
multi: true
},
]
To ng build
从本地 assets
文件夹加载配置。 To ng build --prod
从 Azure 读取配置。与 ng serve
和 ng serve --prod