编程

Laravel artisan dev:运行服务器、队列、日志和 Vite

2 2026-09-13 14:08:00

Laravel 13 引入了一项新的 Artisan 开发命令,用于统一管理项目开发所需的所有组件:开发服务器、队列工作进程、日志输出、Vite 等。在此之前,项目框架是通过 composer.json 中的一个开发脚本将这些组件串联起来的,该脚本利用 npx 同时运行四条命令。

Laravel 13.16 版用一个官方原生命令取代了这种做法:

php artisan dev

composer dev 脚本虽然仍存在于骨架代码中,但它现在除了调用 php artisan dev 之外,不再执行其他操作。进程管理逻辑已移至 PHP 端,你可以通过 DevCommands 类注册自定义进程。

默认设置

该命令开箱即用,会运行四个进程:

名称命令
serverphp artisan serve --host=localhost
queuephp artisan queue:listen --tries=1 --timeout=0
logsphp artisan pail --timeout=0
vitenpm run dev

Pail 进程仅在 pcntl_fork 函数可用时才会注册,因此 Windows 用户将使用另外三个进程。Vite 进程会根据项目中存在的锁文件(npm、pnpm、Yarn 或 Bun)来选择相应的命令前缀;这意味着在 pnpm 项目中,无需任何配置即可直接运行 pnpm run dev。在底层实现上,该命令仍会调用 concurrently;自 13.18 版本起,它会传入 --kill-others-on-fail 参数,从而确保当某个进程崩溃时,其余进程也会随之停止,避免留下一个处于“半运行”状态的系统。

注册自定义进程

默认配置适用于全新安装的项目,但很少有应用能长期保持这种状态。假设有一个应用需要运行 Horizo​​n(而非 queue:listen)、通过 Reverb 进行广播、利用 Stripe CLI 在本地接收 Stripe Webhook,并以“监视模式”(watch mode)执行 TypeScript 类型检查。你可以在 AppServiceProviderboot 方法中注册所有这些进程:

namespace App\Providers;
 
use Illuminate\Foundation\DevCommands;
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        if (! $this->app->environment('local')) {
            return;
        }
 
        DevCommands::artisan('horizon', 'queue');
 
        DevCommands::artisan('reverb:start --debug', 'reverb')->purple();
 
        DevCommands::register(
            'stripe listen --forward-to '.config('app.url').'/stripe/webhook',
            'stripe'
        )->orange();
 
        DevCommands::nodeExec('tsc --noEmit --watch --preserveWatchOutput', 'types')->yellow();
    }
}

注册过程由四个方法负责:artisan() 方法会在命令前加上 php artisan 前缀;node() 会加上检测到的包管理器对应的运行命令前缀;nodeExec() 使用 exec 类命令(如 npx 等);而 register() 则接受原始 Shell 命令,用于处理其他情况(例如上文提到的 Stripe CLI)。

第二个参数是终端中显示的进程名称。如果省略该参数,名称将默认为命令的第一个单词(例如 horizo​​nreverb:startstripe)。不过,示例中的第一个参数不仅仅起标识作用:注册一个名为 queue 的进程,会用 Horizo​​n 替代默认的 queue:listen 工作进程。名称代表了进程的身份,因此复用名称正是替换或重新配置默认进程的方式。

DevCommands::artisan('serve --host=localhost --port=9000', 'server');

这里的注册顺序无关紧要。应用程序注册的命令优先级总是高于框架默认命令,且两者的优先级均高于第三方包(vendor)注册的命令,因此已安装的包无法悄然接管您定义的流程。这些包提供的是供您自行调用的方法,而不是在自动发现阶段进行挂载。

颜色设置是可选的。每个流程都会自动分配一种独特的颜色;只有当您希望某个特定流程格外醒目时,才会用到 blue()、purple()、pink()、orange()、green()、yellow() 或 color('#ff6347') 等颜色设置方法。

检查与筛选列表

若想查看已注册的内容而不实际启动任何进程,可运行 php artisan dev:list(该命令于 13.17 版本新增)。它会列出每个进程及其对应的命令,以及注册该进程的文件和行号——当某个包的安装说明添加了你已遗忘的配置时,这非常有用。

你也可以在不删除注册项的前提下精简列表:

// Only run the server and vite processes...
DevCommands::only('server', 'vite');
 
// Run everything except the queue worker...
DevCommands::except('queue');

两者都是在运行时应用的过滤器,因此被 except() 排除的进程仍会出现在你的提供程序(provider)中,且只需删除一行代码即可将其恢复。

dev 命令由 Joe Tannenbaum 在 Pull Request #60412 中贡献,完整详情请参阅 Artisan 文档。