1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-04 11:24:04 +00:00

Fix ViteBundler not affecting Vite static calls

Replace custom Vite class override with Vite::createAssetPathsUsing() to ensure ViteBundler works for both container and static usage when asset_helper_override is enabled.

Fixes #1388
This commit is contained in:
Faris Alherf 2025-08-07 10:53:02 +03:00
parent 3984d64cfa
commit 37667bd9e7
3 changed files with 126 additions and 39 deletions

View file

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Stancl\Tenancy\Features; namespace Stancl\Tenancy\Features;
use Illuminate\Foundation\Application; use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Vite;
use Stancl\Tenancy\Contracts\Feature; use Stancl\Tenancy\Contracts\Feature;
use Stancl\Tenancy\Overrides\Vite;
use Stancl\Tenancy\Tenancy; use Stancl\Tenancy\Tenancy;
class ViteBundler implements Feature class ViteBundler implements Feature
@ -21,6 +21,8 @@ class ViteBundler implements Feature
public function bootstrap(Tenancy $tenancy): void public function bootstrap(Tenancy $tenancy): void
{ {
$this->app->singleton(\Illuminate\Foundation\Vite::class, Vite::class); Vite::createAssetPathsUsing(function ($path, $secure = null) {
return global_asset($path);
});
} }
} }

View file

@ -1,22 +0,0 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Overrides;
use Illuminate\Foundation\Vite as BaseVite;
class Vite extends BaseVite
{
/**
* Generate an asset path for the application.
*
* @param string $path
* @param bool|null $secure
* @return string
*/
protected function assetPath($path, $secure = null)
{
return global_asset($path);
}
}

View file

@ -3,27 +3,134 @@
declare(strict_types=1); declare(strict_types=1);
use Illuminate\Foundation\Vite; use Illuminate\Foundation\Vite;
use Stancl\Tenancy\Tests\Etc\Tenant; use Illuminate\Support\Facades\Event;
use Stancl\Tenancy\Overrides\Vite as StanclVite; use Illuminate\Contracts\Http\Kernel;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\File;
use Stancl\Tenancy\Middleware\InitializeTenancyByPath;
use Stancl\Tenancy\Bootstrappers\UrlGeneratorBootstrapper;
use Stancl\Tenancy\Actions\CloneRoutesAsTenant;
use Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper;
use Stancl\Tenancy\Controllers\TenantAssetController;
use Stancl\Tenancy\Events\TenancyEnded;
use Stancl\Tenancy\Events\TenancyInitialized;
use Stancl\Tenancy\Features\ViteBundler; use Stancl\Tenancy\Features\ViteBundler;
use Stancl\Tenancy\Listeners\BootstrapTenancy;
use Stancl\Tenancy\Listeners\RevertToCentralContext;
use Stancl\Tenancy\Overrides\TenancyUrlGenerator;
use Stancl\Tenancy\Tests\Etc\Tenant;
test('vite helper uses our custom class', function() { use function Stancl\Tenancy\Tests\pest;
$vite = app(Vite::class);
expect($vite)->toBeInstanceOf(Vite::class);
expect($vite)->not()->toBeInstanceOf(StanclVite::class);
beforeEach(function () {
config([ config([
'tenancy.features' => [ViteBundler::class], 'app.asset_url' => null,
'tenancy.filesystem.asset_helper_override' => true,
'tenancy.bootstrappers' => [FilesystemTenancyBootstrapper::class],
]); ]);
$tenant = Tenant::create(); TenancyUrlGenerator::$prefixRouteNames = false;
TenancyUrlGenerator::$passTenantParameterToRoutes = true;
TenantAssetController::$headers = [];
tenancy()->initialize($tenant); $manifestPath = public_path('build/manifest.json');
File::ensureDirectoryExists(dirname($manifestPath));
File::put($manifestPath, json_encode([
'foo' => [
'file' => 'assets/foo-AbC123.js',
'src' => 'js/foo.js',
],
]));
app()->forgetInstance(Vite::class); $this->tenant = Tenant::create();
$this->assetPath = 'foo';
$vite = app(Vite::class);
expect($vite)->toBeInstanceOf(StanclVite::class);
}); });
test('vite bundler ensures vite assets use global_asset when asset_helper_override is enabled', function () {
config(['tenancy.features' => [ViteBundler::class]]);
app(CloneRoutesAsTenant::class)->handle();
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
tenancy()->initialize($this->tenant);
expect(asset($this->assetPath))
->toBe(route('stancl.tenancy.asset', ['path' => $this->assetPath]))
->and(global_asset($this->assetPath))
->toBe('http://localhost/' . $this->assetPath);
$viteAssetUrl = app(Vite::class)->asset($this->assetPath);
$expectedGlobalUrl = global_asset('build/assets/foo-AbC123.js');
expect($viteAssetUrl)
->toBe($expectedGlobalUrl)
->and($viteAssetUrl)
->not->toBe(route('stancl.tenancy.asset', ['path' => 'build/assets/foo-AbC123.js']));
});
test('vite uses tenant assets when asset_helper_override is enabled without ViteBundler', function () {
config(['tenancy.features' => []]);
app(CloneRoutesAsTenant::class)->handle();
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
tenancy()->initialize($this->tenant);
expect(asset($this->assetPath))
->toBe(route('stancl.tenancy.asset', ['path' => $this->assetPath]))
->and(global_asset($this->assetPath))
->toBe('http://localhost/' . $this->assetPath);
$viteAssetUrl = app(Vite::class)->asset($this->assetPath);
expect($viteAssetUrl)
->toBe(route('stancl.tenancy.asset', ['path' => 'build/assets/foo-AbC123.js']))
->and($viteAssetUrl)
->not->toBe(global_asset('build/assets/foo-AbC123.js'));
});
test('vite asset helper works correctly with path identification', function (bool $kernelIdentification) {
TenancyUrlGenerator::$prefixRouteNames = true;
TenancyUrlGenerator::$passTenantParameterToRoutes = true;
config([
'tenancy.filesystem.asset_helper_override' => true,
'tenancy.features' => [ViteBundler::class],
'tenancy.identification.default_middleware' => InitializeTenancyByPath::class,
'tenancy.bootstrappers' => array_merge([UrlGeneratorBootstrapper::class], config('tenancy.bootstrappers')),
]);
Event::listen(TenancyInitialized::class, BootstrapTenancy::class);
Event::listen(TenancyEnded::class, RevertToCentralContext::class);
$viteRoute = Route::prefix('{tenant}')->get('/vite_helper', function () {
return app(Vite::class)->asset('foo');
})->name('tenant.helper.vite');
$assetRoute = Route::prefix('{tenant}')->get('/asset_helper', function () {
return asset('foo');
})->name('tenant.helper.asset');
if ($kernelIdentification) {
app(Kernel::class)->pushMiddleware(InitializeTenancyByPath::class);
} else {
$viteRoute->middleware(InitializeTenancyByPath::class);
$assetRoute->middleware(InitializeTenancyByPath::class);
}
app(CloneRoutesAsTenant::class)->handle();
tenancy()->initialize(Tenant::create());
expect(pest()->get(route('tenant.helper.asset'))->getContent())
->toBe(route('stancl.tenancy.asset', ['path' => 'foo']));
expect(pest()->get(route('tenant.helper.vite'))->getContent())
->toBe(global_asset('build/assets/foo-AbC123.js'));
})->with([
'kernel identification' => true,
'route-level identification' => false,
]);