From ed6c5e4a92061629cfc8e258b3064a4bc1e5d8cd Mon Sep 17 00:00:00 2001
From: Tim MacDonald
Date: Tue, 13 Aug 2024 11:04:45 +1000
Subject: [PATCH 1/6] Adds asset prefetching strategies
---
src/Illuminate/Foundation/Vite.php | 155 +++++++-
tests/Foundation/FoundationViteTest.php | 364 ++++++++++++++++++
.../fixtures/prefetching-manifest.json | 284 ++++++++++++++
3 files changed, 802 insertions(+), 1 deletion(-)
create mode 100644 tests/Foundation/fixtures/prefetching-manifest.json
diff --git a/src/Illuminate/Foundation/Vite.php b/src/Illuminate/Foundation/Vite.php
index 46deeb8f0041..1d964d21406b 100644
--- a/src/Illuminate/Foundation/Vite.php
+++ b/src/Illuminate/Foundation/Vite.php
@@ -5,6 +5,7 @@
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Collection;
use Illuminate\Support\HtmlString;
+use Illuminate\Support\Js;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\Macroable;
@@ -96,6 +97,20 @@ class Vite implements Htmlable
*/
protected static $manifests = [];
+ /**
+ * The prefetching strategy to use.
+ *
+ * @var null|'waterfall'|'aggressive'
+ */
+ protected $prefetchStrategy = null;
+
+ /**
+ * The number of assets to load concurrently when using the "waterfall" strategy.
+ *
+ * @var int
+ */
+ protected $prefetchChunks = 3;
+
/**
* Get the preloaded assets.
*
@@ -166,6 +181,24 @@ public function useManifestFilename($filename)
return $this;
}
+ /**
+ * Set the prefetching strategy.
+ *
+ * @param 'waterfall'|'aggressive'|null $strategy
+ * @param array $config
+ * @return $this
+ */
+ public function usePrefetchStrategy($strategy, $config)
+ {
+ $this->prefetchStrategy = $strategy;
+
+ if ($strategy === 'waterfall') {
+ $this->prefetchChunks = $config['chunks'] ?? $this->prefetchChunks;
+ }
+
+ return $this;
+ }
+
/**
* Resolve asset paths using the provided resolver.
*
@@ -363,7 +396,127 @@ public function __invoke($entrypoints, $buildDirectory = null)
->sortByDesc(fn ($args) => $this->isCssPath($args[1]))
->map(fn ($args) => $this->makePreloadTagForChunk(...$args));
- return new HtmlString($preloads->join('').$stylesheets->join('').$scripts->join(''));
+ $base = $preloads->join('').$stylesheets->join('').$scripts->join('');
+
+ if ($this->prefetchStrategy === null || $this->isRunningHot()) {
+ return new HtmlString($base);
+ }
+
+ $discoveredImports = [];
+
+ return collect($entrypoints)
+ ->flatMap(fn ($entrypoint) => collect($manifest[$entrypoint]['dynamicImports'] ?? [])
+ ->map(fn ($import) => $manifest[$import])
+ ->filter(fn ($chunk) => str_ends_with($chunk['file'], '.js') || str_ends_with($chunk['file'], '.css'))
+ ->flatMap($f = function ($chunk) use (&$f, $manifest, &$discoveredImports) {
+ return collect([...$chunk['imports'] ?? [], ...$chunk['dynamicImports'] ?? []])
+ ->reject(function ($import) use (&$discoveredImports) {
+ if (isset($discoveredImports[$import])) {
+ return true;
+ }
+
+ return ! $discoveredImports[$import] = true;
+ })
+ ->reduce(
+ fn ($chunks, $import) => $chunks->merge(
+ $f($manifest[$import])
+ ), collect([$chunk]))
+ ->merge(collect($chunk['css'] ?? [])->map(
+ fn ($css) => collect($manifest)->first(fn ($chunk) => $chunk['file'] === $css) ?? [
+ 'file' => $css,
+ ],
+ ));
+ })
+ ->map(function ($chunk) use ($buildDirectory, $manifest) {
+ return collect([
+ ...$this->resolvePreloadTagAttributes(
+ $chunk['src'] ?? null,
+ $url = $this->assetPath("{$buildDirectory}/{$chunk['file']}"),
+ $chunk,
+ $manifest,
+ ),
+ 'rel' => 'prefetch',
+ 'href' => $url,
+ ])->reject(
+ fn ($value) => in_array($value, [null, false], true)
+ )->mapWithKeys(fn ($value, $key) => [
+ $key = (is_int($key) ? $value : $key) => $value === true ? $key : $value,
+ ])->all();
+ })
+ ->reject(fn ($attributes) => isset($this->preloadedAssets[$attributes['href']])))
+ ->unique('href')
+ ->values()
+ ->pipe(fn ($assets) => with(Js::from($assets), fn ($assets) => match ($this->prefetchStrategy) {
+ 'waterfall' => new HtmlString($base.<<
+ window.addEventListener('load', () => window.setTimeout(() => {
+ const linkTemplate = document.createElement('link')
+ linkTemplate.rel = 'prefetch'
+
+ const makeLink = (asset) => {
+ const link = linkTemplate.cloneNode()
+
+ Object.keys(asset).forEach((attribute) => {
+ link.setAttribute(attribute, asset[attribute])
+ })
+
+ return link
+ }
+
+ const loadNext = (assets, count) => window.setTimeout(() => {
+ if (count > assets.length) {
+ count = assets.length
+
+ if (count === 0) {
+ return
+ }
+ }
+
+ const fragment = new DocumentFragment
+
+ while (count > 0) {
+ const link = makeLink(assets.shift())
+ fragment.append(link)
+ count--
+
+ if (assets.length) {
+ link.onload = () => loadNext(assets, 1)
+ link.error = () => loadNext(assets, 1)
+ }
+ }
+
+ document.head.append(fragment)
+ })
+
+ loadNext({$assets}, {$this->prefetchChunks})
+ }))
+
+ HTML),
+ 'aggressive' => new HtmlString($base.<<
+ window.addEventListener('load', () => window.setTimeout(() => {
+ const linkTemplate = document.createElement('link')
+ linkTemplate.rel = 'prefetch'
+
+ const makeLink = (asset) => {
+ const link = linkTemplate.cloneNode()
+
+ Object.keys(asset).forEach((attribute) => {
+ link.setAttribute(attribute, asset[attribute])
+ })
+
+ return link
+ }
+
+ const fragment = new DocumentFragment
+ {$assets}.forEach((asset) => fragment.append(makeLink(asset)))
+ document.head.append(fragment)
+ }))
+
+ HTML),
+ }));
}
/**
diff --git a/tests/Foundation/FoundationViteTest.php b/tests/Foundation/FoundationViteTest.php
index 950fc2c21495..d0ccacee3d71 100644
--- a/tests/Foundation/FoundationViteTest.php
+++ b/tests/Foundation/FoundationViteTest.php
@@ -6,6 +6,7 @@
use Illuminate\Foundation\ViteException;
use Illuminate\Foundation\ViteManifestNotFoundException;
use Illuminate\Support\Facades\Vite as ViteFacade;
+use Illuminate\Support\Js;
use Illuminate\Support\Str;
use Orchestra\Testbench\TestCase;
@@ -1297,6 +1298,369 @@ protected function makeViteManifest($contents = null, $path = 'build')
file_put_contents(public_path("{$path}/manifest.json"), $manifest);
}
+ public function testItCanPrefetchEntrypoint()
+ {
+ $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));
+ $buildDir = Str::random();
+ $this->makeViteManifest($manifest, $buildDir);
+ app()->usePublicPath(__DIR__);
+
+ $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall')->toHtml();
+
+ $expectedAssets = Js::from([
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ]);
+ $this->assertSame(<<
+
+ HTML, $html);
+
+ $this->cleanViteManifest($buildDir);
+ }
+
+ public function testItHandlesSpecifyingPageWithAppJs()
+ {
+ $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));
+ $buildDir = Str::random();
+ $this->makeViteManifest($manifest, $buildDir);
+ app()->usePublicPath(__DIR__);
+
+ $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js', 'resources/js/Pages/Auth/Login.vue'])->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall')->toHtml();
+
+ $expectedAssets = Js::from([
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ]);
+ $this->assertStringContainsString(<<cleanViteManifest($buildDir);
+ }
+
+ public function testItCanSpecifyWaterfallChunks()
+ {
+ $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));
+ $buildDir = Str::random();
+ $this->makeViteManifest($manifest, $buildDir);
+ app()->usePublicPath(__DIR__);
+
+ $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall', ['chunks' => 10])->toHtml();
+
+ $expectedAssets = Js::from([
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ]);
+ $this->assertStringContainsString(<<cleanViteManifest($buildDir);
+ }
+
+ public function testItCanPrefetchAggressively()
+ {
+ $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));
+ $buildDir = Str::random();
+ $this->makeViteManifest($manifest, $buildDir);
+ app()->usePublicPath(__DIR__);
+
+ $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->usePrefetchStrategy('aggressive')->toHtml();
+
+ $expectedAssets = Js::from([
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ]);
+
+ $this->assertSame(<<
+
+ HTML, $html);
+
+ $this->cleanViteManifest($buildDir);
+ }
+
+ public function testAddsAttributesToPrefetchTags()
+ {
+ $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));
+ $buildDir = Str::random();
+ $this->makeViteManifest($manifest, $buildDir);
+ app()->usePublicPath(__DIR__);
+
+ $html = (string) tap(ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall'))->useCspNonce('abc123')->toHtml();
+
+ $expectedAssets = Js::from([
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js", "nonce" => "abc123"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js", "nonce" => "abc123"],
+ ]);
+ $this->assertStringContainsString(<<cleanViteManifest($buildDir);
+ }
+
+ public function testItNormalisesAttributes()
+ {
+ $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));
+ $buildDir = Str::random();
+ $this->makeViteManifest($manifest, $buildDir);
+ app()->usePublicPath(__DIR__);
+
+ $html = (string) tap(ViteFacade::withEntryPoints(['resources/js/app.js']))->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall')->usePreloadTagAttributes([
+ 'key' => 'value',
+ 'key-only',
+ 'true-value' => true,
+ 'false-value' => false,
+ 'null-value' => null,
+ ])->toHtml();
+
+ $expectedAssets = Js::from([
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ]);
+
+ $this->assertStringContainsString(<<cleanViteManifest($buildDir);
+ }
+
+ public function testItPrefetchesCss()
+ {
+ $manifest = json_decode(file_get_contents(__DIR__.'/fixtures/prefetching-manifest.json'));
+ $buildDir = Str::random();
+ $this->makeViteManifest($manifest, $buildDir);
+ app()->usePublicPath(__DIR__);
+
+ $html = (string) ViteFacade::withEntryPoints(['resources/js/admin.js'])->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall')->toHtml();
+
+ $expectedAssets = Js::from([
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/admin-runtime-import-CRvLQy6v.js"],
+ ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/admin-runtime-import-import-DKMIaPXC.js"],
+ ["rel" => "prefetch", "as" => "style", "href" => "https://example.com/{$buildDir}/assets/admin-runtime-import-BlmN0T4U.css"],
+ ]);
+ $this->assertSame(<<
+
+ HTML, $html);
+
+ $this->cleanViteManifest($buildDir);
+ }
+
protected function cleanViteManifest($path = 'build')
{
if (file_exists(public_path("{$path}/manifest.json"))) {
diff --git a/tests/Foundation/fixtures/prefetching-manifest.json b/tests/Foundation/fixtures/prefetching-manifest.json
new file mode 100644
index 000000000000..564ee66a4885
--- /dev/null
+++ b/tests/Foundation/fixtures/prefetching-manifest.json
@@ -0,0 +1,284 @@
+{
+ "_ApplicationLogo-BhIZH06z.js": {
+ "file": "assets/ApplicationLogo-BhIZH06z.js",
+ "name": "ApplicationLogo",
+ "imports": [
+ "__plugin-vue_export-helper-DlAUqK2U.js",
+ "_index-BSdK3M0e.js"
+ ]
+ },
+ "_AuthenticatedLayout-DfWF52N1.js": {
+ "file": "assets/AuthenticatedLayout-DfWF52N1.js",
+ "name": "AuthenticatedLayout",
+ "imports": [
+ "_ApplicationLogo-BhIZH06z.js",
+ "_index-BSdK3M0e.js"
+ ]
+ },
+ "_GuestLayout-BY3LC-73.js": {
+ "file": "assets/GuestLayout-BY3LC-73.js",
+ "name": "GuestLayout",
+ "imports": [
+ "_ApplicationLogo-BhIZH06z.js",
+ "_index-BSdK3M0e.js"
+ ]
+ },
+ "_PrimaryButton-DuXwr-9M.js": {
+ "file": "assets/PrimaryButton-DuXwr-9M.js",
+ "name": "PrimaryButton",
+ "imports": [
+ "__plugin-vue_export-helper-DlAUqK2U.js",
+ "_index-BSdK3M0e.js"
+ ]
+ },
+ "_TextInput-C8CCB_U_.js": {
+ "file": "assets/TextInput-C8CCB_U_.js",
+ "name": "TextInput",
+ "imports": [
+ "_index-BSdK3M0e.js"
+ ]
+ },
+ "__plugin-vue_export-helper-DlAUqK2U.js": {
+ "file": "assets/_plugin-vue_export-helper-DlAUqK2U.js",
+ "name": "_plugin-vue_export-helper"
+ },
+ "_index-!~{00f}~.js": {
+ "file": "assets/index-B3s1tYeC.css",
+ "src": "_index-!~{00f}~.js"
+ },
+ "_index-BSdK3M0e.js": {
+ "file": "assets/index-BSdK3M0e.js",
+ "name": "index",
+ "css": [
+ "assets/index-B3s1tYeC.css"
+ ]
+ },
+ "resources/js/Pages/Auth/ConfirmPassword.vue": {
+ "file": "assets/ConfirmPassword-CDwcgU8E.js",
+ "name": "ConfirmPassword",
+ "src": "resources/js/Pages/Auth/ConfirmPassword.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js",
+ "_GuestLayout-BY3LC-73.js",
+ "_TextInput-C8CCB_U_.js",
+ "_PrimaryButton-DuXwr-9M.js",
+ "_ApplicationLogo-BhIZH06z.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js"
+ ]
+ },
+ "resources/js/Pages/Auth/ForgotPassword.vue": {
+ "file": "assets/ForgotPassword-B0WWE0BO.js",
+ "name": "ForgotPassword",
+ "src": "resources/js/Pages/Auth/ForgotPassword.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js",
+ "_GuestLayout-BY3LC-73.js",
+ "_TextInput-C8CCB_U_.js",
+ "_PrimaryButton-DuXwr-9M.js",
+ "_ApplicationLogo-BhIZH06z.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js"
+ ]
+ },
+ "resources/js/Pages/Auth/Login.vue": {
+ "file": "assets/Login-DAFSdGSW.js",
+ "name": "Login",
+ "src": "resources/js/Pages/Auth/Login.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js",
+ "_GuestLayout-BY3LC-73.js",
+ "_TextInput-C8CCB_U_.js",
+ "_PrimaryButton-DuXwr-9M.js",
+ "_ApplicationLogo-BhIZH06z.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js"
+ ]
+ },
+ "resources/js/Pages/Auth/Register.vue": {
+ "file": "assets/Register-CfYQbTlA.js",
+ "name": "Register",
+ "src": "resources/js/Pages/Auth/Register.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js",
+ "_GuestLayout-BY3LC-73.js",
+ "_TextInput-C8CCB_U_.js",
+ "_PrimaryButton-DuXwr-9M.js",
+ "_ApplicationLogo-BhIZH06z.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js"
+ ]
+ },
+ "resources/js/Pages/Auth/ResetPassword.vue": {
+ "file": "assets/ResetPassword-BNl7a4X1.js",
+ "name": "ResetPassword",
+ "src": "resources/js/Pages/Auth/ResetPassword.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js",
+ "_GuestLayout-BY3LC-73.js",
+ "_TextInput-C8CCB_U_.js",
+ "_PrimaryButton-DuXwr-9M.js",
+ "_ApplicationLogo-BhIZH06z.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js"
+ ]
+ },
+ "resources/js/Pages/Auth/VerifyEmail.vue": {
+ "file": "assets/VerifyEmail-CyukB_SZ.js",
+ "name": "VerifyEmail",
+ "src": "resources/js/Pages/Auth/VerifyEmail.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js",
+ "_GuestLayout-BY3LC-73.js",
+ "_PrimaryButton-DuXwr-9M.js",
+ "_ApplicationLogo-BhIZH06z.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js"
+ ]
+ },
+ "resources/js/Pages/Dashboard.vue": {
+ "file": "assets/Dashboard-DM_LxQy2.js",
+ "name": "Dashboard",
+ "src": "resources/js/Pages/Dashboard.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_AuthenticatedLayout-DfWF52N1.js",
+ "_index-BSdK3M0e.js",
+ "_ApplicationLogo-BhIZH06z.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js"
+ ]
+ },
+ "resources/js/Pages/Profile/Edit.vue": {
+ "file": "assets/Edit-CYV2sXpe.js",
+ "name": "Edit",
+ "src": "resources/js/Pages/Profile/Edit.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_AuthenticatedLayout-DfWF52N1.js",
+ "resources/js/Pages/Profile/Partials/DeleteUserForm.vue",
+ "resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue",
+ "resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue",
+ "_index-BSdK3M0e.js",
+ "_ApplicationLogo-BhIZH06z.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js",
+ "_TextInput-C8CCB_U_.js",
+ "_PrimaryButton-DuXwr-9M.js"
+ ]
+ },
+ "resources/js/Pages/Profile/Partials/DeleteUserForm.vue": {
+ "file": "assets/DeleteUserForm-B1oHFaVP.js",
+ "name": "DeleteUserForm",
+ "src": "resources/js/Pages/Profile/Partials/DeleteUserForm.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js",
+ "_TextInput-C8CCB_U_.js"
+ ]
+ },
+ "resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue": {
+ "file": "assets/UpdatePasswordForm-CaeWqGla.js",
+ "name": "UpdatePasswordForm",
+ "src": "resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js",
+ "_TextInput-C8CCB_U_.js",
+ "_PrimaryButton-DuXwr-9M.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js"
+ ]
+ },
+ "resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue": {
+ "file": "assets/UpdateProfileInformationForm-CJwkYwQQ.js",
+ "name": "UpdateProfileInformationForm",
+ "src": "resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js",
+ "_TextInput-C8CCB_U_.js",
+ "_PrimaryButton-DuXwr-9M.js",
+ "__plugin-vue_export-helper-DlAUqK2U.js"
+ ]
+ },
+ "resources/js/Pages/Welcome.vue": {
+ "file": "assets/Welcome-D_7l79PQ.js",
+ "name": "Welcome",
+ "src": "resources/js/Pages/Welcome.vue",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js"
+ ]
+ },
+ "resources/js/admin-runtime-import-import.js": {
+ "file": "assets/admin-runtime-import-import-DKMIaPXC.js",
+ "name": "admin-runtime-import-import",
+ "src": "resources/js/admin-runtime-import-import.js",
+ "isDynamicEntry": true
+ },
+ "resources/js/admin-runtime-import.js": {
+ "file": "assets/admin-runtime-import-CRvLQy6v.js",
+ "name": "admin-runtime-import",
+ "src": "resources/js/admin-runtime-import.js",
+ "isDynamicEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js"
+ ],
+ "dynamicImports": [
+ "resources/js/admin-runtime-import-import.js"
+ ],
+ "css": [
+ "assets/admin-runtime-import-BlmN0T4U.css"
+ ]
+ },
+ "resources/js/admin.js": {
+ "file": "assets/admin-Sefg0Q45.js",
+ "name": "admin",
+ "src": "resources/js/admin.js",
+ "isEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js"
+ ],
+ "dynamicImports": [
+ "resources/js/Pages/Auth/ConfirmPassword.vue",
+ "resources/js/Pages/Auth/ForgotPassword.vue",
+ "resources/js/Pages/Auth/Login.vue",
+ "resources/js/Pages/Auth/Register.vue",
+ "resources/js/Pages/Auth/ResetPassword.vue",
+ "resources/js/Pages/Auth/VerifyEmail.vue",
+ "resources/js/Pages/Dashboard.vue",
+ "resources/js/Pages/Profile/Edit.vue",
+ "resources/js/Pages/Profile/Partials/DeleteUserForm.vue",
+ "resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue",
+ "resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue",
+ "resources/js/Pages/Welcome.vue",
+ "resources/js/admin-runtime-import.js"
+ ],
+ "css": [
+ "assets/admin-BctAalm_.css"
+ ]
+ },
+ "resources/js/app.js": {
+ "file": "assets/app-lliD09ip.js",
+ "name": "app",
+ "src": "resources/js/app.js",
+ "isEntry": true,
+ "imports": [
+ "_index-BSdK3M0e.js"
+ ],
+ "dynamicImports": [
+ "resources/js/Pages/Auth/ConfirmPassword.vue",
+ "resources/js/Pages/Auth/ForgotPassword.vue",
+ "resources/js/Pages/Auth/Login.vue",
+ "resources/js/Pages/Auth/Register.vue",
+ "resources/js/Pages/Auth/ResetPassword.vue",
+ "resources/js/Pages/Auth/VerifyEmail.vue",
+ "resources/js/Pages/Dashboard.vue",
+ "resources/js/Pages/Profile/Edit.vue",
+ "resources/js/Pages/Profile/Partials/DeleteUserForm.vue",
+ "resources/js/Pages/Profile/Partials/UpdatePasswordForm.vue",
+ "resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue",
+ "resources/js/Pages/Welcome.vue"
+ ]
+ }
+}
+
From b6143556cc8b1e6bb1f97c7e8bee474631892ab4 Mon Sep 17 00:00:00 2001
From: Tim MacDonald
Date: Thu, 15 Aug 2024 11:36:19 +1000
Subject: [PATCH 2/6] Formatting
---
src/Illuminate/Foundation/Vite.php | 104 +++++-----
tests/Foundation/FoundationViteTest.php | 246 ++++++++++++------------
2 files changed, 175 insertions(+), 175 deletions(-)
diff --git a/src/Illuminate/Foundation/Vite.php b/src/Illuminate/Foundation/Vite.php
index 1d964d21406b..037cba0dfb1e 100644
--- a/src/Illuminate/Foundation/Vite.php
+++ b/src/Illuminate/Foundation/Vite.php
@@ -188,7 +188,7 @@ public function useManifestFilename($filename)
* @param array $config
* @return $this
*/
- public function usePrefetchStrategy($strategy, $config)
+ public function usePrefetchStrategy($strategy, $config = [])
{
$this->prefetchStrategy = $strategy;
@@ -449,74 +449,74 @@ public function __invoke($entrypoints, $buildDirectory = null)
->pipe(fn ($assets) => with(Js::from($assets), fn ($assets) => match ($this->prefetchStrategy) {
'waterfall' => new HtmlString($base.<<
- window.addEventListener('load', () => window.setTimeout(() => {
- const linkTemplate = document.createElement('link')
- linkTemplate.rel = 'prefetch'
+
- HTML),
- 'aggressive' => new HtmlString($base.<<prefetchChunks})
+ }))
+
+ HTML),
+ 'aggressive' => new HtmlString($base.<<
- window.addEventListener('load', () => window.setTimeout(() => {
- const linkTemplate = document.createElement('link')
- linkTemplate.rel = 'prefetch'
+
- HTML),
- }));
+ const fragment = new DocumentFragment
+ {$assets}.forEach((asset) => fragment.append(makeLink(asset)))
+ document.head.append(fragment)
+ }))
+
+ HTML),
+ }));
}
/**
diff --git a/tests/Foundation/FoundationViteTest.php b/tests/Foundation/FoundationViteTest.php
index d0ccacee3d71..5f3071ea197d 100644
--- a/tests/Foundation/FoundationViteTest.php
+++ b/tests/Foundation/FoundationViteTest.php
@@ -1308,24 +1308,24 @@ public function testItCanPrefetchEntrypoint()
$html = (string) ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall')->toHtml();
$expectedAssets = Js::from([
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
]);
$this->assertSame(<<
@@ -1387,18 +1387,18 @@ public function testItHandlesSpecifyingPageWithAppJs()
$html = (string) ViteFacade::withEntryPoints(['resources/js/app.js', 'resources/js/Pages/Auth/Login.vue'])->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall')->toHtml();
$expectedAssets = Js::from([
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
]);
$this->assertStringContainsString(<<useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall', ['chunks' => 10])->toHtml();
$expectedAssets = Js::from([
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
]);
$this->assertStringContainsString(<<useBuildDirectory($buildDir)->usePrefetchStrategy('aggressive')->toHtml();
$expectedAssets = Js::from([
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
]);
$this->assertSame(<<useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall'))->useCspNonce('abc123')->toHtml();
$expectedAssets = Js::from([
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js", "nonce" => "abc123"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js", "nonce" => "abc123"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js", 'nonce' => 'abc123'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js", 'nonce' => 'abc123'],
]);
$this->assertStringContainsString(<<toHtml();
$expectedAssets = Js::from([
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js", "key" => "value", "key-only" => "key-only", "true-value" => "true-value"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js", 'key' => 'value', 'key-only' => 'key-only', 'true-value' => 'true-value'],
]);
$this->assertStringContainsString(<<useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall')->toHtml();
$expectedAssets = Js::from([
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/admin-runtime-import-CRvLQy6v.js"],
- ["rel" => "prefetch", "href" => "https://example.com/{$buildDir}/assets/admin-runtime-import-import-DKMIaPXC.js"],
- ["rel" => "prefetch", "as" => "style", "href" => "https://example.com/{$buildDir}/assets/admin-runtime-import-BlmN0T4U.css"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/GuestLayout-BY3LC-73.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/TextInput-C8CCB_U_.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/PrimaryButton-DuXwr-9M.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ApplicationLogo-BhIZH06z.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/_plugin-vue_export-helper-DlAUqK2U.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ForgotPassword-B0WWE0BO.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Login-DAFSdGSW.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Register-CfYQbTlA.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ResetPassword-BNl7a4X1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/VerifyEmail-CyukB_SZ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Dashboard-DM_LxQy2.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/AuthenticatedLayout-DfWF52N1.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Edit-CYV2sXpe.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/DeleteUserForm-B1oHFaVP.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdatePasswordForm-CaeWqGla.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/UpdateProfileInformationForm-CJwkYwQQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/Welcome-D_7l79PQ.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/admin-runtime-import-CRvLQy6v.js"],
+ ['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/admin-runtime-import-import-DKMIaPXC.js"],
+ ['rel' => 'prefetch', 'as' => 'style', 'href' => "https://example.com/{$buildDir}/assets/admin-runtime-import-BlmN0T4U.css"],
]);
$this->assertSame(<<
From 60a12096e496e2159df79f8620faae7fab290583 Mon Sep 17 00:00:00 2001
From: Tim MacDonald
Date: Fri, 16 Aug 2024 09:49:30 +1000
Subject: [PATCH 3/6] Rename config
---
src/Illuminate/Foundation/Vite.php | 6 +++---
tests/Foundation/FoundationViteTest.php | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Illuminate/Foundation/Vite.php b/src/Illuminate/Foundation/Vite.php
index 037cba0dfb1e..5d6c42b50ccf 100644
--- a/src/Illuminate/Foundation/Vite.php
+++ b/src/Illuminate/Foundation/Vite.php
@@ -109,7 +109,7 @@ class Vite implements Htmlable
*
* @var int
*/
- protected $prefetchChunks = 3;
+ protected $prefetchConcurrently = 3;
/**
* Get the preloaded assets.
@@ -193,7 +193,7 @@ public function usePrefetchStrategy($strategy, $config = [])
$this->prefetchStrategy = $strategy;
if ($strategy === 'waterfall') {
- $this->prefetchChunks = $config['chunks'] ?? $this->prefetchChunks;
+ $this->prefetchConcurrently = $config['concurrently'] ?? $this->prefetchConcurrently;
}
return $this;
@@ -489,7 +489,7 @@ public function __invoke($entrypoints, $buildDirectory = null)
document.head.append(fragment)
})
- loadNext({$assets}, {$this->prefetchChunks})
+ loadNext({$assets}, {$this->prefetchConcurrently})
}))
HTML),
diff --git a/tests/Foundation/FoundationViteTest.php b/tests/Foundation/FoundationViteTest.php
index 5f3071ea197d..1e859438a02e 100644
--- a/tests/Foundation/FoundationViteTest.php
+++ b/tests/Foundation/FoundationViteTest.php
@@ -1414,7 +1414,7 @@ public function testItCanSpecifyWaterfallChunks()
$this->makeViteManifest($manifest, $buildDir);
app()->usePublicPath(__DIR__);
- $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall', ['chunks' => 10])->toHtml();
+ $html = (string) ViteFacade::withEntryPoints(['resources/js/app.js'])->useBuildDirectory($buildDir)->usePrefetchStrategy('waterfall', ['concurrently' => 10])->toHtml();
$expectedAssets = Js::from([
['rel' => 'prefetch', 'href' => "https://example.com/{$buildDir}/assets/ConfirmPassword-CDwcgU8E.js"],
From b755cd3a889e713b7933ce20f9cf2424fdf03c25 Mon Sep 17 00:00:00 2001
From: Tim MacDonald
Date: Fri, 16 Aug 2024 10:02:04 +1000
Subject: [PATCH 4/6] Use low fetch priority
---
src/Illuminate/Foundation/Vite.php | 11 +-
tests/Foundation/FoundationViteTest.php | 261 ++++++++++++------------
2 files changed, 129 insertions(+), 143 deletions(-)
diff --git a/src/Illuminate/Foundation/Vite.php b/src/Illuminate/Foundation/Vite.php
index 5d6c42b50ccf..3a52b9437cc3 100644
--- a/src/Illuminate/Foundation/Vite.php
+++ b/src/Illuminate/Foundation/Vite.php
@@ -436,6 +436,7 @@ public function __invoke($entrypoints, $buildDirectory = null)
$manifest,
),
'rel' => 'prefetch',
+ 'fetchpriority' => 'low',
'href' => $url,
])->reject(
fn ($value) => in_array($value, [null, false], true)
@@ -451,11 +452,8 @@ public function __invoke($entrypoints, $buildDirectory = null)