跳转到内容

供应商二进制文件和`vendor/bin`目录

Composer 包希望传递给安装该包的用户的任何命令行脚本都应列为供应商二进制文件。

如果一个包包含包用户不需要的其他脚本(如构建或编译脚本),则该代码不应被列为供应商二进制文件。

它是通过向项目的composer.json中添加bin键来定义的。它被指定为一个文件数组,因此可以为任何给定的项目添加多个二进制文件。

{
"bin": ["bin/my-script", "bin/my-other-script"]
}

在composer.json中定义供应商二进制文件有什么作用?

Section titled “在composer.json中定义供应商二进制文件有什么作用?”

它指示Composer将包的二进制文件安装到vendor/bin目录,供任何依赖该项目的项目使用。

这是一种便捷的方式,可以公开那些原本会深藏在vendor/目录中的有用脚本。

当在定义了供应商二进制文件的composer.json上运行Composer时会发生什么?

Section titled “当在定义了供应商二进制文件的composer.json上运行Composer时会发生什么?”

对于包直接定义的二进制文件,不会发生任何事情。

当在包含带有列出的供应商二进制文件的依赖项的composer.json上运行Composer时,会发生什么情况?

Section titled “当在包含带有列出的供应商二进制文件的依赖项的composer.json上运行Composer时,会发生什么情况?”

Composer 会查找所有依赖项中定义的二进制文件。每个依赖项的二进制文件会生成一个代理文件(在 Windows/WSL 上为两个)到 vendor/bin 目录。

假设包my-vendor/project-a的二进制文件是这样设置的:

{
"name": "my-vendor/project-a",
"bin": ["bin/project-a-bin"]
}

对这个composer.json运行composer install不会对bin/project-a-bin产生任何影响。

假设项目my-vendor/project-b的需求设置如下:

{
"name": "my-vendor/project-b",
"require": {
"my-vendor/project-a": "*"
}
}

运行composer install时,此composer.json会查看project-a的所有二进制文件,并将它们安装到vendor/bin

在这种情况下,Composer会将vendor/my-vendor/project-a/bin/project-a-bin设置为vendor/bin/project-a-bin

从二进制文件中查找Composer自动加载器

Section titled “从二进制文件中查找Composer自动加载器”

自Composer 2.2起,bin代理文件定义了一个新的$_composer_autoload_path全局变量,因此当你的二进制文件执行时,它可以使用该变量轻松定位项目的自动加载器。

然而,在运行由根包本身定义的二进制文件时,此全局变量将不可用,因此你需要准备一个备用方案。

例如,情况可能如下:

<?php
include $_composer_autoload_path ?? __DIR__ . '/../vendor/autoload.php';

不过,如果你想在你的包中依赖这一点,你应该确保同时要求"composer-runtime-api": "^2.2",以保证该包能在支持此功能的Composer版本中安装。

从二进制文件中查找Composer的bin目录

Section titled “从二进制文件中查找Composer的bin目录”

自 Composer 2.2.2 版本起,bin 代理文件定义了一个新的 $_composer_bin_dir 全局变量,因此当你的二进制文件执行时,可以使用该变量轻松定位项目的 Composer bin 目录。

对于非PHP二进制文件,从Composer 2.2.6版本开始,bin代理会设置一个COMPOSER_RUNTIME_BIN_DIR环境变量。

然而,当运行由根包本身定义的二进制文件时,这个全局变量将不可用,因此你需要准备一个备用方案。

例如,可能如下所示:

<?php
$binDir = $_composer_bin_dir ?? __DIR__ . '/../vendor/bin';
#!/bin/bash
if [[ -z "$COMPOSER_RUNTIME_BIN_DIR" ]]; then
BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
else
BIN_DIR="$COMPOSER_RUNTIME_BIN_DIR"
fi

不过,如果你想在你的包中依赖这一点,你应该确保同时要求"composer-runtime-api": "^2.2.2",以确保该包能与支持此功能的Composer版本一同安装。

完全由Composer管理的包不需要包含任何.bat文件来实现Windows兼容性。Composer在Windows环境中运行时,会以一种特殊方式处理二进制文件的安装:

  • 会自动生成一个.bat文件来引用该二进制文件
  • 还会生成一个与二进制文件同名的Unix风格代理文件,这对WSL、Linux虚拟机等很有用。

需要支持可能不包含Composer的工作流的包,欢迎维护自定义.bat文件。在这种情况下,该包不应.bat文件列为二进制文件,因为它不是必需的。

供应商二进制文件能否安装在vendor/bin以外的位置?

Section titled “供应商二进制文件能否安装在vendor/bin以外的位置?”

是的,有两种方法可以指定备用的供应商二进制文件位置:

  1. composer.json中设置bin-dir配置项
  2. 设置环境变量 COMPOSER_BIN_DIR

前者的一个例子如下:

{
"config": {
"bin-dir": "scripts"
}
}

运行composer install时,此composer.json会将所有供应商二进制文件安装到scripts/中,而非vendor/bin/

你可以将bin-dir设置为./,以将二进制文件放在项目根目录中。