diff --git a/src/Illuminate/Foundation/Vite.php b/src/Illuminate/Foundation/Vite.php
index 0eddc517b2b5..a860e94f2b92 100644
--- a/src/Illuminate/Foundation/Vite.php
+++ b/src/Illuminate/Foundation/Vite.php
@@ -233,7 +233,7 @@ public function useStyleTagAttributes($attributes)
/**
* Use the given callback to resolve attributes for preload tags.
*
- * @param (callable(string, string, ?array, ?array): array)|array $attributes
+ * @param (callable(string, string, ?array, ?array): array|false)|array|false $attributes
* @return $this
*/
public function usePreloadTagAttributes($attributes)
@@ -351,8 +351,8 @@ public function __invoke($entrypoints, $buildDirectory = null)
*
* @param string $src
* @param string $url
- * @param ?array $chunk
- * @param ?array $manifest
+ * @param array|null $chunk
+ * @param array|null $manifest
* @return string
*/
protected function makeTagForChunk($src, $url, $chunk, $manifest)
@@ -386,12 +386,16 @@ protected function makeTagForChunk($src, $url, $chunk, $manifest)
* @param string $url
* @param array $chunk
* @param array $manifest
- * @return string|null
+ * @return string
*/
protected function makePreloadTagForChunk($src, $url, $chunk, $manifest)
{
$attributes = $this->resolvePreloadTagAttributes($src, $url, $chunk, $manifest);
+ if ($attributes === false) {
+ return '';
+ }
+
$this->preloadedAssets[$url] = $this->parseAttributes(
Collection::make($attributes)->forget('href')->all()
);
@@ -404,8 +408,8 @@ protected function makePreloadTagForChunk($src, $url, $chunk, $manifest)
*
* @param string $src
* @param string $url
- * @param ?array $chunk
- * @param ?array $manifest
+ * @param array|null $chunk
+ * @param array|null $manifest
* @return array
*/
protected function resolveScriptTagAttributes($src, $url, $chunk, $manifest)
@@ -426,8 +430,8 @@ protected function resolveScriptTagAttributes($src, $url, $chunk, $manifest)
*
* @param string $src
* @param string $url
- * @param ?array $chunk
- * @param ?array $manifest
+ * @param array|null $chunk
+ * @param array|null $manifest
* @return array
*/
protected function resolveStylesheetTagAttributes($src, $url, $chunk, $manifest)
@@ -450,7 +454,7 @@ protected function resolveStylesheetTagAttributes($src, $url, $chunk, $manifest)
* @param string $url
* @param array $chunk
* @param array $manifest
- * @return array
+ * @return array|false
*/
protected function resolvePreloadTagAttributes($src, $url, $chunk, $manifest)
{
@@ -472,7 +476,11 @@ protected function resolvePreloadTagAttributes($src, $url, $chunk, $manifest)
: $attributes;
foreach ($this->preloadTagAttributesResolvers as $resolver) {
- $attributes = array_merge($attributes, $resolver($src, $url, $chunk, $manifest));
+ if (false === ($resolvedAttributes = $resolver($src, $url, $chunk, $manifest))) {
+ return false;
+ }
+
+ $attributes = array_merge($attributes, $resolvedAttributes);
}
return $attributes;
diff --git a/src/Illuminate/Support/Facades/Vite.php b/src/Illuminate/Support/Facades/Vite.php
index ad5576463699..3a289074a7d9 100644
--- a/src/Illuminate/Support/Facades/Vite.php
+++ b/src/Illuminate/Support/Facades/Vite.php
@@ -14,7 +14,7 @@
* @method static \Illuminate\Foundation\Vite useBuildDirectory(string $path)
* @method static \Illuminate\Foundation\Vite useScriptTagAttributes((callable(string, string, ?array, ?array): array)|array $attributes)
* @method static \Illuminate\Foundation\Vite useStyleTagAttributes((callable(string, string, ?array, ?array): array)|array $attributes)
- * @method static \Illuminate\Foundation\Vite usePreloadTagAttributes((callable(string, string, ?array, ?array): array)|array $attributes)
+ * @method static \Illuminate\Foundation\Vite usePreloadTagAttributes((callable(string, string, ?array, ?array): array|false)|array|false $attributes)
* @method static \Illuminate\Support\HtmlString|void reactRefresh()
* @method static string asset(string $asset, string|null $buildDirectory = null)
* @method static string|null manifestHash(string|null $buildDirectory = null)
diff --git a/tests/Foundation/FoundationViteTest.php b/tests/Foundation/FoundationViteTest.php
index 68814a7535b1..8d8a69a6328b 100644
--- a/tests/Foundation/FoundationViteTest.php
+++ b/tests/Foundation/FoundationViteTest.php
@@ -865,6 +865,157 @@ public function testItCanSpecifyAttributesForPreloadedAssets()
$this->cleanViteManifest($buildDir);
}
+ public function testItCanSuppressPreloadTagGeneration()
+ {
+ $buildDir = Str::random();
+ $this->makeViteManifest([
+ 'resources/js/app.js' => [
+ 'src' => 'resources/js/app.js',
+ 'file' => 'assets/app.versioned.js',
+ 'imports' => [
+ 'import.js',
+ 'import-nopreload.js',
+ ],
+ 'css' => [
+ 'assets/app.versioned.css',
+ 'assets/app-nopreload.versioned.css',
+ ],
+ ],
+ 'resources/js/app-nopreload.js' => [
+ 'src' => 'resources/js/app-nopreload.js',
+ 'file' => 'assets/app-nopreload.versioned.js',
+ ],
+ 'import.js' => [
+ 'file' => 'assets/import.versioned.js',
+ ],
+ 'import-nopreload.js' => [
+ 'file' => 'assets/import-nopreload.versioned.js',
+ ],
+ 'resources/css/app.css' => [
+ 'src' => 'resources/css/app.css',
+ 'file' => 'assets/app.versioned.css',
+ ],
+ 'resources/css/app-nopreload.css' => [
+ 'src' => 'resources/css/app-nopreload.css',
+ 'file' => 'assets/app-nopreload.versioned.css',
+ ],
+ ], $buildDir);
+ ViteFacade::usePreloadTagAttributes(function ($src, $url, $chunk, $manifest) use ($buildDir) {
+ $this->assertSame([
+ 'resources/js/app.js' => [
+ 'src' => 'resources/js/app.js',
+ 'file' => 'assets/app.versioned.js',
+ 'imports' => [
+ 'import.js',
+ 'import-nopreload.js',
+ ],
+ 'css' => [
+ 'assets/app.versioned.css',
+ 'assets/app-nopreload.versioned.css',
+ ],
+ ],
+ 'resources/js/app-nopreload.js' => [
+ 'src' => 'resources/js/app-nopreload.js',
+ 'file' => 'assets/app-nopreload.versioned.js',
+ ],
+ 'import.js' => [
+ 'file' => 'assets/import.versioned.js',
+ ],
+ 'import-nopreload.js' => [
+ 'file' => 'assets/import-nopreload.versioned.js',
+ ],
+ 'resources/css/app.css' => [
+ 'src' => 'resources/css/app.css',
+ 'file' => 'assets/app.versioned.css',
+ ],
+ 'resources/css/app-nopreload.css' => [
+ 'src' => 'resources/css/app-nopreload.css',
+ 'file' => 'assets/app-nopreload.versioned.css',
+ ],
+ ], $manifest);
+
+ (match ($src) {
+ 'resources/js/app.js' => function () use ($url, $chunk, $buildDir) {
+ $this->assertSame("https://example.com/{$buildDir}/assets/app.versioned.js", $url);
+ $this->assertSame([
+ 'src' => 'resources/js/app.js',
+ 'file' => 'assets/app.versioned.js',
+ 'imports' => [
+ 'import.js',
+ 'import-nopreload.js',
+ ],
+ 'css' => [
+ 'assets/app.versioned.css',
+ 'assets/app-nopreload.versioned.css',
+ ],
+ ], $chunk);
+ },
+ 'resources/js/app-nopreload.js' => function () use ($url, $chunk, $buildDir) {
+ $this->assertSame("https://example.com/{$buildDir}/assets/app-nopreload.versioned.js", $url);
+ $this->assertSame([
+ 'src' => 'resources/js/app-nopreload.js',
+ 'file' => 'assets/app-nopreload.versioned.js',
+ ], $chunk);
+ },
+ 'import.js' => function () use ($url, $chunk, $buildDir) {
+ $this->assertSame("https://example.com/{$buildDir}/assets/import.versioned.js", $url);
+ $this->assertSame([
+ 'file' => 'assets/import.versioned.js',
+ ], $chunk);
+ },
+ 'import-nopreload.js' => function () use ($url, $chunk, $buildDir) {
+ $this->assertSame("https://example.com/{$buildDir}/assets/import-nopreload.versioned.js", $url);
+ $this->assertSame([
+ 'file' => 'assets/import-nopreload.versioned.js',
+ ], $chunk);
+ },
+ 'resources/css/app.css' => function () use ($url, $chunk, $buildDir) {
+ $this->assertSame("https://example.com/{$buildDir}/assets/app.versioned.css", $url);
+ $this->assertSame([
+ 'src' => 'resources/css/app.css',
+ 'file' => 'assets/app.versioned.css',
+ ], $chunk);
+ },
+ 'resources/css/app-nopreload.css' => function () use ($url, $chunk, $buildDir) {
+ $this->assertSame("https://example.com/{$buildDir}/assets/app-nopreload.versioned.css", $url);
+ $this->assertSame([
+ 'src' => 'resources/css/app-nopreload.css',
+ 'file' => 'assets/app-nopreload.versioned.css',
+ ], $chunk);
+ },
+ })();
+
+ return Str::contains($src, '-nopreload') ? false : [];
+ });
+
+ $result = app(Vite::class)(['resources/js/app.js', 'resources/js/app-nopreload.js'], $buildDir);
+
+ $this->assertSame(
+ ''
+ .''
+ .''
+ .''
+ .''
+ .''
+ .'',
+ $result->toHtml());
+
+ $this->assertSame([
+ "https://example.com/$buildDir/assets/app.versioned.css" => [
+ 'rel="preload"',
+ 'as="style"',
+ ],
+ "https://example.com/$buildDir/assets/app.versioned.js" => [
+ 'rel="modulepreload"',
+ ],
+ "https://example.com/$buildDir/assets/import.versioned.js" => [
+ 'rel="modulepreload"',
+ ],
+ ], ViteFacade::preloadedAssets());
+
+ $this->cleanViteManifest($buildDir);
+ }
+
public function testPreloadAssetsGetAssetNonce()
{
$buildDir = Str::random();