tronyx's avatar

Defer JS scripts using Vite

Is there a way to defer .js scripts using default Vite setup on new Laravel app without installing laravel-vite.dev?

EDIT: I have created a very simple package to add defer attribute in Vite scripts. I needed it for internal purposes, to easily enable this on multiple Laravel apps but if anyone wants to use it here is the link https://packagist.org/packages/lexo/defer-vite

1 like
16 replies
tronyx's avatar

@Sinnbeck Thanks for the reply. I have tried to create an class which extends Vite class and overrides the function responsible for printing the script tag. Then I have created service container and there inside register method I have created an alias. But then I get the error that Vite class does not exist. Not sure if I’m going the right way even. I can show the code tomorrow, I’m on mobile atm. Or maybe you have some suggestion how it should be done?

Sinnbeck's avatar

@tronyx ok that's cool. I'll do my best to help once I see the code (it sounds correct btw if you try to use the default helper. Personally I would probably make my own )

tronyx's avatar

@Sinnbeck Ok, this is my code:

  • I have created \App\Http\Services\ViteService class and this is the content of that file:
<?php

namespace App\Http\Services;

use Illuminate\Foundation\Vite;

class ViteService extends Vite
{
    /**
     * 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);
    }
}
  • then I have created a new provider App\Providers\ViteServiceProvider and this is the content of that file:
<?php

namespace App\Providers;

use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\ServiceProvider;

class ViteServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->booting(function () {
            AliasLoader::getInstance()->alias(
                \App\Http\Services\ViteService::class,
                \Illuminate\Foundation\Vite::class
            );
        });
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}
  • and then I have added App\Providers\ViteServiceProvider::class, in the array of the providers in config/app.php

But nothing happens, no defer has been added to the script (no interception whatsoever).

The error that I had yesterday about missing Vite class happened because I have switched the order of the classes in alias() method.

Sinnbeck's avatar

@tronyx try resolving it from the container yourself to see if you get your own version

Sinnbeck's avatar
Sinnbeck
Best Answer
Level 102

Or try and overwrite it

$this->app->bind(\Illuminate\Foundation\Vite::class, \App\Http\Services\ViteService::class);
2 likes
rambii's avatar

You can also configure arbitrary attributes for the script tag in a service provider.

use Illuminate\Support\Facades\Vite;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Vite::useScriptTagAttributes([
            'defer' => true, // Specify an attribute without a value...
        ]);
    }
}

I cannot include links yet but look for: vite and arbitrary attributes in the v9 version of the docs.

8 likes
Sinnbeck's avatar

@keizah7 make a new thread please and we will try and help you out

Thanks @martinbean it's always great to learn new things :) I wonder why it was ever needed then

martinbean's avatar

@Sinnbeck The defer attribute is still needed on non-module scripts.

I still need to read about and understand the difference between “modules” in the browser and non-module scripts, but yeah, adding type="module" to a <script> tag defers it by default.

AdRock's avatar

@martinbean you may want to create a github page with instructions on how to use your package as there aren't any and I've had issues getting it working

martinbean's avatar

@AdRock What package? I’m not discussing a package in my comments; just the standard HTML defer attribute.

Please or to participate in this conversation.