Angular是最流行的前端框架之一。持续部署(CD)是过去十年中软件工程领域最重要的发展之一。它是持续集成(CI)的一个自然而又激进的演变。它的前身指出,开发人员应该经常将他们的工作合并到主线上,而CD则更进一步,指出每一次合并--当它们成功时--都应该自动部署到生产环境中。
在今天的文章中,我将指导你如何以一种基本而实用的方式为Angular应用程序设置CD,只利用免费资源。我还会告诉你如何在功能标志后面为你的应用添加一个新的功能,这样你就可以改变它的行为并跟踪它的性能,而无需多次部署。
持续集成和持续部署的好处
在我们进入帖子的实践部分之前,让我们通过解释什么是CI和CD,以及采用它们的好处来涵盖一些基础知识。
持续集成意味着开发人员经常集成他们的工作,至少每天一次,但通常更多。通过这样做,他们可以享受到缩短反馈周期、更早发现缺陷和提高产品整体质量的好处。
持续部署是更进一步,也是将部署自动化。这意味着,每次成功合并到主分支--即代码构建和所有测试及其他自动检查通过--产品都会交付给生产。
Angular中持续部署的实用指南
为了简洁起见,我们不会指导你设置一个Angular应用程序。我们要做的是把你指向一个GitHub仓库,在那里你可以下载或克隆一个赤裸裸的、功能性的CRUD应用。所以去这个仓库,克隆或下载这个应用程序。
一旦你有了一个包含应用程序的文件夹,打开一个终端,并导航到应用程序目录。如果你已经用Git克隆了仓库,通过运行这个删除与原始仓库的连接。
git remote remove origin
Code language: Shell Session (shell)
如果你是通过下载压缩包的方式获得该应用程序,则不需要上述步骤。现在,当你还在该应用程序的文件夹中时,通过运行以下命令来服务该应用程序。
ng serve
Code language: Shell Session (shell)
转到http://localhost:4200,你会看到应用程序正在运行。
该应用是一个简单的CRUD应用,它消耗了一个测试的Rest API(https://jsonplaceholder.typicode.com/)。
你现在已经准备好开始为你的应用程序实施CI/CD了。所以,让我们开始行动吧。
为你的Angular应用程序提供Firebase主机
正如我们所承诺的,你只需要免费的资源就可以完成这个教程。而你要利用的第一个资源是Firebase Hosting,一个由Google提供的免费托管服务。
因此,首先进入Firebase Hosting,并开始一个新项目。下一步,你将使用npm在全球范围内安装Firebase CLI。
npm install -g firebase-tools
Code language: Shell Session (shell)
安装完成后,你要通过运行以下命令登录到Firebase。
firebase login
Code language: Shell Session (shell)
浏览器上的一个新标签会把你带到一个页面,在那里你必须授权Firebase CLI访问你的谷歌账户。在你授权给Firebase CLI之后,你可以关闭浏览器窗口,回到你的终端。
现在你已经准备好为项目初始化Firebase了。在项目的根目录下,运行这个。
firebase init
Code language: Shell Session (shell)
然后你会被问到一堆问题。下划线到Hosting: Configure and deploy Firebase Hosting sites ,触摸空格键,然后点击回车。下划线到Create a new project ,然后点击回车键。给它一个独特的名字(如下图所示:mps-split-ang-crud )。为公共目录问题设置dist/<your local app name> 。
**注意:**这是你给你的angular项目的名字。在我的例子中,它被称为:my-crud-app 。后面的问题输入n 。关于这里描述的设置,请看下面的图片。
有了这些,你就准备好做第一次部署到Firebase了。首先,你要用Angular进行生产构建。
ng build --configuration production
Code language: Shell Session (shell)
在构建完成后,你会有一个dist文件夹,其中包含了生成的工件。该文件夹的内容就是你在部署应用程序时发送的内容。这就是为什么当Firebase问你想用什么作为你的公共目录时,你必须回答dist。
所以,为了部署你的公共目录的内容,你只需要运行一个简单的命令。
firebase deploy
Code language: Shell Session (shell)
如果你看到像下面这样的图片,你的部署就成功了。
你现在可以指向Firebase显示的URL,看到你的应用程序在线。
下一步是什么?自动化。
设置Travis CI
正如你所看到的,使用Firebase CLI来部署你的应用程序是非常容易的。然而,每次你想部署你的应用程序时都运行Firebase部署命令是不行的。让我们使用Travis CI来实现自动化。
首先去travis-ci.com/ ,用你的GitHub账户注册。然后你就可以看到你的GitHub仓库了。
下一步是前往 repo.new,在 GitHub 上启动一个新的仓库。然后回到终端,把你的 GitHub 仓库添加为远程仓库,并推送给它。
git remote add origin https://github.com/<your-user-name>/<your-repo-name>.git git push -u origin master
Code language: Shell Session (shell)
现在你离用Travis CI配置你的项目又近了一步。下一步是创建文件,以存储Travis CI的配置。因此,在你的版本库的根层,创建一个名为 .travis.yml 的文件,内容如下。
`language: node_js node_js:
- "12.14"
branches:
only:
- master before_script:
- npm install -g @angular/cli script:
- npm install
- npm run build deploy: skip_cleanup: true provider: firebase token: secure: ""`
Code language: YAML (yaml)
**注意:**由于良好的原因,GitHub 上新项目的默认分支是
main。然而,当分支的名称不是master,我很难让项目正常部署到Firebase。如果你知道如何在一个不同的分支上部署到Firebase,请告诉我们。
正如你所注意到的,这里少了一条信息:token。这是因为令牌是一个秘密数据,这意味着你不能把它作为纯文本放在那里。相反,你必须对它进行加密。
首先,你必须生成Firebase令牌,你可以通过运行以下命令来完成。
firebase login:ci
Code language: Shell Session (shell)
运行该命令后,你会看到一条信息:"成功!"。使用此令牌在CI服务器上登录:",后面是生成的令牌。
使用这里的说明安装Travis CLI。
注意:Travis正在将所有端点从travis-ci.org切换到travis-ci.com。仍然有一个免费层。Travis CLI仍然默认使用.org地址,所以下面的命令是为了确保CLI能够使用.com地址。
下一步是使用Travis CLI对该令牌进行加密。
travis encrypt --add deploy.token <YOUR-FIREBASE-TOKEN> --com
Code language: Shell Session (shell)
你可以先加密令牌,然后把生成的值粘贴到.travis.yml ,但上面的命令只用了一个步骤就完成了所有工作。
现在可以安全地提交了,所以这就是你要做的:提交你的.travis.yml 文件并将其推送到你的远程 repo。这将触发一个构建,你可以在travis-ci.org上跟踪其状态。构建成功后,就会触发部署。你可以通过访问Firebase来跟踪部署情况。
为你的Angular应用程序添加功能标志
你已经成功地使用Firebase主机和Travis CI配置了Angular应用程序的持续构建和部署。作为奖励,现在让我们看看如何向这个应用添加功能标志。
但首先要做的是:什么是特性标志,以及为什么你要关心这个问题?
什么是功能标志?
功能标志--也被称为功能切换器和功能翻转器,以及其他一些名称--是一种机制,允许你禁用和启用功能,而不需要改变代码和重新部署应用程序。这种能力是非常强大的,并且有许多使用案例。例如,你可以使用标志来推出一个新功能,只针对一小部分用户,以减轻其风险。同样,你可以使用标志来执行A/B测试,将你的用户群分成两组,并为每组提供不同版本的功能,以衡量用户的兴趣和反应。
然而,功能标记的影响比这要深得多。它更像是一个健全的CI/CD流程的推动者。采用功能标记,使开发人员可以自由地发送包含未完成功能的代码。然后,他们可以尽可能频繁地将代码合并到主仓库,以享受更短的反馈周期带来的好处。这是一个更接近于真正的持续集成的场景,而不仅仅是配置一些工具--注意,这些工具也是有价值和必要的。
开始使用Split
现在我们将快速向你展示如何向你的应用程序添加一个功能标志。你将模拟一个未完成的功能的部署。你会看到,通过保持功能的关闭,就不会有用户访问这种功能的风险。
从注册一个Split的永久免费账户开始。一旦你完成了,是时候获得你的API密钥了。登录到你的账户,点击左上角的工作区按钮--标有DE的那个--然后点击管理设置。
在新页面上,点击API密钥。
在下一个屏幕上,找到JavaScript SDK和暂存环境的密钥。
点击复制,并将密钥保存在安全的地方。
将Split的JavaScript SDK添加到你的Angular代码中
下一步,你需要安装Split的JavaScript SDK,这样你就可以通过查询Split来检查你的特性标志是否处于激活状态。回到终端,确保你在项目的文件夹内,然后运行这个。
npm install --save @splitsoftware/splitio-browserjs
Code language: Shell Session (shell)
提交添加到package.json文件中的修改。现在你可以进行下一步了。
对你的Angular代码进行修改
为了实现这个特性标志,你需要对代码进行一些修改。第一个改动是创建一个新的文件,作为Split解决方案的外墙。
运行:ng generate service splitio ,在angular应用程序中创建一个新的服务。
将以下代码粘贴在src/app/splitio.service.ts 。
``import { Injectable } from '@angular/core'; import { SplitFactory } from '@splitsoftware/splitio-browserjs'; import { fromEvent, Subscription } from 'rxjs';
@Injectable() export class SplitIoService {
splitio: SplitIO.ISDK;
splitClient: SplitIO.IClient;
isReady = false;
treatments: SplitIO.Treatments;
subscription: Subscription;
features: string[] = [
'include_phone'
];
isTreatmentOn(treatmentName: string) : boolean {
let treatment = this.splitClient.getTreatment(treatmentName);
let result = null;
if (treatment == 'on') {
result = true;
} else if (treatment == 'off') {
result = false;
} else {
result = false;
}
console.log(`Value of: ${treatmentName} is ${treatment}`);
return result;
}
initSdk(): void {
this.splitio = SplitFactory({
core: {
authorizationKey: '<your api key>',
key: 'customer-key'
}
});
this.splitClient = this.splitio.client();
this.verifyReady();
}
private verifyReady(): void {
const isReadyEvent = fromEvent(this.splitClient, this.splitClient.Event.SDK_READY);
this.subscription = isReadyEvent.subscribe({
next() {
this.isReady = true;
console.log('Sdk ready: ', this.isReady);
},
error(err) {
console.log('Sdk error: ', err);
this.isReady = false;
}
});
}
getTreatments(): void {
this.treatments = this.splitClient.getTreatments(this.features);
}
}``
Code language: JavaScript (javascript)
让我们来分析一下你刚刚创建的SplitIoService 。
initSdk获取Split客户端的设置。它使用你的SDK客户端密钥。它调用verifyReadyverifyReady使用jsx事件系统和Split的SDK_READY事件来表示SplitIoService已经准备好行动。isTreatmentOn接受一个字符串参数,即一个治疗的名称,并根据该治疗是on还是 ,返回一个布尔值。off
代码只剩下一个小改动。你将进入src/app/user/create/create.component.html 文件,并向其添加以下代码。
`<div *ngIf="splitService.isTreatmentOn('INCLUDE_PHONE')" class="form-group"> Phone:
`Code language: HTML, XML (xml)
*ngIf 从SplitIoService 中调用isTreatmentOn 函数,它决定是否呈现电话字段。
你已经完成了对代码的修改。现在让我们进入下一个步骤,它将再次把你带到Split的网站。
在Angular中创建你的第一个持续部署的特性标志
回到你的Split账户。点击Splits,然后点击Create Split。
你会被要求为你的分片取一个名字。这个名字必须与你在代码中使用的内容相匹配,所以就用 "INCLUDE_PHONE "吧。
在这之后,只剩下三个步骤。
- 点击 "添加规则"。
- 点击 "保存更改"。
- 最后,点击确认。
现在,你可以回到应用程序,创建一个新用户,并确认你没有看到电话字段。然后回到Split,激活该处理方法(将其从关闭切换到开启)。
如果你回到应用程序,并导航到创建一个新用户,你会看到新字段被显示出来。
了解更多关于JavaScript中的CI/CD
今天的文章提供了一个关于如何在Angular中开始使用CI/CD的指南。我们已经指导你如何设置部署到Firebase Hosting,然后使用Travis CI自动完成这一过程。作为奖励,我们向你展示了一个强大的技术,你可以应用它来改变你的应用程序在生产中的行为,而不需要编写代码和重新部署。
这个机制就是特征标记。正如你已经读到的,功能标记带来了很多好处。但最大的好处是:它们允许开发者无畏地、经常地将他们的工作合并到主线上,知道最终的用户将无法访问未完成的功能。
换句话说,功能标记是目前最有效的CI和CD的推动者之一。如果你想了解更多,我鼓励你去看看这些额外的资源。
- 功能交付释放速度、安全和商业影响
- 使用GitHub Actions和Heroku进行Node.js的持续部署
- 如何利用特性标记减少代码周期时间
- 15分钟内完成特性监控
- 用Netlify部署你的React应用
要想了解关于特性标记和现代CI/CD的最新信息,请在Twitter上关注我们@splitsoftware,并订阅我们的YouTube频道!