laravel包开发核心卡点在于composer.json三处配置、服务提供者命名规范及本地path仓库配置,缺一即导致class not found或vendor:publish失效。

直接说结论:Laravel 包开发不是写完代码就能用,核心卡点在 composer.json 的三处配置、服务提供者命名规范、以及本地开发时必须用 path 仓库——漏任何一项,Class not found 或 php artisan vendor:publish 找不到配置就是大概率事件。
composer.json 必填字段有哪些
很多人跑 composer init 后只填了 name 和 description,结果包装进 Laravel 就“消失”。真正起作用的字段只有这几个:
-
"type": "laravel-package"(非强制但强烈建议,否则某些工具链会跳过识别) -
"autoload": {"psr-4": {"Acme\Sms\": "src/"}}—— 命名空间和路径必须严格匹配,src/下的SmsServiceProvider.php就得对应Acme\Sms\SmsServiceProvider -
"require": {"php": "^8.1", "illuminate/support": "^10.0|^11.0"}——illuminate/support版本要对齐你目标 Laravel 主版本,别写^8.0|^9.0|^10.0这种宽泛范围,Laravel 11 已移除部分旧方法 -
"extra": {"laravel": {"providers": ["Acme\Sms\SmsServiceProvider"]}}—— 这是自动注册服务提供者的唯一依据,不写这行,就得手动加到config/app.php
SmsServiceProvider 类怎么写才生效
类名、位置、继承关系,三者缺一不可。常见错误是类放在 src/Providers/ 下却没更新命名空间,或继承错了基类。
- 文件路径必须是
src/SmsServiceProvider.php(不能套子目录),类名必须为SmsServiceProvider,且以ServiceProvider结尾 - 必须
extends Illuminate\Support\ServiceProvider,不能是Illuminate\Foundation\Support\Providers下的任意其他类 -
register()里做绑定,boot()里调$this->publishes()或$this->mergeConfigFrom();如果想支持php artisan vendor:publish --tag=config,publishes 第二个参数必须是字符串 tag,比如'sms-config' - 配置文件得放在包内
config/sms.php,且mergeConfigFrom()的路径要写对:用__DIR__.'/../../config/sms.php',不是__DIR__.'/config/sms.php'
本地开发为什么不能直接 composer require
因为远程包是压缩包解压出来的静态副本,改一行代码就得 composer update,效率归零。真实开发必须让 Laravel 读 symlink 目录下的实时文件。
- 在 Laravel 项目根目录的
composer.json里加:"repositories": [{"type": "path", "url": "../my-laravel-package"}] - 然后运行:
composer require acme/sms:@dev(注意@dev,否则可能拉 Git tag 而非本地最新) - 执行后检查
vendor/acme/sms是否是 symlink,指向你本地包目录;如果不是,说明path配置没生效或路径写错 - 别用
composer link:它在 Laravel 10+ 上常因 autoload 冲突导致Class not found,path是目前最稳的方案
发布前最容易被忽略的兼容性点
一个包在你本地 Laravel 11.2 上跑通,别人 composer require 后报错,往往不是代码问题,而是这些细节断链:
-
bootstrap/cache/packages.php缓存没清——每次改完composer.json或服务提供者,先删这个文件再跑php artisan package:discover - Git 仓库没打
v1.0.0这样的语义化标签,Packagist 就无法识别稳定版本 -
composer.json里漏了"license": "MIT",有些企业 CI 会拒绝安装无协议包 - 测试时只跑
phpunit,没在干净 Laravel 项目里走一遍composer require → php artisan vendor:publish → php artisan serve全流程











