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.

162 lines
5.2 KiB

  1. <?php namespace Wpstudio\AssetsManifest\Classes\Bundlers;
  2. use Cms\Classes\Theme;
  3. use Illuminate\Support\Collection;
  4. use Wpstudio\AssetsManifest\Classes\AssetsManifestException;
  5. use Config;
  6. use Wpstudio\AssetsManifest\Classes\Bundlers\Vite\ViteEntrypoint;
  7. class ViteBundler extends Bundler
  8. {
  9. private array $assetsInjected = [];
  10. public function getEntrypointAssets(string $entrypointName): string
  11. {
  12. $entrypoint = $this->getViteEntrypoint($entrypointName);
  13. $tags = collect();
  14. if ($entrypoint->hasImports()) {
  15. $entrypoint->getImports()->filter(fn(string $entrypointNameFromImports) => !$this->hasInjected($entrypointNameFromImports))->each(
  16. fn(string $entrypointNameFromImports) => $this->injectAsset(
  17. $entrypointNameFromImports,
  18. $tags,
  19. $this->getEntrypointAssets($entrypointNameFromImports)
  20. )
  21. );
  22. }
  23. if ($entrypoint->hasCss()) {
  24. $entrypoint->getCss()->filter(fn(string $cssAssetRelativeFilePath) => !$this->hasInjected($cssAssetRelativeFilePath))->each(
  25. fn(string $cssAssetRelativeFilePath) => $this->injectAsset(
  26. $cssAssetRelativeFilePath,
  27. $tags,
  28. $this->getStylesheetTag($this->getViteAssetUrl($cssAssetRelativeFilePath))
  29. )
  30. );
  31. }
  32. if (!$this->hasInjected($entrypointName)) {
  33. $this->injectAsset($entrypointName, $tags, $this->getScriptTag($entrypointName, $entrypoint));
  34. }
  35. return $tags->implode(PHP_EOL);
  36. }
  37. public function getViteDevClientScriptTag(): string
  38. {
  39. return sprintf(
  40. '<script type="module" src="%s"></script>',
  41. sprintf(
  42. '%s/@vite/client',
  43. $this->getViteDevServerAddress(),
  44. )
  45. );
  46. }
  47. /**
  48. * @param string $entrypointName
  49. * @return string
  50. * @throws AssetsManifestException
  51. */
  52. public function getEntrypointStylesheets(string $entrypointName): string
  53. {
  54. $entrypoint = $this->getViteEntrypoint($entrypointName);
  55. $stylesheetTags = collect();
  56. if ($entrypoint->hasCss()) {
  57. $entrypoint
  58. ->getCss()
  59. ->filter(fn(string $cssAssetRelativeFilePath) => !$this->hasInjected($cssAssetRelativeFilePath))
  60. ->each(
  61. fn(string $cssAssetRelativeFilePath) => $this->injectAsset(
  62. $cssAssetRelativeFilePath,
  63. $stylesheetTags,
  64. $this->getStylesheetTag($this->getViteAssetUrl($cssAssetRelativeFilePath)
  65. )
  66. )
  67. );
  68. }
  69. return $stylesheetTags->implode(PHP_EOL);
  70. }
  71. public function getStylesheetTag(string $href): string
  72. {
  73. return sprintf(
  74. '<link rel="stylesheet" href="%s">',
  75. $href,
  76. );
  77. }
  78. public function getScriptTag(string $entrypointName, ?ViteEntrypoint $entrypoint = null): string
  79. {
  80. return sprintf(
  81. '<script type="module" src="%s" %s></script>',
  82. $this->isViteDevEnabled() ?
  83. sprintf(
  84. '%s/%s',
  85. $this->getViteDevServerAddress(),
  86. $this->getViteEntrypointSrc($entrypointName)
  87. ) :
  88. $this->getViteAssetUrl($entrypoint->getFile()),
  89. !$this->isViteDevEnabled() ? 'async defer' : '',
  90. );
  91. }
  92. private function getViteEntrypointSrc(string $entrypointName): string
  93. {
  94. return sprintf(
  95. '%s/%s/%s',
  96. Config::get('wpstudio.assetsmanifest::vite_path_src'),
  97. Config::get('wpstudio.assetsmanifest::vite_dir_entrypoints'),
  98. $entrypointName,
  99. );
  100. }
  101. private function getViteEntrypoint(string $entrypointName): ViteEntrypoint
  102. {
  103. return new ViteEntrypoint($this->getEntrypoint(
  104. !starts_with($entrypointName, '_') ?
  105. $this->getViteEntrypointSrc($entrypointName) :
  106. $entrypointName
  107. ));
  108. }
  109. private function getViteAssetUrl(string $relativeAssetsFilePath): string
  110. {
  111. return sprintf(
  112. '/themes/%s/%s/%s',
  113. Theme::getActiveTheme()->getDirName(),
  114. Config::get('wpstudio.assetsmanifest::vite_path_build'),
  115. $relativeAssetsFilePath
  116. );
  117. }
  118. public function isViteDevEnabled(): bool
  119. {
  120. return Config::get('wpstudio.assetsmanifest::vite_dev_enabled');
  121. }
  122. private function getViteDevServerAddress(): string
  123. {
  124. return sprintf(
  125. '%s://%s:%s',
  126. Config::get('wpstudio.assetsmanifest::vite_dev_server_protocol'),
  127. Config::get('wpstudio.assetsmanifest::vite_dev_server_host'),
  128. Config::get('wpstudio.assetsmanifest::vite_dev_server_port'),
  129. );
  130. }
  131. private function hasInjected(string $assetsUid): bool
  132. {
  133. return in_array($assetsUid, $this->assetsInjected);
  134. }
  135. private function injectAsset(string $assetsUid, Collection $tags, string $assetTag): void
  136. {
  137. $this->assetsInjected[] = $assetsUid;
  138. $tags->add($assetTag);
  139. }
  140. }