Write your own custom @vite helper?
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
@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?
@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 )
@Sinnbeck Ok, this is my code:
- I have created
\App\Http\Services\ViteServiceclass 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\ViteServiceProviderand 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 inconfig/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.
@tronyx try resolving it from the container yourself to see if you get your own version
Or try and overwrite it
$this->app->bind(\Illuminate\Foundation\Vite::class, \App\Http\Services\ViteService::class);
@Sinnbeck Wow, this works! Thanks a lot!
@tronyx happy to help :) if it's solved please set the thread as solved
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.
@tronyx @rambii It’s all a non-issue any way, because scripts with type="module" are already deferred by default:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer
The
deferattribute has no effect on module scripts — they defer by default.
/cc @sinnbeck
@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
@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.
@martinbean Yeah its a bit new to me as well :) But thanks!
@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
@AdRock What package? I’m not discussing a package in my comments; just the standard HTML defer attribute.
@martinbean Perfect, didn't know about this behavior. Thanks for sharing :)
Please or to participate in this conversation.