Composer本身不执行构建,它仅负责依赖解析与文件分发,不会自动运行npm、make或artisan等构建命令;包作者须预编译产物并提交至Git或Packagist,用户需手动触发构建或依赖已构建好的dist文件。

Composer 本身不执行构建,构建过程必须由包作者预编译或交由用户手动触发
Composer 是依赖解析与文件分发工具,不是构建系统。它不会运行 npm run build、make 或 php artisan optimize 这类命令——哪怕你在被 require 的包的 composer.json 里写了 "scripts",默认也不会自动执行。
常见错误现象是:你装了一个前端组件包(比如含 dist/ 目录的 Vue 插件),但 vendor/package-name/dist/ 为空,直接引用 JS 报 404;或者一个扩展包声称“需编译 C 扩展”,但 composer install 后 extension.so 并不存在。
- 包作者应在发布前完成构建:打 tag 前运行构建脚本,把产物(如
dist/、bin/、.so)提交进 Git,或上传到 Packagist 的 dist 包中 - 若你控制该依赖包,可在其
composer.json中定义"scripts",并要求用户显式运行:composer run build --no-dev(注意:这不会被install或update自动触发) - 避免在
post-install-cmd或post-update-cmd中调用耗时/失败风险高的构建命令——CI 环境可能无 Node.js 或 GCC,导致整个composer install失败
require-dev 里的构建工具不能用于生产依赖的构建
很多人误以为把 nodejs、webpack-cli 放进根项目的 require-dev,就能让被 require 的前端包自动构建。不行。Composer 不会跨包执行 dev 工具链。
使用场景很明确:只有当你自己维护那个带构建逻辑的包,且你希望在开发它时能一键构建,才把工具放它的 require-dev 里;而作为使用者,你只能:要么信任它已预构建好,要么自己写 wrapper 脚本,在 composer install 后手动跑构建。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 例如,你依赖
acme/ui-kit,它源码含src/和webpack.config.js,但没提供dist/—— 你得自己加一步:npx webpack --config vendor/acme/ui-kit/webpack.config.js --mode production - 别在根项目
scripts里写"post-install-cmd": "cd vendor/acme/ui-kit && npm install && npm run build":路径不稳定(vendor可能被重命名)、权限问题、Node 版本不匹配都会让它在不同机器上行为不一致 - 更可靠的做法是 fork 该包,补全
dist/并发布新版本,或提 PR 让作者走 CI 构建 + 发布 dist 包
私有包或 path 仓库中构建失败的典型陷阱
用 {"type": "path", "url": "../packages/*"} 加载本地包时,最容易忽略构建状态同步问题。Composer 会原样复制目录内容,但不会判断 dist/ 是否过期。
错误现象:改了 packages/my-ui/src/index.ts,但 composer update 后网页仍加载旧的 dist/bundle.js,因为构建没被触发,也没被检查。
- 必须约定协作流程:每次修改源码后,手动运行
npm run build再提交,确保dist/始终与src/一致 - CI 流程中加校验:
git diff --quiet HEAD^ HEAD -- packages/my-ui/dist/ || (echo 'dist/ out of sync' && exit 1) - 不要依赖
autoload的files字段去加载未构建的 TS/JS 源码——PHP 无法执行它们,前端构建才是唯一出口
替代方案:用 Composer 插件或自定义 installer 实现构建集成(慎用)
理论上可通过 composer-plugin 在 InstallEvent 中调用外部命令,但这是高风险操作:
- 插件需声明
"type": "composer-plugin",且必须在根项目require中显式引入,不能藏在子依赖里 - 所有构建命令必须幂等、无副作用、可离线运行;否则
composer install在 CI 或 Docker 构建中大概率失败 - Packagist 不允许插件自动执行 shell 命令,多数托管平台会拒绝这类包;主流生态(如 Laravel、Symfony)也从不这么做
真正值得投入的点,是让构建成为包发布流程的一部分,而不是安装流程的一部分。Composer 的职责边界很清晰:下载、解压、链接、加载。越界的事,它不做,也不该做。

















