十一、最佳实践和惯例

本章将教您在其他开发人员中脱颖而出。这可以通过有风格地开发和执行本书中学习的策略,并遵循具体标准来实现。

代码版本控制最佳实践

随着时间的推移,您的应用程序将不断发展,并且在某个时刻,您会想知道您将如何使用任何微服务的 API。您可以将更改保持在最低限度,并对 API 的用户透明,也可以创建不同版本的代码。最好的解决方案是对代码(API)进行版本控制。

众所周知和常用的代码版本控制方法如下所示:

  • URL:在这种方法中,您将 API 的版本添加到请求的 URL 中。例如,https://phpmicroservices.com/api/v2/userURL 表示我们正在使用 API 的v2。在整本书的示例中,我们都使用了这种方法。
  • 自定义请求头:在这个方法中,我们不在 URL 中指定版本。相反,我们使用 HTTP 头来指定要使用的版本。例如,我们可以对https://phpmicroservices.com/api/user进行 HTTP 调用,但需要额外的头"api-version: 2"。在这种情况下,我们的服务器将检查 HTTP 头并使用 API 的v2
  • 接受头:此方法与前一种非常类似,但我们将使用Accept头,而不是使用自定义头。例如,我们将调用https://phpmicroservices.com/api/user,但我们的 Accept 标头将是"Accept: application/vnd.phpmicroservices.v2+json"。在本例中,我们表示需要版本 2,数据将在 JSON 上。

可以想象,在代码中实现版本控制的最简单方法是在 URL 中使用版本代码,但不幸的是,这并不是最好的选择。大多数开发人员认为对代码进行版本化的最好方法是使用 HTTP 报头来指定要使用的版本。我们的建议是使用最适合您的项目的方法。分析谁将使用您的 API 以及如何使用,您将发现需要使用的版本控制方法。

缓存最佳实践

缓存是一个可以存储时态数据的地方;它用于提高应用程序的性能。在这里,您可以找到一些小提示来帮助您使用缓存。

绩效影响

向应用程序中添加缓存层始终会对性能产生影响,您需要对此进行衡量。在应用程序中的何处添加缓存层并不重要。您需要测量影响,以了解新缓存层是否是一个好的选择。首先,在没有缓存层的情况下制定一些指标,一旦有了一些统计数据,就启用缓存层并比较结果。有时,您会发现缓存层的好处变成了一个地狱般的管理,以保持缓存运行。您可以使用我们在前几章中讨论的一些监视服务来监视性能影响。

句柄缓存未命中

缓存未命中是指请求未保存在缓存中,应用程序需要从服务/应用程序获取数据。确保您的代码可以处理缓存未命中和后续更新。要跟踪丢失缓存命中率,您可以使用任何监控软件,甚至是日志系统。

分组请求

尽可能多地对缓存请求进行分组。假设前端需要缓存服务器中的五个不同元素来呈现页面。您可以尝试将请求分组,而不是进行五次呼叫,从而节省一些时间。

假设您使用 Redis 作为缓存层,并希望在foobar变量中保存一些值。请看下面的代码:

    $redis->set('foo', 'my_value');
    /** Some code **/
    $redis->set('bar', 'another_value');

不必这样做,您可以在一个事务中完成两个集合:

    $redis->mSet(['foo' => 'my_value', 'bar' => 'another_value']);

前面的示例将在一次提交中完成这两个集合,从而节省一些时间并提高应用程序的性能。

要存储在缓存中的元素的大小

在缓存中存储大型项目比存储小型项目更有效。如果开始缓存小项目的负载,则总体性能将降低。在这种情况下,序列化大小、时间、缓存提交时间和容量使用将增加。

监视您的缓存

如果您已决定添加缓存层,请至少对其进行监视。保留缓存的一些统计信息将帮助您了解它的性能(缓存命中率)或是否达到其容量限制。大多数缓存软件都是稳定和健壮的,但这并不意味着如果不进行管理,就不会有任何问题。

仔细选择缓存算法

大多数缓存引擎支持不同的算法。每种算法都有自己的优点和问题。我们的建议是深入分析您的需求,不要使用您选择的缓存引擎的默认模式,直到您确定它是适合您的用例的正确算法。

绩效最佳实践

如果您正在阅读本书,可能是因为您对 web 开发感兴趣,而且在过去几年中,web 应用程序(如 API)性能的重要性变得越来越重要。以下是一些统计数据,让您了解:

  • 亚马逊几年前报告说,加载时间每增加 100 毫秒,他们的销售额就会下降 1%。
  • 谷歌发现,将页面大小从 100KB 减少到 80KB 会使他们的流量减少 25%。
  • 57%的在线消费者会在等待页面加载 3 秒钟后放弃网站。
  • 80%的放弃网站的人不会回来。大约 50%的人会告诉别人他们的负面经历。

正如你所见,你的应用程序的性能会影响你的用户甚至你的收入。在本节中,我们将为您提供一些技巧,以提高 web 应用程序的总体性能。

最小化 HTTP 请求

每个 HTTP 请求都有一个有效负载。因此,提高性能的一个简单方法是减少 HTTP 请求的数量。你需要在发展的每一个方面都牢记这一点。尽量减少对 API/后端中其他服务的外部调用。在前端,您可以合并文件以只处理一个请求。您只需要在请求数量和每个请求的大小之间保持平衡。

假设您的前端将其 CSS 拆分为几个不同的文件;您可以将它们组合成一个或几个文件,而不是每次都加载每个文件。

对于 HTTP 请求,您可以做的另一个快速而微小的改变是尽量避免 CSS 文件中的@import函数。使用链接标签而不是@import功能将允许您的浏览器并行下载 CSS 文件。

最小化 HTML、CSS 和 JavaScript

作为开发人员,我们尝试以一种更易于阅读的格式编写代码——一种人性化的格式。通过发展这种方式,我们正在用不必要的字符增加纯文本文件的大小。不必要的字符可以包括空格、注释和换行符。

我们不是说您需要编写模糊代码,但是一旦您准备好了所有内容,为什么不删除不重要的字符呢?

假设您的一个 JavaScript 文件(myapp.js的内容如下:

    /**
    * This is my JS APP
    */
    var myApp = {
      // My app variable
      myVariable : 'value1',

      // Main action of my JS app
      doSomething : function () {
        alert('Doing stuff');
      }
    };

最小化后,您的代码可以保存到不同的文件(myapp.min.js中),如下所示:

    var myApp={myVariable:"value1",doSomething:function()
      {alert("Doing stuff")}};

在新代码中,我们将文件大小减少了 60%左右,这是一个巨大的节省。请注意,我们的存储库将有两个版本的文件:一个是便于进行更改的人性化版本,另一个是最小化版本,我们将加载到前端。

您可以使用在线工具进行最小化,也可以将gulpgrunt等工具集成到您的管道中。设置这些工具后,它们将跟踪某些特定文件(CSS、JS 和其他文件)的更改,一旦您将更改保存到这些文件中的任何一个,该工具将最小化内容。使用缩小工具的另一个隐藏的好处是,大多数工具还检查代码或重命名变量以使其更小。

图像优化

在 web 开发中最常用的资产之一就是图像。它们会让你的网站看起来很棒,但也会让你的网站慢得令人痛苦。主要的建议是将图像数量保持在最小,但如果需要保留图像,至少在将图像发送给用户之前尝试对其进行优化。在本节中,我们将向您展示一些可以优化图像的方法,从而优化应用程序的性能。

使用精灵

精灵是由多个图像组成的图像;稍后,您可以使用此图像并仅显示您感兴趣的部分。假设你有一个很好的网站,在每个页面上都有一些社交图标(Facebook、Twitter、Instagram 等等)。您可以将它们组合成一个,并使用 CSS 仅显示每个图标所需的部分,而不是每个社交图标都有一个图像。这样做,您将只需一次加载所有社交图标,从而减少请求数量。

我们的建议是保持你的精灵小,只包括最常用和共享的图像在其中。

使用无损图像压缩

并非所有图像格式都适合 Web,因为有些格式太大或不支持压缩。目前网络上最常用的三种图像类型如下:

  • JPG:这是最常用的无损压缩方法之一
  • PNG:这是最好的无损数据压缩格式
  • GIF:这是一种老式的格式,支持每张图像每像素最多 8 位,并以其动画效果而闻名

目前推荐的网页格式为PNG。它受到浏览器的良好支持,易于创建,支持压缩,并为您提供最大限度地提高站点性能所需的所有功能。

缩放图像

如果您使用的是图像而不是数据 URI,则应按原始大小发送它们。您应该避免使用 CSS 调整图像大小,并将正确大小的图像发送到浏览器。建议使用 CSS 缩放图像的唯一情况是使用流体图像(响应性设计)。

您可以使用像 Imagick 或 GD 这样的 PHP 库轻松地缩放图像。使用这些库和几行代码,您可以在几秒钟内缩放图像。通常,您不会动态缩放图像。大多数情况下,一旦图像上传到应用程序,一个批处理过程就会处理该图像,从而创建应用程序所需的不同大小。

想象一下,你可以将任何大小的图像上传到你的应用程序中,你只在前端显示最大宽度为350px 的图像。您可以使用 Imagick 轻松缩放以前存储的图像:

    $imagePath = '/tmp/my_uploaded_image.png';
    $myImage   = new Imagick($imagePath);

    $myImage->resizeImage(350, 0, Imagick::FILTER_LANCZOS, 1);

    $myImage->writeImage('/tmp/my_uploaded_image_350.png');

前面的代码将加载my_uploaded_image.png文件,并使用 Lanczos 过滤器将图像的宽度调整为350px(请参阅 PHP Imagick 文档以查看您可以使用的所有可用过滤器)。

这是一种方法,另一种(可能更有效)常用的方法是按需调整图像大小(即,当第一次从客户端请求时),然后将调整大小的图像存储在缓存或永久存储器中。

使用数据 URI

另一种减少 HTTP 请求数量的快速方法是将图像嵌入为数据 URI。这样,您将在代码中将图像作为字符串,避免图像请求,这种方法最适合静态页面。生成此类 URI 的最佳方法是使用外部或在线工具。

以下示例将向您展示它在 HTML 中的外观:

    <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgA..."
     alt="My Image">

缓存、缓存和更多缓存

Web 上的性能就是尽可能快地提供数据,如果我们的应用程序已经发送了仍然有效的数据,为什么还要再次发送呢?默认情况下,现代浏览器试图减少对同一站点的请求数量,因此在内部缓存中保留一些资产/资源的副本,以备将来使用。由于这种行为,如果您正在浏览网站,我们不会在您在各个部分之间移动时一次又一次地尝试加载所有资产。

您可以使用以下Cache-ControlHTTP 头帮助浏览器指定每个请求-响应:

  • 最大年龄=【秒】:设置响应被视为最新的最长时间。此指令与请求的时间相关。
  • s-maxage=[seconds]:这类似于 max age,但用于共享缓存。
  • public:此标签将响应标记为可缓存。
  • 私有:此标签允许您存储对一个用户的响应。不允许共享缓存存储响应。
  • 无缓存:此标签指示缓存将请求提交给原始服务器进行验证。
  • 无存储:此标签指示缓存不保留响应的副本。
  • 必须重新验证:这个标签告诉缓存,它们必须遵循您提供给它们的关于响应的任何新信息。
  • 代理重新验证:类似于必须重新验证,但用于代理缓存。

主要建议是对长期资产进行至少一周或一天到期的静态资产标记。对于经常变动的资产,建议将到期时间设置为几天或更短。根据资产的使用寿命调整其缓存过期日期。

假设你有一个每 6 小时改变一次的图像;在这种情况下,您不应该将到期日期设置为一周,最好的选择是大约 6 小时。

避免不良请求

没有什么比坏请求更烦人的了,因为这种请求会大大降低应用程序的性能。您可能知道,浏览器可以同时为同一主机管理的并发连接数量有限。如果您的网站发出大量请求,此连接可用插槽列表可能已满,其余请求将排队。

假设您的浏览器最多可以管理 10 个并发连接,而您的 web 应用程序发出 20 个请求。并非所有请求都可以同时处理,其中一些请求已排队。如果您的应用程序试图获取一项资产,但该资产不存在,现在会发生什么情况?在这种情况下,浏览器将浪费时间(和时间)等待提供不存在的资产,但这种情况永远不会发生。

作为一项建议,请密切关注浏览器开发人员工具(一组内置于浏览器中的 web 调试工具,可用于调试和评测网站)。这些工具允许您发现有问题的请求,甚至可以检查每个请求所用的时间。在大多数浏览器中,您可以按F12键打开嵌入式开发工具,但如果您的浏览器没有按此键打开工具,请查看浏览器的文档。

使用内容交付网络(CDN)

内容交付网络将您的资产的副本托管在服务器中,这些服务器设计用于快速响应,并尽可能从最近的服务器进行响应。这样,如果将请求从服务器移动到 CDN 服务器,web 服务器将处理更少的请求,从而提高应用程序的性能。

假设您在前端使用 jQuery;如果更改代码以从官方 CDN 加载库,则用户在浏览器缓存中拥有库的可能性会增加。

我们的主要建议是至少对 CSS、JavaScript 和图像使用 CDN。

依赖关系管理

在项目中可以使用多个 PHP 库、框架、组件和工具。直到几年前,PHP 还没有管理项目依赖关系的现代方法。现在我们有了 Composer,这是一个灵活的项目,它被转换为依赖关系管理的事实标准。

您可能对 Composer 很熟悉,因为我们在整本书中都在使用此工具在vendor文件夹中安装新库。此时,您将想知道是否应该提交vendor文件夹的依赖项。没有快速响应,但一般建议是否定的,您不应该将vendor文件夹提交到您的存储库。

提交供应商文件夹的主要缺点总结如下:

  • 增加存储库的大小
  • 复制依赖项的历史记录

正如我们之前告诉您的,不承诺供应商是主要建议,但如果您确实需要这样做,以下是一些建议:

  • 使用标记的版本(无开发版本),以便 Composer 获取压缩的源代码
  • 在配置文件中使用--prefer-dist标志或将preferred-install设置为dist
  • /vendor/**/.git规则添加到您的.gitignore文件中

语义版本控制

在启动的任何项目中,都应该在主分支上使用语义版本控制。语义版本控制是一组规则,您可以按照这些规则在版本控制软件中标记应用程序的代码。通过遵循这些规则,您将随时了解生产环境的当前状态。在代码中使用标记的另一个好处是,它允许我们在不同版本之间移动,或者以简单快捷的方式进行回滚。

源代码带有发布标记的另一个优点是,它允许您使用发布分支,使您能够更好地规划和控制对代码所做的更改。

语义版本控制是如何工作的

在语义版本控制方面,您的代码用带有vX.Y.Z表单的标记进行标记,这表示您代码的版本。您的标签上的每一块都有以下含义:

  • X(专业):此版本号增加表示有较大变化;它们非常重要,与当前版本不兼容
  • Y(小调):此版本号的增加表示我们正在为项目添加新功能
  • Z(补丁):此版本号中的增量表示我们在您的源代码中添加了补丁

发布标签的实现通常由将代码推送到生产环境的开发人员完成。请记住在部署代码之前更新发布标签。

语义版本控制在起作用

假设您从其他人的项目开始,主分支被标记为v1.2.3。让我们看一些例子。

我们被告知要在项目中添加新功能

在现场项目中工作会导致收到新功能的申请。在本例中,我们显然是在处理次要版本号的增量,因为我们正在添加与实际基本代码不兼容的新代码。在我们的情况下,如果我们的主分支在v1.2.3上,新版本标签将是v1.3.0。我们增加了次要版本号,而且,我们重置了补丁号,因为我们正在添加新代码。

我们被告知我们的项目中有一个漏洞

在日常工作中,您将修复代码中的错误。在这种情况下,我们正在处理一个小的变化,主要功能是解决我们的问题,所以我们需要增加补丁版本。在我们的示例中,如果当前生产版本为v1.2.3,则新版本标签将为v1.2.4。我们只是增加了补丁数量,因为我们的修复并不意味着其他更大的更改。

我们被要求做一个大的改变

想象一下,现在有人要求我们对源代码进行重大更改;一旦我们应用了更改,源代码的某些部分将与以前的版本不兼容。例如,假设您正在使用library_a,而我们改为使用library_b,它们是相互排斥的。在这种情况下,我们正在处理一个非常大的变化,这表明我们需要增加我们的主要版本号,同时,我们还需要重置次要版本号和补丁号。例如,如果我们的生产代码标记为v1.2.3,则应用更改后的新版本代码将为v2.0.0

如您所见,执行语义版本控制将有助于保持源代码的整洁,并且仅通过查看版本号就可以更容易地知道正在进行哪种代码更改。

错误处理

当我们因为在应用程序执行过程中发生了什么而抛出异常时,我们应该向用户或消费者提供更多关于发生了什么的信息。这可以通过添加可描述的标准代码(也称为状态代码)实现。在回答中使用这些标准代码将帮助您(和您的同事)快速了解应用程序中是否出现问题。检查以下列表,了解在 API 中使用它们的正确和最常见的 HTTP 状态代码。

客户端请求成功

如果应用程序需要通知 API 客户端请求已成功,则通常会使用以下 HTTP 状态代码之一进行回复:

  • 200-好:请求成功完成
  • 201-已创建:成功创建客户端指定的 URI
  • 202-已接受:已接受处理,但服务器尚未完成处理
  • 204-无内容:请求已完成,响应中未返回任何信息

请求已重定向

当应用程序需要答复通知请求已重定向的请求时,您将使用以下 HTTP 状态代码之一:

  • 301-永久移动:请求的资源在服务器上不存在。将位置标头发送到客户端,以将其重定向到新 URL。客户端在将来的请求中继续使用新的 URL。
  • 302-临时移动:请求的资源已临时移动。将位置标头发送到客户端,以将其重定向到新 URL。客户端在将来的请求中继续使用旧 URL。
  • 304-未修改:用于响应If-Modified-Since请求头。它表示请求的文档自指定日期以来未被修改,客户端应使用缓存副本。

客户请求不完整

如果需要发送给 API 客户端的信息与不完整或错误的请求有关,则将返回以下 HTTP 代码之一:

  • 400-错误请求:服务器检测到客户端请求中存在语法错误。
  • 401-未授权:请求需要用户认证。服务器发送 WWW Authenticate 标头以指示所请求资源的身份验证类型和领域。
  • 402-需要付款:这是为将来预留的。
  • 403-禁止:禁止访问请求的资源。客户端不应重复该请求。
  • 404-未找到:请求的文档在服务器上不存在。
  • 405-不允许方法:客户使用的请求方法不可接受。服务器发送Allow报头,说明哪些方法可以访问请求的资源。
  • 408-请求超时:客户端无法在服务器使用的请求超时时间内完成请求。但是,客户端可以重新请求。
  • 410-消失:请求的资源已从服务器永久消失。
  • 413-请求实体太大:服务器拒绝处理请求,因为其消息体太大。服务器可以关闭连接以阻止客户端继续请求。
  • 414-请求 URI 过长:服务器拒绝处理请求,因为指定的 URI 过长。
  • 415-不支持的媒体类型:服务器拒绝处理请求,因为它不支持消息体的格式。

服务器错误

如果应用程序不幸需要通知 API 客户端存在问题,您将返回以下 HTTP 代码之一:

  • 500-内部服务器错误:服务器配置设置或外部程序导致错误。
  • 501-未实现:服务器不支持满足请求所需的功能。
  • 502-坏网关:服务器遇到来自上游服务器或代理的无效响应。
  • 503-服务不可用:该服务暂时不可用。服务器可以发送一个Retry-After报头,指示服务何时可以再次可用。
  • 504-网关超时:网关或代理已超时。

编码实践

代码是应用程序的核心;因此,您需要正确、干净、高效地编写它。在本节中,我们将为您提供一些改进代码的提示。

处理字符串

行业标准之一是在所有应用程序级别中使用 UTF-8 格式。如果您跳过此建议,您将在项目的整个生命周期中处理编码问题。在写这本书的时候,PHP 不支持低级别的 Unicode,所以在处理字符串时需要小心,特别是 UTF-8。以下建议仅适用于使用 UTF-8 的情况。

在 PHP 中,基本的字符串操作(如赋值或连接)在 UTF-8 中不需要任何特殊的东西;在其他情况下,可以使用核心函数处理字符串。大多数情况下,这些函数都有对应的(前缀为mb_*)来处理 Unicode。例如,在 PHP 核心中,您可以找到substr()mb_substr()函数。无论何时使用 Unicode 字符串操作,都必须使用多字节函数。假设您需要获取 UTF-8 字符串的一部分;如果您使用substr()而不是mb_substr(),则很有可能获得您不期望的结果。

单引号与双引号

PHP 不会解析单引号字符串,因此不管字符串中包含什么,PHP 都会返回未更改的字符串。对于双引号字符串,PHP 引擎将对其进行解析,并对字符串中的任何变量进行求值。对于双引号字符串,还将计算转义字符(例如 t 或 n)。

在实际应用中,使用一种或另一种的性能差异可能会被忽略,但在高负载应用中,性能可能会有所不同。我们的建议是一致的,如果需要计算变量和转义字符,则只使用双引号。在任何其他情况下,请使用单引号。

空格与制表符

使用空格的开发人员和使用选项卡将代码制表的开发人员之间存在着一场战争。每种方法都有各自的优点和不便之处,但 PHP FIG 建议使用四个空格。仅使用空间可以避免差异、面片、历史记录和注释方面的问题。

正则表达式

在 PHP 中,有两个选项可以编写正则表达式:PCRE 和 POSIX 函数。主要建议使用 PCRE 函数(前缀为preg_*),因为 PHP5.3 中已经不推荐使用 POSIX 系列函数。

对数据库的连接和查询

在 PHP 中有多种连接数据库的方法,但在所有这些方法中,推荐的连接方法是使用 PDO。使用 PDO 的好处之一是它有一个标准接口,可以连接到多个不同的数据库,允许您更改数据存储而不会出现太多问题。在对数据库进行查询时,如果不想出现任何问题,请确保始终使用准备好的语句。这样,您将避免大多数 SQL 注入攻击。

使用===运算符

PHP 是一种松散类型的编程语言,在比较变量时,这种灵活性附带了一些注意事项。如果使用===运算符,PHP 将确保进行严格的比较并避免误报。请注意,===is_null()is_bool()功能稍快。

使用释放分支

一旦我们有了遵循语义版本控制的项目,我们就可以开始使用版本控制系统中的发布和发布分支,例如 Git。使用发布和发布分支可以让我们更好地规划和组织代码中的更改。

使用版本的工作是基于语义版本控制的,因为每个版本分支都将从主版本创建,通常从具有标记的最新主版本(例如 v1.2.3)创建。

使用发布分支的主要好处如下所示:

  • 帮助您遵循严格的方法将代码推向生产环境
  • 帮助您轻松规划和控制对代码所做的更改
  • 尝试避免将不需要的代码拖到生产环境中的常见问题
  • 允许您阻止特殊分支,如 dev 或 stage,以避免在没有拉请求的情况下提交

请注意,这只是一项建议;每个项目都不同,此工作流可能不适合您的项目。

快速示例

要在项目中使用版本,您需要使用一个发布分支和另一个临时分支,在其中对代码进行更改。对于下面的示例,假设我们的项目将主分支标记为 v1.2.3。

第一步是检查我们是否已经有了一个发布分支,我们将针对它工作。如果不是这样,则需要从主控创建一个新的:

  • 首先,我们需要决定下面的版本号;我们将使用从语义版本控制中学到的所有知识。
  • 一旦我们知道了下面的版本号,我们将从 master 创建一个发布分支。下一个命令将显示如何获取最新的主分支,以及如何创建和推送新的发布分支:

    ```php git checkout master git fetch git pull origin master git checkout -b release/v1.3.0 git push origin release/v1.3.0

    ```

  • 在前面的步骤之后,我们的存储库将使我们的发布分支干净并准备好使用。

现在,我们已经准备好了发布分支。这意味着任何代码修改都将在从发布分支创建的临时分支中完成:

  • 假设我们需要向项目中添加一个新特性,因此我们需要从发布分支创建一个临时分支:

    ```php git checkout release/v1.3.0 git fetch git pull origin release/v1.3.0 git checkout -b feature/my_new_feature

    ```

  • 一旦我们有了feature/my_new_feature,我们就可以将所有更改提交给这个新分支。一旦我们的所有更改都提交并准备就绪,我们就可以将我们的feature/my_new_feature与发布分支合并。

上述步骤可以重复任意次数,直到完成为发布计划的所有任务。

完成所有发布任务并批准所有更改后,可以将发布分支与 master 合并。完成与 master 的合并后,请记住更新 release 标记。

我们可以用以下提醒注释总结我们的示例:

  • 新的发布分支总是从主版本创建的
  • 时间分支总是从发布分支创建的
  • 尽量避免将其他时态分支与当前时态分支合并
  • 尽量避免将非计划分支与发布分支合并

在前面的工作流中,我们建议使用以下分支前缀来了解与分支关联的更改类型:

  • release/*:此前缀表示所有包含的更改将以相同的版本号部署在未来版本中
  • feature/*:此前缀表示添加到分支的任何更改都是新功能
  • hotfix/*:此前缀表示包含的更改已提交以修复错误/问题

以这种方式工作,将不需要的代码推送到生产环境将更加困难。可以根据您的需要随意调整前面的工作流。

总结

在本章中,我们向您介绍了一些您可以在项目中使用的常见最佳实践和约定。这些都是建议,但它们有助于从其他项目中脱颖而出。