vendor目录需加.gitignore并执行git rm -r --cached vendor;composer.lock必须提交且统一php/composer版本;私有包应优先用dist方式安装。

composer install 时提示 vendor 目录不存在或报错
这是最常见现象:本地运行 composer install 却发现 vendor 没生成,或者报 Could not find package。根本原因往往是 git 把 vendor 提交进去了,又删了,导致状态混乱;或者别人没提交 composer.lock,你本地用的 PHP 版本/扩展和 CI 不一致。
实操建议:
-
vendor/必须加进.gitignore,且确保没被意外 track 过:git rm -r --cached vendor(仅移出索引,不删本地) -
composer.lock必须提交——它锁定了依赖版本,没它,composer install就退化成composer update - CI/CD 或协作环境里,优先跑
composer install --no-dev(除非真要跑测试) - 如果报
Package ... has a dependency on ext-xxx,说明对方环境缺扩展,不是 composer 配置问题
git status 总是显示 composer.lock 被修改,但没动过它
这通常是因为不同平台或 PHP 版本下,composer.lock 的 JSON 格式、排序、换行符或哈希值不一致。Windows 和 macOS 下 composer 可能生成不同格式的 lock 文件,Git 默认按 LF 处理,容易误判“变更”。
实操建议:
- 统一团队 PHP 版本(至少小版本一致),并确认都用 Composer 2.x(v1 和 v2 生成的 lock 结构不同)
- 在项目根目录加
.gitattributes,写入:composer.lock text eol=lf,强制 Git 当作文本+LF 处理 - 避免手动编辑
composer.lock;改依赖只用composer require或composer update - 提交前执行
composer update --lock(不升级包,只刷新 lock 文件结构)可消除无意义 diff
怎么让 git 忽略 vendor/ 但保留部分子目录
极少数场景需要保留 vendor/bin(如 phpunit 软链)或某个私有包的源码(比如公司内部 fork 后打了 patch 的包)。Git 不能“忽略父目录却保留子目录”,必须靠规则顺序绕过。
实操建议:
- 先忽略全部:
vendor/ - 再反向取消忽略目标:
!vendor/bin/、!vendor/my-company/private-package/ - 注意顺序:Git 的 .gitignore 是从上到下匹配,第一条匹配就终止;所以
!规则必须写在vendor/之后 - 如果
vendor/bin已被 track,仍需git rm -r --cached vendor/bin再提交,否则忽略无效
CI 环境中 composer install 很慢,或因 git clone 私有包失败
Composer 默认用 git clone 方式拉取 VCS 包(尤其是 dev-master 或 dev-feature/xxx 分支),而 CI 环境往往没配 SSH key 或没开 HTTPS 认证,直接卡住或 401。
实操建议:
- 私有包优先走
dist(zip 包)而非vcs:在composer.json中为该包加"dist": {"url": "https://.../package.zip", "shasum": "..."} - CI 中设置
COMPOSER_AUTH环境变量,内容为 JSON,含 GitHub/GitLab 的 personal access token - 用
composer install --prefer-dist强制走压缩包(比 git clone 快,也绕过权限问题) - 避免在
require里写"dev-xxx"分支名——它会触发 clone;改用dev-xxx#commit-hash或打正式 tag
git add vendor 一次,后续所有人就得花十分钟排查为什么 composer install 总是不生效。










