You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
5.3 KiB

<?php namespace Wpstudio\AssetsManifest\Classes\Bundlers;
use Cms\Classes\Theme;
use Illuminate\Support\Collection;
use Wpstudio\AssetsManifest\Classes\AssetsManifestException;
use Config;
use Wpstudio\AssetsManifest\Classes\Bundlers\Vite\ViteEntrypoint;
class ViteBundler extends Bundler
{
private array $assetsInjected = [];
public function getEntrypointAssets(string $entrypointName): string
{
$entrypoint = $this->getViteEntrypoint($entrypointName);
$tags = collect();
if ($entrypoint->hasImports()) {
$entrypoint->getImports()->filter(fn(string $entrypointNameFromImports) => !$this->hasInjected($entrypointNameFromImports))->each(
fn(string $entrypointNameFromImports) => $this->injectAsset(
$entrypointNameFromImports,
$tags,
$this->getEntrypointAssets($entrypointNameFromImports)
)
);
}
if ($entrypoint->hasCss()) {
$entrypoint->getCss()->filter(fn(string $cssAssetRelativeFilePath) => !$this->hasInjected($cssAssetRelativeFilePath))->each(
fn(string $cssAssetRelativeFilePath) => $this->injectAsset(
$cssAssetRelativeFilePath,
$tags,
$this->getStylesheetTag($this->getViteAssetUrl($cssAssetRelativeFilePath))
)
);
}
if (!$this->hasInjected($entrypointName)) {
$this->injectAsset($entrypointName, $tags, $this->getScriptTag($entrypointName, $entrypoint));
}
return $tags->implode(PHP_EOL);
}
public function getViteDevClientScriptTag(): string
{
return sprintf(
'<script type="module" src="%s"></script>',
sprintf(
'%s/@vite/client',
$this->getViteDevServerAddress(),
)
);
}
/**
* @param string $entrypointName
* @return string
* @throws AssetsManifestException
*/
public function getEntrypointStylesheets(string $entrypointName): string
{
if ($this->isViteDevEnabled()) {
return '';
}
$entrypoint = $this->getViteEntrypoint($entrypointName);
$stylesheetTags = collect();
if ($entrypoint->hasCss()) {
$entrypoint
->getCss()
->filter(fn(string $cssAssetRelativeFilePath) => !$this->hasInjected($cssAssetRelativeFilePath))
->each(
fn(string $cssAssetRelativeFilePath) => $this->injectAsset(
$cssAssetRelativeFilePath,
$stylesheetTags,
$this->getStylesheetTag($this->getViteAssetUrl($cssAssetRelativeFilePath)
)
)
);
}
return $stylesheetTags->implode(PHP_EOL);
}
private function getStylesheetTag(string $href): string
{
return sprintf(
'<link rel="stylesheet" href="%s">',
$href,
);
}
private function getScriptTag(string $entrypointName, ViteEntrypoint $entrypoint): string
{
return sprintf(
'<script type="module" src="%s" %s></script>',
$this->isViteDevEnabled() ?
sprintf(
'%s/%s',
$this->getViteDevServerAddress(),
$this->getViteEntrypointSrc($entrypointName)
) :
$this->getViteAssetUrl($entrypoint->getFile()),
!$this->isViteDevEnabled() ? 'async defer' : '',
);
}
private function getViteEntrypointSrc(string $entrypointName): string
{
return sprintf(
'%s/%s/%s',
Config::get('wpstudio.assetsmanifest::vite_path_src'),
Config::get('wpstudio.assetsmanifest::vite_dir_entrypoints'),
$entrypointName,
);
}
private function getViteEntrypoint(string $entrypointName): ViteEntrypoint
{
return new ViteEntrypoint($this->getEntrypoint(
!starts_with($entrypointName, '_') ?
$this->getViteEntrypointSrc($entrypointName) :
$entrypointName
));
}
private function getViteAssetUrl(string $relativeAssetsFilePath): string
{
return sprintf(
'/themes/%s/%s/%s',
Theme::getActiveTheme()->getDirName(),
Config::get('wpstudio.assetsmanifest::vite_path_build'),
$relativeAssetsFilePath
);
}
public function isViteDevEnabled(): bool
{
return Config::get('wpstudio.assetsmanifest::vite_dev_enabled');
}
private function getViteDevServerAddress(): string
{
return sprintf(
'%s://%s:%s',
Config::get('wpstudio.assetsmanifest::vite_dev_server_protocol'),
Config::get('wpstudio.assetsmanifest::vite_dev_server_host'),
Config::get('wpstudio.assetsmanifest::vite_dev_server_port'),
);
}
private function hasInjected(string $assetsUid): bool
{
return in_array($assetsUid, $this->assetsInjected);
}
private function injectAsset(string $assetsUid, Collection $tags, string $assetTag): void
{
$this->assetsInjected[] = $assetsUid;
$tags->add($assetTag);
}
}