钥匙要点
>以较小的块整合代码,并以更频繁的方式集成代码,可以使开发团队更快地提出问题,并尽快为用户获取新功能。 CI还消除了对工程师团队需要保持清醒的任何大型版本的需求,直到夜晚的凌晨为止,以最大程度地减少对用户的干扰。
>以前,这意味着(可能)冗长且(绝对)的(绝对)痛苦的回滚过程,并在修复该错误的另一天,将发行版重新安排为另一个不敬虔的小时。取而代之的是,使用开关的切换,该功能可以全部或一部分用户关闭,并且疼痛消失了。一旦确定错误并修复了错误,就可以部署补丁发布,并且可以重新启用该功能。
概述我们的示例项目
>>不是从一开始就重复该教程,而是从一个基本的TIC-TAC-TOE游戏开始并运行。
在这一点上,我们将使用功能标志和远程配置来连续配置,推送和部署新功能。要将这个概念带到一个极端,我们将不断推动掌握。不会使用其他分支。我们将介绍一个错误(当然是故意的!),并将修复程序推向掌握,以演示如何处理这种情况不需要完整的回滚或其他分支。>
如果您想在本教程期间遵循编写代码,则可以在此处分配存储库。>
实现CI>自动化连续集成的最常见方法是在将更改更改为GIT存储库时具有构建过程触发。不同的构建工具以不同的方式实现这一目标。
>我们将使用Netlify将其用于我们的项目。 Netlify允许您连接GIT存储库,并在每次推到分支机构时自动部署构建。
在下一步中,配置NetLify如下运行应用程序。
浏览该URL应该以所有荣耀显示您的TIC TAC TOE游戏。
>为我们的项目设置功能标志
继续与我们继续前进,继续在子弹列车上创建一个免费帐户。单击“创建项目”按钮并创建您的项目。我们命名了我们的FF教程。
接下来,我们需要创建一个新功能来宣布获胜者。 单击下一个屏幕底部的“创建您的第一个功能”按钮,以列出以下表单并添加详细信息。
请注意,我们一直将功能禁用。
>实现功能标志
首先,让我们在我们的开发环境中运行该项目。从命令行导航到项目文件夹,然后运行命令NPM i以安装必要的依赖项。
>现在,我们将在现有代码中实现我们的新功能标志。让我们从为JavaScript安装子弹列车客户端首先,打开另一个命令行并在项目目录中运行以下内容:
>npm i子弹 - 训练 - 链接-Save
>>在您的首选编辑器中打开项目,并编辑./web/app.js。
找到计算温纳(正方形)函数。此功能根据是否可以找到相同形状的行确定是否有赢家。我们将根据我们的功能标志的值来使此函数返回null null,以便我们可以测试填充板而不声明获胜者。
在app.js的最高顶部,添加以下行:
现在,让我们初始化我们之前安装的子弹列车客户端。从子弹列车接口中的“功能”页面中复制所有代码示例2,然后将其粘贴在您刚刚添加的行之下。
>>代码段中的环境ID将是与子弹列车项目中的开发环境相关的正确环境ID。如果需要,可以通过浏览到“环境设置”页面进行检查。
>现在,我们需要在bullettrain.init()函数中编辑onChange()函数,以适应我们的需求。用一行替换其中的所有代码:
<span>var declareWinner = true; </span>
您现在应该将其放在app.js
的顶部declareWinner <span>= bulletTrain.hasFeature("declare-winner"); </span>
>向下滚动到计算Winner(正方形)函数,在顶部,在线路的声明上方,让我们添加行:
<span>var declareWinner = true; </span>import bulletTrain from "bullet-train-client"; //Add this line if you're using bulletTrain via npm bulletTrain.init({ environmentID:"", onChange: (oldFlags,params)=>{ //Occurs whenever flags are changed declareWinner <span>= bulletTrain.hasFeature("declare-winner"); </span> } });
>
>返回子弹列车管理员并使用右侧的开关切换功能。>刷新您的浏览器,游戏再次变得可赢。在此处查看此部分的末尾的代码。
提交并按下您的代码(是的,全部在主上),并且NetLify将自动部署您的代码。再次浏览您分配的NetLify URL,然后切换功能标志,以查看其在生产环境中工作。甜!
在错误上工作
>首先,让我们设置我们的功能标志以包装新功能。在您的子弹列车项目中,创建一个名为“ select-who-goes-Fir”的新功能,如下所示。让我们从一开始就禁用它。
现在,让我们添加我们的新功能。在Render()函数中,如果游戏尚未启动,我们将渲染按钮而不是状态。在Render()函数返回的顶部,替换行:
…带有以下代码:
>现在,我们想编写代码以使用我们创建的功能标志来控制我们的新功能。和以前一样,这需要进入bullettrain.init({...})函数。
<span>if (!declareWinner) return null; </span>
首先,让我们将生命周期函数componentDidmount()添加到板组件中,然后将整个BulletTrain.Init({...})函数移动到其中的内部,以便我们可以在标志之后更新组件的状态检索:
<span>var declareWinner = true; </span>
如果我们在组件之外留下Bullettrain.Init({...}),我们将无法调用this.setState(),并且使组件从更改的旗帜重新呈现。
>现在,让我们添加代码以控制我们的新功能。我们希望该应用程序像禁用标志之前那样添加此功能之前的应用程序。为此,如果禁用标志,让我们将所选的状态值设置为true。在bullettrain.init({...})方法中添加以下行,就在DeclareWinner行下方。
declareWinner <span>= bulletTrain.hasFeature("declare-winner"); </span>
>让我们继续前进(再次,直接进入主人)。建造后,前往您的Netlify URL。您应该看到什么都没有改变 - 这是因为该功能在我们的子弹列车项目中仍然是禁用的。
>前往子弹列车并启用该功能。
辉煌!现在我们可以看到它有效,但是哦,有一个错误!可以在不选择谁之前开始游戏。如果您这样玩游戏,您会发现状态永远不会设置为显示获胜者。那是不对的!
>返回子弹列车并禁用该功能,直到我们可以解决问题为止。这是子弹列车的其他功能(例如环境和用户)派上用场的地方。在本教程中,我们不会参与其中的任何一个,但是请查看文档以获取有关使用多个环境或控制功能的更多信息。
>返回我们的错误:我们还需要将另外一行添加到Handleclick()的顶部,以防止玩家启动,直到选择了第一个玩家为止。将以下内容添加在Handleclick()函数的顶部。
<span>var declareWinner = true; </span>import bulletTrain from "bullet-train-client"; //Add this line if you're using bulletTrain via npm bulletTrain.init({ environmentID:"", onChange: (oldFlags,params)=>{ //Occurs whenever flags are changed declareWinner <span>= bulletTrain.hasFeature("declare-winner"); </span> } });
在子弹列车中再次重新打开功能,并在本地环境中测试该功能,您应该看到我们现在可以防止游戏启动而不选择谁去。出色的!再次将其提交主人,然后将其直接推到部署。
>前往您的NetLify URL,您应该看到固定并正常工作的新功能。
>您可以在此处查看本节末尾的最终代码。
>>现在,我们将在功能标志(称为远程配置)上查看一些略有变化。远程配置允许您控制功能是否打开还是关闭,还可以控制不仅仅是一个不需要更改代码而远程更改给定值。例如,如果您想配置样式的某些方面。 在我们的教程中,我们将使用它来更改游戏中每个玩家使用的形状。让我们创建两个远程配置值,以便在板上使用哪些形状。在您的子弹列车项目中,单击“创建功能”按钮,但是这次,选择“远程配置”选项卡而不是“功能标志”。按照以下内容填写数据。
都完成了!现在返回代码。在我们的Bullet Train客户端的OnChange()函数中,我们需要检索这些值并将其设置为组件的状态。让我们更改我们的this.setState()呼叫:
><span>var declareWinner = true; </span>
>我们现在有两个形状,可以用状态值替换“ x”和“ o”的所有静态用途。每个形状应在handleclick()中每个形状1,呈渲染()中的每个形状有2个(一个是在返回的呼叫中)。这是handleclick()中的参考的更新代码:
>declareWinner <span>= bulletTrain.hasFeature("declare-winner"); </span>
请注意,对于redender()返回调用中的实例,您需要将JavaScript包裹在这样的卷曲括号中:
<span>var declareWinner = true; </span>import bulletTrain from "bullet-train-client"; //Add this line if you're using bulletTrain via npm bulletTrain.init({ environmentID:"", onChange: (oldFlags,params)=>{ //Occurs whenever flags are changed declareWinner <span>= bulletTrain.hasFeature("declare-winner"); </span> } });
>将其提交为主,然后推到GIT存储库,以查看NetLify URL上的更改。如果您做得正确,游戏应该像以前一样使用“ X”和“ O”形状。继续,将管理员中的形状更改为不同的字母,然后刷新页面。如果一切顺利,您现在将使用不同的形状。
>您可以通过远程配置来实现更多的目标,例如控制整个游戏的样式或说板的尺寸。我们添加了更多远程配置值,包括形状颜色和方形大小。您可以在此处查看游戏的完成代码。
>不应将功能标志视为金色子弹,但是它们确实带有某些警告。
例如,如果您使用的是为您(例如Django或Rails)处理数据库模式的框架,则在模型中实现功能标志时需要小心。在模型中使用功能标志可能会导致DB模式不匹配,这可能会使应用程序的一部分减少。同样,如果您正在与对其消费者具有某些要求的第三方API进行互动,则使用功能标志来控制此方面的方面可能会导致应用程序中的意外错误。另外,反之亦然,如果您的应用程序为其他人提供了API,请使用功能标志来控制API的数据模型,因为它可能会给这些消费者带来问题。
>最后,我们在上面的教程中使用了子弹列车,因为它目前可以免费使用和开源。还有许多其他产品在做同样的事情或略有不同的变体 - 您应该检查所有这些产品,以确定最适合您的东西。例如,启动黑暗和飞艇总部。
也称为功能切换,提供了一种在运行时隐藏,启用或禁用某些功能的方法。在连续整合中,它们提供了一些好处。首先,它们允许开发人员在不影响主代码库的情况下从事功能。这意味着,即使该功能未完全开发或测试,总体应用程序仍然保持稳定。其次,它们可以轻松测试生产环境中的功能。这对于A/B测试或金丝雀释放尤其有用。最后,它们提供了一种方法,可以在问题中快速禁用功能,而不必退缩整个部署。
>我可以使用功能标志来进行A/B测试吗?
>
>如何在大规模应用程序中管理功能标志?大规模应用可能具有挑战性。一种方法是使用功能标志管理系统。这些系统提供了定义和管理功能标志的中心位置,并且通常具有用户细分,A/B测试和分析等功能。另一种方法是将功能标志用作服务提供商。这些提供商为功能标志管理提供了托管解决方案,这对于大规模应用程序特别有用。>如何将功能标志用于金丝雀版本?
>如何测试功能标志?
>可以将功能标志用于逐渐推出吗?
以上是如何在连续集成中使用功能标志的详细内容。更多信息请关注PHP中文网其他相关文章!