Composer可以选择只在开发过程中加载几个依赖项,因此这些工具不会在生产中安装(在实时服务器上)。这(理论上)对于只有在开发中才有意义的脚本来说非常方便,比如测试、假数据工具、调试器等。
方法是使用dev:中所需的工具添加一个额外的require-dev
块
"require-dev": {
"codeception/codeception": "1.6.0.3"
}
然后(理论上)通过加载这些依赖关系
composer install --dev
问题&问题:
Composer在2013年极大地改变了install
和update
的行为,现在默认安装了require-dev
-依赖项(!),可以随意创建一个带有require-dev
块的Composer.json,并执行composer install
来进行复制。
因为最被接受的部署方式是推送composer锁定(保存当前的composer设置),然后在生产服务器上执行composer install
,这也将安装开发人员。
在不安装-dev依赖项的情况下部署的正确方法是什么?
注意:我试图在这里创建一个规范的Q/a,以澄清奇怪的Composer部署。请随意编辑此问题
为什么
IMHO是Composer现在默认使用--dev
标志(在安装和更新时)的一个很好的理由。Composer主要在场景中运行,其中这是所需的行为:
Composer的基本工作流程如下:
- 一个新项目开始了:
composer.phar install --dev
、json和锁文件被提交到VCS - 其他开发人员开始着手这个项目:签出VCS和
composer.phar install --dev
- 开发人员添加依赖项:
composer.phar require <package>
,如果您想在require-dev
部分中添加包,请添加--dev
(并提交) - 其他人也有:(结账和)
composer.phar install --dev
- 开发人员需要更新版本的依赖项:
composer.phar update --dev <package>
(和提交) - 其他人也有:(结账和)
composer.phar install --dev
- 项目已部署:
composer.phar install --no-dev
正如您所看到的,--dev
标志的使用(远远)多于--no-dev
标志,尤其是当项目开发人员的数量增加时。
生产部署
在不安装";dev";依赖关系?
好吧,composer.json
和composer.lock
文件应该提交给VCS。不要忽略composer.lock
,因为它包含有关应该使用的包版本的重要信息。
执行生产部署时,可以将--no-dev
标志传递给Composer:
composer.phar install --no-dev
composer.lock
文件可能包含有关开发包的信息。这并不重要。--no-dev
标志将确保未安装这些开发包。
当我说";生产部署";,我指的是旨在用于生产的部署。我并不是在争论composer.phar install
是应该在生产服务器上完成,还是应该在可以查看内容的临时服务器上完成。这不是这个答案的范围。我只是指出如何在不安装"CCD_;dev";依赖关系。
偏离主题
--optimize-autoloader
标志在生产中可能也是可取的(它生成一个类映射,可以加快应用程序中的自动加载):
composer.phar install --no-dev --optimize-autoloader
或者当自动部署完成时:
composer.phar install --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --optimize-autoloader
如果你的代码库支持它,你可以把--optimize-autoloader
换成--classmap-authoritative
。更多信息点击这里
实际上,我强烈建议不要在生产服务器上安装依赖项
我的建议是在部署机器上签出代码,根据需要安装依赖项(这包括如果代码进入生产环境,则不安装开发依赖项),然后将所有文件移动到目标机器。
为什么?
- 在共享主机上,您可能无法访问命令行
- 即使你这样做了,PHP也可能在命令、内存或网络访问方面受到限制
- 存储库CLI工具(Git、Svn)可能不会安装,如果您的锁文件记录了签出某个提交的依赖项,而不是将该提交下载为ZIP,则会失败(您使用了--preferred source,或者Composer没有其他方法来获取该版本)
- 如果您的生产机器更像一个小型测试服务器(想想AmazonEC2微实例),那么可能甚至没有足够的内存来执行
composer install
- 当composer试图不破坏东西时,你对以一个部分破坏的制作网站结束有什么感觉,因为在composer安装阶段无法加载一些随机依赖项
长话短说:在您可以控制的环境中使用Composer。您的开发机器确实合格,因为您已经拥有运行Composer所需的所有东西。
在不安装-dev依赖项的情况下部署它的正确方法是什么
要使用的命令是
composer install --no-dev
这将在任何环境中工作,无论是生产服务器本身,还是部署机器,或者应该进行最后检查以确定是否有任何开发需求被错误地用于实际软件的开发机器。
该命令不会安装或主动卸载composer.lock文件中声明的开发需求。
如果您不介意在生产服务器上部署开发软件组件,那么运行composer install
也可以完成同样的工作,只需增加移动的字节数,还可以创建更大的自动加载器声明。
现在默认启用require-dev
,对于本地开发,您可以在不使用--dev
选项的情况下执行composer install
和composer update
。
当您想部署到生产环境中时,您需要确保composer.lock
没有任何来自require-dev
的包。
你可以用做到这一点
composer update --no-dev
一旦使用--no-dev
进行了本地测试,就可以将所有内容部署到生产环境中,并基于composer.lock
进行安装。您需要在此处再次使用--no-dev
选项,否则composer会说"锁定文件不包含所需的dev信息">。
composer install --no-dev
注意:小心任何可能在开发和生产之间引入差异的东西!我通常尽量避免需要开发,因为包括开发工具并不是很大的开销。
我认为自动化流程更好:
在git存储库中添加composer.lock文件,确保在发布时使用composer.phar install--no dev,但在您的开发机器中,您可以毫无顾虑地使用任何composer命令,这将不会进入生产,生产将其依赖项建立在锁定文件中。
在服务器上签出此特定版本或标签,并在替换应用程序之前运行所有测试,如果测试通过,则继续部署。
如果测试依赖于开发依赖项,因为composer没有测试范围依赖项,那么一个不太优雅的解决方案可以使用开发依赖项运行测试(composer.phar install),删除供应商库,再次运行composer.phan install--no dev,这将使用缓存的依赖项,因此速度更快。但如果你知道其他构建工具中作用域的概念,那就是破解
自动化这件事,忘记剩下的,去喝杯啤酒:-)
PS.:正如下面的@Sven评论中所说,不签出composer.lock文件不是一个好主意,因为这将使composer安装作为composer更新工作。
你可以用http://deployer.org/这是一个简单的工具。
在生产服务器上,我将vendor
重命名为vendor-<datetime>
,在部署期间将有两个供应商目录。
HTTP cookie使我的系统选择新的供应商autoload.php
,在测试后,我在它们之间进行完全原子/即时切换,以针对未来的所有请求禁用旧的供应商目录,然后在几天后删除以前的目录。
这避免了我在apache.php中使用的文件系统缓存所引起的任何问题,也允许任何活动的php代码继续使用以前的供应商目录
尽管其他答案建议不要这样做,但我个人在服务器上运行composer install
,因为这比从我的暂存区(笔记本电脑上的虚拟机)进行rsync更快。
我使用--no-dev --no-scripts --optimize-autoloader
。您应该阅读每一个文档,以检查这是否适合您的环境。