diff --git a/src/BladeService.php b/src/BladeService.php index 31af937a..c4159ea9 100644 --- a/src/BladeService.php +++ b/src/BladeService.php @@ -271,6 +271,32 @@ public function componentNameToPath($name): string return ''; } + /** + * Determine if view path is the conventional view for a class-based component. + */ + public function isClassBasedComponentView(string $path): bool + { + $path = str_replace('\\', '/', $path); + + if (! preg_match('#^(.*/components/)(.+)$#i', $path, $matches)) { + return false; + } + + $afterComponents = $matches[2]; + + if (! Str::endsWith($afterComponents, '.blade.php')) { + return false; + } + + $name = str_replace('/', '.', Str::beforeLast($afterComponents, '.blade.php')); + + if ($name === '') { + return false; + } + + return $this->hasClassBasedComponent($name); + } + /** * Determine if a component resolves to a class rather than a blade view. * diff --git a/src/BlazeManager.php b/src/BlazeManager.php index 2ed5db99..c9810ae2 100644 --- a/src/BlazeManager.php +++ b/src/BlazeManager.php @@ -119,7 +119,11 @@ public function compile(string $template, ?string $path = null): string $directives = new Directives($source); - if ($path && ($directives->blaze() || $this->config->shouldCompile($path))) { + $shouldWrap = $path + && ($directives->blaze() || $this->config->shouldCompile($path)) + && ! $this->blade->isClassBasedComponentView($path); + + if ($shouldWrap) { $output = $this->wrapper->wrap($output, $path, $source); } elseif ($this->isDebugging() && ! $this->isFolding() && $path) { $output = $this->instrumenter->profileView($output, $path, $source); @@ -231,11 +235,13 @@ public function compileForFolding(string $template, ?string $path = null): strin } $directives = new Directives($source); - $shouldWrap = $this->config->shouldFold($path) - || $this->config->shouldMemoize($path) - || $this->config->shouldCompile($path); + $shouldWrap = ($directives->blaze() + || $this->config->shouldFold($path) + || $this->config->shouldMemoize($path) + || $this->config->shouldCompile($path)) + && ! $this->blade->isClassBasedComponentView($path); - if ($directives->blaze() || $shouldWrap) { + if ($shouldWrap) { $output = $this->wrapper->wrap($output, $path, $source); } diff --git a/tests/BladeServiceTest.php b/tests/BladeServiceTest.php index 7dae5470..804b89f6 100644 --- a/tests/BladeServiceTest.php +++ b/tests/BladeServiceTest.php @@ -50,3 +50,21 @@ expect(app(BladeService::class)->customConditions())->toContain('disk'); }); + +test('isClassBasedComponentView detects app convention class component', function () { + expect(app(BladeService::class)->isClassBasedComponentView( + fixture_path('views/components/alert.blade.php') + ))->toBeTrue(); +}); + +test('isClassBasedComponentView is false for anonymous components', function () { + expect(app(BladeService::class)->isClassBasedComponentView( + fixture_path('views/components/input.blade.php') + ))->toBeFalse(); +}); + +test('isClassBasedComponentView handles nested names', function () { + expect(app(BladeService::class)->isClassBasedComponentView( + fixture_path('views/components/dummy/foo.blade.php') + ))->toBeFalse(); +}); diff --git a/tests/BlazeManagerTest.php b/tests/BlazeManagerTest.php index 52a5947d..2514a8e5 100644 --- a/tests/BlazeManagerTest.php +++ b/tests/BlazeManagerTest.php @@ -54,3 +54,11 @@ expect($manager->viewContainsExpiredFrontMatter($view))->toBeFalse(); }); + +test('class-based component renders when its directory is optimized', function () { + Blaze::optimize()->in(fixture_path('views/components')); + + // Alert maps to App\View\Components\Alert in workbench. + expect(trim(Blade::render(''))) + ->toBe('
hello
'); +}); diff --git a/tests/fixtures/views/components/alert.blade.php b/tests/fixtures/views/components/alert.blade.php new file mode 100644 index 00000000..e5c8d6d6 --- /dev/null +++ b/tests/fixtures/views/components/alert.blade.php @@ -0,0 +1,3 @@ +@blaze + +
{{ $message }}
\ No newline at end of file diff --git a/workbench/app/View/Components/Alert.php b/workbench/app/View/Components/Alert.php index 111ad9f4..a23d63bb 100644 --- a/workbench/app/View/Components/Alert.php +++ b/workbench/app/View/Components/Alert.php @@ -3,11 +3,14 @@ namespace App\View\Components; use Illuminate\View\Component; +use Illuminate\Contracts\View\View; class Alert extends Component { - public function render(): string + public function __construct(public string $message = '') {} + + public function render(): View { - return '
'; + return view('components.alert'); } }