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('