composer中如何定义项目的版本号_composer.json中version字段详解【指南】

10次阅读

version 字段非必需,但若填写必须符合 SemVer 2.0 规范且与 git 状态一致;本地开发中硬写 version 会导致安装失败;私有包通过 path 引入时 version 被忽略;仅在发布分发包或 CI/CD 动态生成构建号时建议显式设置;日常开发应删除 version,依赖 Git 标签和 branch-alias 管理版本。

composer中如何定义项目的版本号_composer.json中version字段详解【指南】

version 字段不是必须填的,但填了就得符合规范

composer 不强制要求 composer.json 中定义 version 字段。如果你没写,Composer 会根据 Git 标签(如 v1.2.3)或分支名(如 dev-main)自动推断版本。但一旦你手动写了 "version": "1.2.3",就必须满足 SemVer 2.0 规范,且不能和 Git 状态冲突——否则 composer install 可能报错:Root package cannot be installed because it is not available in the configured repositories

  • 只允许使用 1.2.31.2.3-beta.11.2.3+build.456 这类标准格式,1.21.2.3.4 都不合法
  • 如果项目是本地开发态(无 Git 标签),又硬写了 "version": "1.0.0",Composer 会拒绝安装依赖,除非加 --ignore-platform-reqs(不推荐)
  • 私有包若通过 path 仓库引入,其 version 字段会被完全忽略,实际版本以父项目的 require 中指定的约束为准

什么时候该显式写 version?常见于发布包场景

只有两类情况建议显式设置 version

  • 打包为可分发的私有包(比如放在 Satis 或 private Packagist 上),且希望明确锁定某次构建的语义化版本
  • CI/CD 流水线中生成带构建号的版本(如 2.1.0+git.abc123),此时需配合脚本动态写入 composer.json,再执行 composer install --no-interaction

注意:github/gitlab 仓库直接作为 Composer 包使用时,version 字段会被 Git 标签覆盖,手动写的值不起作用。

version 和 package name 共同决定包的唯一标识

Composer 把 {"name": "vendor/name", "version": "1.2.3"} 当作一个完整包坐标。这意味着:

  • 同一 name 下,不同 version 值会被视为不同包(即使代码完全一样)
  • 如果你在 require 中写 "vendor/name": "^1.2",而该包的 composer.jsonversion"1.2.0-dev",那它不会被匹配——因为 -dev 后缀属于不稳定版本,默认不启用
  • 运行 composer show vendor/name 输出的版本号,优先显示 Git 标签,其次才是 version 字段值

想动态控制版本号?别碰 version 字段,改用 branch-alias 或 version constraint

日常开发中,硬编码 version 很容易导致协作混乱。更稳妥的做法是:

  • 删掉 version 字段,靠 Git 标签管理发布版本
  • extra 中配 branch-alias,例如:
    {     "extra": {         "branch-alias": {             "dev-main": "2.3.x-dev"         }     } }

    这样其他项目 require "vendor/name": "^2.3" 就能命中 main 分支

  • 发布前用 git tag v2.3.0 && git push origin v2.3.0,比手改 version 更可靠

真正容易被忽略的是:哪怕你只改了 version 字段,也相当于修改了包的身份标识,所有依赖它的项目都可能因版本解析失败而中断构建。

text=ZqhQzanResources