diff --git a/src/Illuminate/Foundation/Vite.php b/src/Illuminate/Foundation/Vite.php index 57ea3dbb4a01..c3eb977fb6ad 100644 --- a/src/Illuminate/Foundation/Vite.php +++ b/src/Illuminate/Foundation/Vite.php @@ -536,6 +536,26 @@ protected function manifestPath($buildDirectory) return public_path($buildDirectory.'/manifest.json'); } + /** + * Get a unique hash representing the current manifest, or null if there is no manifest. + * + * @return string|null + */ + public function manifestHash($buildDirectory = null) + { + $buildDirectory ??= $this->buildDirectory; + + if ($this->isRunningHot()) { + return null; + } + + if (! is_file($path = $this->manifestPath($buildDirectory))) { + return null; + } + + return md5_file($path) ?: null; + } + /** * Get the chunk for the given entry point / asset. * diff --git a/src/Illuminate/Support/Facades/Vite.php b/src/Illuminate/Support/Facades/Vite.php index c41ed5709f14..0534600e157d 100644 --- a/src/Illuminate/Support/Facades/Vite.php +++ b/src/Illuminate/Support/Facades/Vite.php @@ -5,6 +5,7 @@ /** * @method static string useCspNonce(?string $nonce = null) * @method static string|null cspNonce() + * @method static string|null manifestHash(?string $buildDirectory = null) * @method static string asset(string $asset, string|null $buildDirectory) * @method static string hotFile() * @method static \Illuminate\Foundation\Vite useBuildDirectory(string $path) diff --git a/tests/Foundation/FoundationViteTest.php b/tests/Foundation/FoundationViteTest.php index 86fd067423ed..fa5a5ba4cbf9 100644 --- a/tests/Foundation/FoundationViteTest.php +++ b/tests/Foundation/FoundationViteTest.php @@ -535,6 +535,36 @@ public function testItThrowsWhenUnableToFindAssetChunkInBuildMode() ViteFacade::asset('resources/js/missing.js'); } + public function testItDoesNotReturnHashInDevMode() + { + $this->makeViteHotFile(); + + $this->assertNull(ViteFacade::manifestHash()); + + $this->cleanViteHotFile(); + } + + public function testItGetsHashInBuildMode() + { + $this->makeViteManifest(['a.js' => ['src' => 'a.js']]); + + $this->assertSame('98ca5a789544599b562c9978f3147a0f', ViteFacade::manifestHash()); + + $this->cleanViteManifest(); + } + + public function testItGetsDifferentHashesForDifferentManifestsInBuildMode() + { + $this->makeViteManifest(['a.js' => ['src' => 'a.js']]); + $this->makeViteManifest(['b.js' => ['src' => 'b.js']], 'admin'); + + $this->assertSame('98ca5a789544599b562c9978f3147a0f', ViteFacade::manifestHash()); + $this->assertSame('928a60835978bae84e5381fbb08a38b2', ViteFacade::manifestHash('admin')); + + $this->cleanViteManifest(); + $this->cleanViteManifest('admin'); + } + public function testViteCanSetEntryPointsWithFluentBuilder() { $this->makeViteManifest();