You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel重写Vite类受保护方法添加script标签defer属性

实现方案

Illuminate\Foundation\Vite类未引入宏扩展特性,且makeScriptTag为受保护方法,无法从外部直接修改,在不改动框架核心代码的前提下,最规范的实现方式是继承重写+服务容器绑定替换,全程不修改vendor目录下的任何文件,不会被后续框架更新覆盖。


步骤1:创建自定义Vite子类

在项目中新建自定义Vite类,继承框架原生的Vite基类,重写makeScriptTag方法,在生成的script标签上新增defer属性。你可以根据自身目录规范调整类的存放位置,例如存放在app/Vite/CustomVite.php:

<?php

namespace App\Vite;

use Illuminate\Foundation\Vite as BaseVite;

class CustomVite extends BaseVite
{
    /**
     * Generate a script tag for the given URL.
     *
     * @param  string  $url
     * @return string
     */
    protected function makeScriptTag($url)
    {
        return sprintf('<script type="module" src="%s" defer></script>', $url);
    }
}

步骤2:替换服务容器中的Vite绑定

Laravel所有用到Vite实例的地方(包括@vite Blade指令、vite()助手函数)都是从服务容器解析的,你只需要在服务提供者中把原生Vite的绑定替换为自定义子类的实例即可。
打开app/Providers/AppServiceProvider.php,在register方法中添加绑定逻辑:

<?php

namespace App\Providers;

use App\Vite\CustomVite;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        $this->app->singleton(\Illuminate\Foundation\Vite::class, function () {
            return new CustomVite();
        });
    }

    // 其余boot等原有方法保持不变即可
}

验证生效

代码修改完成后,执行php artisan optimize:clear清除应用缓存,刷新页面查看前端源码,就能看到所有Vite自动生成的module类型script标签都已经带上了defer属性,原有资源加载、版本号处理等功能完全不受影响。

说明:

  • 不要直接修改vendor/laravel/framework目录下的核心代码,后续执行composer update时改动会被直接覆盖,且不符合框架扩展规范
  • 这种继承替换的实现方式是Laravel官方推荐的扩展模式,后续框架升级不会覆盖自定义逻辑,维护成本极低
  • 替换绑定后不需要额外修改模板或其他业务代码,所有调用Vite生成资源标签的逻辑都会自动走重写后的方法

内容的提问来源于stack exchange,提问作者Mark Shust at M.academy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:48:54