diff --git a/src/Illuminate/Foundation/Vite.php b/src/Illuminate/Foundation/Vite.php index f5f53364b0d8..ad3328b82a64 100644 --- a/src/Illuminate/Foundation/Vite.php +++ b/src/Illuminate/Foundation/Vite.php @@ -338,9 +338,10 @@ public function __invoke($entrypoints, $buildDirectory = null) } } - [$stylesheets, $scripts] = $tags->partition(fn ($tag) => str_starts_with($tag, 'unique()->partition(fn ($tag) => str_starts_with($tag, 'sortByDesc(fn ($args) => $this->isCssPath($args[1])) + $preloads = $preloads->unique() + ->sortByDesc(fn ($args) => $this->isCssPath($args[1])) ->map(fn ($args) => $this->makePreloadTagForChunk(...$args)); return new HtmlString($preloads->join('').$stylesheets->join('').$scripts->join('')); diff --git a/tests/Foundation/FoundationViteTest.php b/tests/Foundation/FoundationViteTest.php index 68814a7535b1..92d3c9ae7b3c 100644 --- a/tests/Foundation/FoundationViteTest.php +++ b/tests/Foundation/FoundationViteTest.php @@ -982,6 +982,57 @@ public function testItCanConfigureTheManifestFilename() rmdir(public_path($buildDir)); } + public function testItOnlyOutputsUniquePreloadTags() + { + $buildDir = Str::random(); + $this->makeViteManifest([ + 'resources/js/app.css' => [ + 'file' => 'assets/app-versioned.css', + 'src' => 'resources/js/app.css', + ], + 'resources/js/Pages/Welcome.vue' => [ + 'file' => 'assets/Welcome-versioned.js', + 'src' => 'resources/js/Pages/Welcome.vue', + 'imports' => [ + 'resources/js/app.js', + ], + ], + 'resources/js/app.js' => [ + 'file' => 'assets/app-versioned.js', + 'src' => 'resources/js/app.js', + 'css' => [ + 'assets/app-versioned.css', + ], + ], + ], $buildDir); + + $result = app(Vite::class)(['resources/js/app.js', 'resources/js/Pages/Welcome.vue'], $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/Welcome-versioned.js" => [ + 'rel="modulepreload"', + ], + ], ViteFacade::preloadedAssets()); + + $this->cleanViteManifest($buildDir); + } + protected function makeViteManifest($contents = null, $path = 'build') { app()->singleton('path.public', fn () => __DIR__);