乐趣区

关于android:你必须知道的-17-个-Composer-最佳实践已更新至-22-个

这是一篇社区协同翻译的文章,已实现翻译,更多信息请点击 协同翻译介绍。

只管大多数 PHP 开发人员都晓得如何应用 Composer,但并不是所有的人都在无效地或以最好的形式应用它。所以我决定总结一些对我日常工作流程很重要的货色。大部分技巧的理念是_「Play it safe」_,这意味着如果有更多的办法来解决某些事件,我会应用最不容易出错的办法。

Tip 1: 浏览文档

我是认真的。官网的文档 写得十分棒,当初只需几个小时的浏览,会给你将来节俭很多工夫。你会诧异于 Composer 如此之多能。

Tip 2: 意识 “ 我的项目 ” 和 “ 库 ” 间的不同

创立的是“我的项目”还是“库”,意识到这点十分重要。这两者在应用过程中,都存在十分微小的差别。

库是一个可重用的包,须要作为一个依赖项进行增加 – 比方 symfony/symfony, doctrine/ormelasticsearch/elasticsearch.

而典型的我的项目是一个应用程序,要依赖于多个库。它通常不可重用(其余我的项目不须要它成为一个依赖项)。像电子商务网站、客户服务零碎等类型的利用就是典型的例子。

在上面的 Tip 中,我会更认真地解说库和我的项目两者的区别。

Tip 3: 为应用程序应用指定的依赖版本

创立应用程序时,应应用最清晰的版本号定义依赖项。如果须要解析 YAML 文件,就应该以 "symfony/yaml": "4.0.2" 这样的模式明确依赖项。即便依赖的库遵循了 语义化版本 标准,也会因次版本号和订正号的不同毁坏后向兼容性。例如,应用形如 "symfony/symfony": "^3.1",有可能存在在 3.2 版本废除的货色,而这会毁坏你的应用程序在该版本下通过测试。或者可能在 PHP\_CodeSniffer 中存在一个已修复的 bug,代码就会检测出新的格局问题,这会再次导致谬误的构建。

依赖的降级要慎之又慎,不能撞大运。上面 Tip 当中会有一条对此进行更具体的解说。

听起来有些危言耸听,然而留神这个要点就会防止你的合作伙伴向我的项目中在增加新库时不小心更新了所有依赖(代码审查时可能疏忽这一点)。

Tip 4: 对库依赖项应用版本范畴

创立库时,应尽可能定义最大的可用版本范畴。比方创立了一个库,要应用 symfony/yaml 库进行 YAML 解析,就应这样写:`
“symfony/yaml”: “^3.0 || ^4.0”

这示意该库能从 Symfony 3.x 或 4.x 中任意版本中应用 `symfony/yaml`。这相当重要,因为这个版本束缚会传递给应用该库的应用程序。万一有两个库的申请存在抵触,比方一个要 `~3.1.0`,另一个须要 `~3.2.0`,则装置会失败。[![image](https://upload-images.jianshu.io/upload_images/27242968-98ca24f983e8ace0.image?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Fusers%2F12155 "https://laravel-china.org/users/12155")bigqiang 翻译于 1 周前 [0](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Ftranslations%2F7609%2Fsections%2F153%2Fvote "https://laravel-china.org/translations/7609/sections/153/vote") [重译](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Ftranslations%2Fsections%2F153 "https://laravel-china.org/translations/sections/153")

# Tip 5: 开发应用程序要提交 `composer.lock` 文件到 git 版本库中


创立了 _一个我的项目_,肯定要把 `composer.lock` 文件提交到 git 中。这会确保每一个人——你、你的合作伙伴、你的 CI 服务器以及你的产品服务器——所运行的应用程序领有雷同依赖的版本。乍一看有些画龙点睛,在 Tip #3 中曾经提过要应用明确的版本号的束缚了啊。这并不多余,要晓得你应用的依赖项的依赖项并不受这些束缚绑定(如 `symfony/console` 还依赖 `symfony/polyfill-mbstring`)。如果不提交 `composer.lock` 文件,就不会获取到雷同版本的依赖汇合。[![image](https://upload-images.jianshu.io/upload_images/27242968-085517b8e2d0e050.image?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Fusers%2F12155 "https://laravel-china.org/users/12155")bigqiang 翻译于 1 周前 [0](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Ftranslations%2F7609%2Fsections%2F154%2Fvote "https://laravel-china.org/translations/7609/sections/154/vote") [重译](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Ftranslations%2Fsections%2F154 "https://laravel-china.org/translations/sections/154")

Tip #6: 开发库要把 `composer.lock` 文件增加到 `.gitignore` 文件中
----------------------------------------------------

创立 _一个库_(比如说叫 `acme/my-library`),这就不应该把 `composer.lock` 文件提交到 git 库中了。该文件对应用该库的我的项目 It  [不会有任何影响](https://link.juejin.cn/?target=https%3A%2F%2Fgetcomposer.org%2Fdoc%2F02-libraries.md%23lock-file "https://getcomposer.org/doc/02-libraries.md#lock-file")。假如 `acme/my-library` 应用 `monolog/monolog` 作依赖项。你曾经在版本库中提交了 `composer.lock`,开发 `acme/my-library` 的每个人都可能在应用 Monolog 的老旧版本。该库开发实现后,在理论我的项目中应用该库,就可能存在装置的 Monolog 是一个新版本,而此时就会和该库存在不兼容。可是你在之前基本就不会留神到兼容问题就因为这个 `composer.lock`!因而,最佳解决形式就是把 `composer.lock` 增加到 `.gitignore` 文件中,这样就防止了不小心提交它到版本库中引发的问题。如果还想确保该库与它的依赖项的不同版本放弃兼容性,那持续浏览下一个 Tip![![image](https://upload-images.jianshu.io/upload_images/27242968-64a472f50df347eb.image?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Fusers%2F12155 "https://laravel-china.org/users/12155")

# Tip 7: Travis CI 构建依赖项的不同版本


> 以后 Tip 仅适宜库(对于应用程序要指明具体的版本号)。如果你在构建开源的库,很有可能你会应用 Travis CI 来跑构建过程。默认状况下,在 `composer.json` 文件束缚容许的条件下,composer 装置会装置依赖的最新可能版本。这就意味着对于 `^3.0 || ^4.0` 这样的依赖束缚,构建装置总是应用最新的 v4 版本发行包。而 3.0 版本基本不会测试,所构建的库就可能与该版本不兼容,你的用户要哭了。幸好,composer 为装置低版本依赖项提供了一个开关  `--prefer-lowest`(应应用 `--prefer-stable`,可阻止不稳固版本的装置)。已上传的 `.travis.yml` 配置相似上面的格局:```
language: php

php:
  - 7.1
  - 7.2

env:
  matrix:
    - PREFER_LOWEST="--prefer-lowest --prefer-stable"
    - PREFER_LOWEST=""

before_script:
  - composer update $PREFER_LOWEST

script:
  - composer ci

代码详见 my mhujer/fio-api-php library 及 the build matrix on Travis CI

尽管这解决了少数的不兼容问题,不过依然要记得,依赖项的最低和最高版本间有太多的组合。他们仍旧可能存在不兼容的状况。

Tip 8: 按名称对 require 和 require-dev 中的包排序

按名称对 requirerequire-dev 中的包排序是十分好的实际。这在衍合一个分支时能够防止不必要的合并抵触。如果你把一个包增加到两个分支文件中的列表开端,那每次合并都可能遇到抵触。手动进行包排序的话会很乏味,所以最好方法就是在 composer.json 中 配置一下 即可:`
{

"config": {"sort-packages": true},


}


当前再要 `require` 一个新的包,它会主动增加到一个正确地位(不会跑到尾部)。[![image](https://upload-images.jianshu.io/upload_images/27242968-61c883a85581fef9.image?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Fusers%2F12155 "https://laravel-china.org/users/12155")bigqiang 翻译于 1 周前 [0](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Ftranslations%2F7609%2Fsections%2F157%2Fvote "https://laravel-china.org/translations/7609/sections/157/vote") [重译](https://link.juejin.cn/?target=https%3A%2F%2Flaravel-china.org%2Ftranslations%2Fsections%2F157 "https://laravel-china.org/translations/sections/157")

# Tip 9: 进行版本衍合或合并时不要合并 `composer.lock` 
---------------------------------------

如果你在 `composer.json`(和 `composer.lock`)中增加了一个新依赖项,并且在该分支被合并前主分支中增加另一个依赖项,此时就须要对你的分支进行衍合解决。那么 `composer.lock` 文件就会失去一个合并抵触。千万别试图手动解决抵触,这是因为 `composer.lock` 文件蕴含了定义 `composer.json` 中依赖项的哈希值。所以即便你解决了抵触,这个最终合并后果的 lock 文件仍是谬误的。最佳计划应该这样做,用上面一行代码在我的项目根目录创立一个 `.gitattributes` 文件,它会通知 git 不要试图对 `composer.lock` 文件进行合并操作:```
/composer.lock -merge

举荐 Trunk Based Development 形式(罕用佳品,不会有错),应用长期的个性分支纠正这种问题。当你有个长期分支须要即时合并时,因而导致的 composer.lock 文件合并抵触的危险极小。你甚至能够仅仅为增加一个依赖项而创立分支,而后马上进行合并。

如果在衍合过程中 composer.lock 遇到合并抵触又当如何呢?应用主分支版本解决,这样仅仅批改 composer.json 文件即可(新增一个包)。而后运行 composer update --lock,就会把 composer.json 文件的批改更新到 composer.lock 文件中。当初把曾经更新的 composer.lock 文件提交到版本暂存区,而后持续衍合操作。

Tip 10: 理解 requirerequire-dev之间的区别


可能意识到 requirerequire-dev 模块之间的区别是十分重要的。须要运行在利用中或者库中的包都应该被定义在 require (例如:Symfony, Doctrine, Twig, Guzzle, …)中。如果你正在创立一个库,留神将什么内容定义为 require。因为这个局部的 每个依赖项同时也是应用了该库的利用的依赖。
开发应用程序 (或库) 所需的包应该定义在 require-dev (例如:PHPUnit, PHP\_CodeSniffer, PHPStan) 中。

Tip 11: 平安地降级依赖项


我想大家对如下事实存有共识:应该定期对依赖项降级。此处我想探讨的是依赖项的降级应该放在明处且慎之又慎,而不能是因其余活计的须要才棘手为之。如果在重构利用的同时又降级了库,那么就很难辨别利用解体的起因是重构还是降级带来的。

可用 composer outdated 命令查看哪些依赖项须要降级。追加一个 --direct(或 -D)参数开关是个聪慧之举,这只会查看 composer.json 指定的依赖项。还有一个 -m 参数开关,只查看次版本号的降级列表。

对每一个老版本的依赖项进行降级都要尊循如下步骤:

  1. 创立新分支
  2. composer.json 文件中更新该依赖项版本到最新版本号
  3. 运行 composer update phpunit/phpunit --with-dependencies(应用降级过的库替换 phpunit/phpunit
  4. 查看 Github 上库的版本库中 CHANGELOG 文件,查看是否存在重大变动。如果存在就降级应用程序
  5. 本地测试应用程序(应用 Symfony 的话还能在调试栏看到弃用正告)
  6. 提交批改(包含 composer.jsoncomposer.lock 及其他新版本失常运行所做的必要批改)
  7. 等 CI 构建完结
  8. 合并而后部署

有时须要一次降级多个依赖项,比方降级 Doctrine 或 Symfony。这种状况下,就要在降级命令中把他们全副列举进去:

composer update symfony/symfony symfony/monolog-bundle --with-dependencies

或者应用通配符降级所有指定命名空间的依赖:

composer update symfony/* --with-dependencies

这全都是很乏味的工作,但绝对于不小心降级依赖项而言,这提供了额定保障。

一个可承受的简捷形式就是一次降级所有 require-dev 中的依赖项(如果程序代码没有批改的话,否则还是倡议创立独立分支以便代码审查)。

Tip 12: 在 composer.json 中定义其余类型的依赖

除了定义库作为依赖项外,也以在这儿定义其余货色。

能够定义应用程序和库所反对的 PHP 版本:

"require": {"php": "7.1.* || 7.2.*",},

也能定义应用程序和库所须要的扩大。在尝试 docker 化本人的利用时,或是你的伙伴头一次设置应用环境时,这招超级实用。

"require": {
    "ext-mbstring": "*",
    "ext-pdo_mysql": "*",
},

(当 扩大版本不统一 时,版本号要用 *)。

Tip 13: 在 CI 构建期间验证 composer.json

composer.jsoncomposer.lock 该当始终放弃同步. 因而, 始终为他们放弃主动核查是一个好主见. 将此增加成为你的构建脚本的一部分将会确保 composer.lockcomposer.json 放弃同步:

composer validate --no-check-all --strict

Tip 14: 在 PHPStorm 中应用 Composer 插件

这里有一个 composer.json plugin for PHPStorm. 当手动批改 composer.json 时,插件会主动实现及执行一些验证.

如果你在应用其余 IDE (或者只是一个编辑器), 你能够应用 its JSON schema 设置验证.

Tip 15: 在 composer.json 中指明生产环境的 PHP 版本号

如果你和我一样,有时还 在本地环境跑 PHP 最新预释版本,那么就会处于降级依赖项的版本不能运行于生产环境的危险。当初我就在应用 PHP 7.2.0,也就意味着我装置的库可能在 7.1 版本中运行不了。如果生产环境跑的是 7.1 版本,装置就会失败。不过不必放心,有个非常简单的解决办法,在 composer.json 文件的config 局部指明生产环境的 PHP 版本号即可:

"config": {
    "platform": {"php": "7.1"}
}

别把它和 require 局部的设置搞混了,它的作用不同。你的利用就能够运行 7.1 或 7.2 版本下,而且同时指定了平台版本为 7.1(这意味着依赖项的降级版本要和 平台版本 7.1 放弃兼容):

"require": {"php": "7.1.* || 7.2.*"},
"config": {
    "platform": {"php": "7.1"}
}

Tip 16: 应用自有托管 Gitlab 上的公有包

举荐应用 vcs 作为版本库类型,并且 Composer 决定获取包的适合的办法。比方,从 Github 上增加一个 fork,应用它的 API 下载整个版本库的 .zip 文件,而不必克隆。不过对一个公有的 Gitlab 装置来讲会更简单。如果用 vcs 作版本库类型,Composer 会检测到它是个 Gitlab 类型的装置,会尝试应用 API 下载包(这要求有 API key。我不想设置,所以我只用 SSH 克隆装置了):首先指明版本库类型是 git

"repositories": [
    {
        "type": "git",
        "url": "git@gitlab.mycompany.cz:package-namespace/package-name.git"
    }
]

而后指明罕用的包:

"require": {"package-namespace/package-name": "1.0.0"}

Tip 17: 长期应用 fork 下 bug 修复分支的办法

如果在某个公共的库中找到一个 bug,并且在 Github 上本人的 fork 中修复了它,这就须要从本人的版本库里装置这个库,而不是官网版本库(要到修复合并且修复的版本释出才行)。

应用 内嵌别名 可轻松搞定:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/you/monolog"
        }
    ],
    "require": {
        "symfony/monolog-bundle": "2.0",
        "monolog/monolog": "dev-bugfix as 1.0.x-dev"
    }
}

能够通过 设置 path 作为版本库类型 在本地测试这次修复,而后再 push 更新版本库。

Tip 18:应用 prestissimo 减速你的包装置

Composer 有个 hirak/prestissimo 插件,通过该插件可能以并行的形式进行下载,从而进步依赖包的装置速度。

那么,这么好的货色,你当初该如何做?你仅仅须要马上全局装置这个插件,而后就能够主动地在所有我的项目中应用。

composer global require hirak/prestissimo

Tip 19: 当你不确定时,测试你的版本束缚

即便在浏览 the documentation 之后,书写正确的版本束缚在一些时候也是很辣手的. 侥幸的是, 这里有 Packagist Semver Checker 能够用来查看哪个本部匹配特定的束缚. 他不是仅仅的剖析版本束缚, 他从 Packagist 下载数据以来展现理论的公布版本. 查看 the result for symfony/symfony:^3.1.

查看其余 1 个版本

Tip 20: 在生产环境中应用应用权威类映射文件

应该在生产环境中 生成权威类映射文件。这会让类映射文件中蕴含的所有类疾速加载,而不用到磁盘文件系统进行任何查看。

能够在生产环境构建时运行以下命令:

composer dump-autoload --classmap-authoritative

Tip 21: 为测试配置 autoload-dev

你也不想在生产环境中加载测试文件(思考到测试文件的大小和内存应用)。这能够通过配置 autoload-dev 解决(与 autoload 类似):

"autoload": {
    "psr-4": {"Acme\\": "src/"}
},
"autoload-dev": {
    "psr-4": {"Acme\\": "tests/"}
},

Tip 22: 尝试 Composer 脚本

Composer 脚本是一个创立构建脚本的轻量级工具。对于这个,我有另文述及。

总结

如果你不批准某些观点且论述出你为什么不批准的意见(不要遗记标注 tip 的编号)我将很快乐。

本文中的所有译文仅用于学习和交换目标,转载请务必注明文章译者、出处、和本文链接
咱们的翻译工作遵循 CC 协定,如果咱们的工作有进犯到您的权利,请及时分割咱们。

作者:折叠椅
链接:https://juejin.cn/post/684490…
起源:稀土掘金
著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。

退出移动版