Angular (8) 应用程序构建一次(使用生产配置)并部署到多个环境
Posted
技术标签:
【中文标题】Angular (8) 应用程序构建一次(使用生产配置)并部署到多个环境【英文标题】:Angular (8) application build once (with production config) and deploy to multiple environments 【发布时间】:2020-05-13 05:18:52 【问题描述】:我有一种情况,我正在尝试使用生产配置构建我的 Angular 应用程序并部署到多个环境,例如,ng build --configuration=production
这里的工作流程是当我使用上述命令(ng build --configuration=production)进行构建时,environment.ts 文件被替换为 environment.prod.ts
我在environment.prod.ts中的配置如下,
export const environment =
production: true,
environment: 'Production',
_webApiHost: 'prodsomename.company.com/api/',
;
我在environmrnt.test.ts中的配置如下,
export const environment =
production: true,
environment: 'Test',
_webApiHost: 'testsomename.company.com/api/',
;
我对 angular.json 文件的设置如下,
"configurations":
"production":
"fileReplacements": [
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
]
,
"test":
"fileReplacements": [
"replace": "src/assets/configs/environment.ts",
"with": "src/assets/configs/environment.test.ts"
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
]
如果我分别为每个环境构建解决方案并部署到适当的环境,如下图,
它的作用就像魅力,这意味着,
testApp 与 _webApiHost 通信:testsomename.company.com/api/ 和 prodApp 与 _webApiHost 通信:prodsomename.company.com/api/
在上述情况下,由 QA 测试的 工件与部署到生产环境的工件不同,这不是将代码推送到生产环境的理想方式。
但我担心的是我只想构建应用程序并将其部署到多个环境中,每个环境都会与适当的 api 进行通信,如下图所示,
当我使用命令 ng build --configuration=production 构建它时,environment.ts 文件将具有生产配置,
export const environment =
production: true,
environment: 'Production',
_webApiHost: 'prodsomename.company.com/api/',
;
因此,如果将该工件部署到测试环境, testApp 正在尝试与 _webApiHost: 'prodsomename.company.com/api/ 通信,这是不对的。
这是我用来构建解决方案的 Azure DevOps 构建管道 powershell 脚本。
Set-Location "$(Build.Repository.LocalPath)\Buffini.Web.UI\Angular"
Write-Host 'Angular Install Starting'
npm install -g @angular/cli@8.0.6 -Verbose
Write-Host 'Angular Install Finished'
Write-Host 'NPM Install Starting'
npm install -Verbose
Write-Host 'NPM Install Finished'
Write-Host 'NPM Update Starting'
npm update -Verbose
Write-Host 'NPM Update Finished'
Write-Host 'NPM Audit Starting'
npm audit fix -Verbose
Write-Host 'NPM Audit Finished'
Write-Host 'Angular Build Starting'
ng build --configuration=production --deleteOutputPath=true
Write-Host 'Angular Build Finished'
我已尝试在线搜索解决方案,但找不到任何解决方案。 请帮助我解决问题。我将非常感谢您的时间和帮助。提前致谢。
【问题讨论】:
【参考方案1】:在运行时替换应用配置。您需要创建包含动态配置的 config.json 文件(例如_webApiHost
)。您可以查看this blog 中的示例代码以获取 config.json。
在您的管道中,您可以添加扩展任务来替换 config.json 内容,然后再部署到不同的环境(例如测试、生产)。
这样你只需要构建你的 Angular 应用程序一次,并且只需要在部署到不同的环境之前相应地替换 config.json 内容。
您可以查看可用的扩展程序。 Magic Chunks task,或 RegEx Match & Replace Task。您可以查看this thread 以获取使用这些任务的示例。
【讨论】:
嗨@Ananth Asamani 您是否尝试过上述扩展,效果如何? 嗨,Levi Lu,很抱歉耽搁了,我被卷入了其他问题,所以不得不解决它们。我最终在我的 service.ts 文件中按照以下方式进行操作,if (window.location.hostname === 'account.company.com') this._webApiHost = 'api.company.com/api/'; else if (window.location.hostname === 'test-account.company.com') this._webApiHost = 'testapi.company.com/api/'; else this._webApiHost = 'localhost:62603';这可能不是一个理想或正确的方法,但我现在(暂时)最终有了这个。但现在我正在尝试实施上述您。我会让您知道。【参考方案2】:我不会假装这是一个答案,但它的想法足够长,不适合 cmets 领域。也许你会发现它很有帮助。 (完全披露:我使用的不是 Azure,而是 GitLab。因此,无论如何,如果您发现这种使用方法,则需要进行一些翻译。)
不管怎样,我不久前也问过同样的问题。经过一番挖掘,I found this link helpful
根据该指导,我执行了以下操作:
首先,我做了一个基本的 docker 构建。在那个版本中,我在一个文件夹中有各种“准备好询问”的环境文件。实际驱动应用的配置文件位于根目录。
然后我进行另一个 docker 构建,其唯一目的是获取第一个构建并为其提供所需的配置。 (我这样做是因为第一次构建很慢,但我想在不重建的情况下推动生产。)
接下来我做我想要的环境构建。
对于暂存,例如:在我的 GitLab 构建 CI/CD 管道 yaml 中,我有这样一行......
docker build -t xxxxx --build-arg SERVE_CONFIGURATION=staging -f [A-Docker-File] .
docker 文件对于所有环境都是相同的,但根据传入的参数,此 docker 构建会拉取不同的文件并将其猛烈撞击到驾驶员座位上。由于 Angular 部署中没有秘密,因此文件夹结构中潜伏着额外(未使用的)配置文件并不重要(尽管如果有动机,可以轻松删除它们。)
无论如何,在第二个 docker build 中,我有...
...
FROM registry.gitlab.com/xxxxxxxxxxxx/compiled as default-config
FROM registry.gitlab.com/xxxxxxxxxxxx/compiled as final-config
COPY --from=default-config /usr/share/nginx/html/environments/environment.$SERVE_CONFIGURATION.js /usr/share/nginx/html/environment.js
所以这个 docker 镜像只不过是之前镜像的构建,但所需的环境文件位于适当的位置。
无论如何,我可能遗漏了一些细节,但我不确定这是否会对您有所帮助并且会到此为止。
【讨论】:
以上是关于Angular (8) 应用程序构建一次(使用生产配置)并部署到多个环境的主要内容,如果未能解决你的问题,请参考以下文章
构建 Angular 8 项目时出现空白页面,但使用“ng serve”可以完美运行
如何在 Angular cli 中启用 gzip 压缩以进行生产构建