Laravel 不自动加载 Composer 包中的迁移文件,因其仅扫描 database/migrations 目录;需在服务提供者中调用 loadMigrationsFrom() 显式注册包内 migrations/ 路径,并确保服务提供者已启用或被自动发现。

Composer 包本身不自动加载迁移文件,必须由应用显式引入或通过服务提供者注册 —— 这是 Laravel 项目中最常被误解的一点。
为什么 php artisan migrate 找不到包里的迁移文件
Laravel 默认只扫描 database/migrations 目录,不会递归扫描已安装 Composer 包中的 migrations/ 子目录。即使你把迁移文件放在包的 src/migrations/ 或根目录 migrations/ 下,Laravel 也完全无视它们。
- Composer 只负责代码分发,不参与 Laravel 的迁移发现机制
- 迁移路径硬编码在
Illuminate\Database\Migrations\Migrator内部,不支持自动扫描 vendor - 直接复制迁移文件到主项目是临时方案,破坏包升级一致性
正确注册包内迁移的两种方式(Laravel 5.5+)
核心是让 Laravel 知道“这个包有迁移,该从哪读”。推荐用服务提供者注册,而非手动复制:
- 在包的
ServiceProvider(如MyPackageServiceProvider)中重写boot()方法,调用$this->loadMigrationsFrom(__DIR__.'/../migrations'); - 确保包的
migrations/目录位于包根下(与src/同级),且迁移文件命名符合 Laravel 格式:2023_01_01_000000_create_x_table.php - 若使用 Laravel 5.5+ 的自动发现(
composer.json中声明"extra": {"laravel": {"dont-discover": []}}),需确认包已列入providers数组,否则boot()不会被调用
运行迁移前必须执行的检查项
即使注册了路径,仍可能因环境或配置失败:
- 运行
php artisan package:discover(尤其在添加新包后),否则服务提供者不会被识别 - 检查
config/app.php是否已启用该包的服务提供者(自动发现未开启时必须手动加) - 执行
php artisan migrate:status,确认包迁移显示为Pending而非完全不出现 —— 若不出现,说明loadMigrationsFrom()未生效或路径错误 - 注意权限:迁移文件必须可读,且路径不能含 Windows 风格反斜杠(
__DIR__在 Linux/macOS 下返回正斜杠,安全)
最易忽略的是服务提供者未被加载导致迁移静默失效;只要 migrate:status 里看不到包的迁移,就先查 package:discover 和 app.php 配置,而不是反复改路径。


















