diff --git a/CHANGELOG.md b/CHANGELOG.md
index fc337e8..5c317e6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,8 @@
## Next
- make services privates.
+- add tests for EntrypointRenderer, EntrypointsLookup and TagRenderer.
+- add preload option (symfony/web-link)
## v5.0.1
diff --git a/composer.json b/composer.json
index f2ee866..4104626 100644
--- a/composer.json
+++ b/composer.json
@@ -39,7 +39,8 @@
"friendsofphp/php-cs-fixer": "^3.9",
"phpstan/phpstan": "^1.8",
"phpunit/phpunit": "^9.5",
- "symfony/phpunit-bridge": "^4.4 || ^5.0 || ^6.0 || ^7.0"
+ "symfony/phpunit-bridge": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/web-link": "^4.4 || ^5.0 || ^6.0 || ^7.0"
},
"scripts": {
"cs-fix": "php8.1 vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php",
diff --git a/composer.lock b/composer.lock
index 6349663..e176f96 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "0621f19a1a733ca72da436652082e9aa",
+ "content-hash": "10c9d61736ec57babdfdb4c006dcc26b",
"packages": [
{
"name": "psr/cache",
@@ -1031,16 +1031,16 @@
},
{
"name": "symfony/framework-bundle",
- "version": "v6.3.6",
+ "version": "v6.3.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/framework-bundle.git",
- "reference": "5b5dca452a70d06d0463d3aeae640b2d034ef485"
+ "reference": "dba20792c726c30d455626eddfb2db008f64085f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/5b5dca452a70d06d0463d3aeae640b2d034ef485",
- "reference": "5b5dca452a70d06d0463d3aeae640b2d034ef485",
+ "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/dba20792c726c30d455626eddfb2db008f64085f",
+ "reference": "dba20792c726c30d455626eddfb2db008f64085f",
"shasum": ""
},
"require": {
@@ -1155,7 +1155,7 @@
"description": "Provides a tight integration between Symfony components and the Symfony full-stack framework",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/framework-bundle/tree/v6.3.6"
+ "source": "https://github.com/symfony/framework-bundle/tree/v6.3.7"
},
"funding": [
{
@@ -1171,20 +1171,20 @@
"type": "tidelift"
}
],
- "time": "2023-10-12T17:41:20+00:00"
+ "time": "2023-10-26T18:15:14+00:00"
},
{
"name": "symfony/http-client",
- "version": "v6.3.6",
+ "version": "v6.3.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
- "reference": "ab8446f997efb9913627e9da10fa784d2182fe92"
+ "reference": "cd67fcaf4524ec6ae5d9b2d9497682d7ad3ce57d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-client/zipball/ab8446f997efb9913627e9da10fa784d2182fe92",
- "reference": "ab8446f997efb9913627e9da10fa784d2182fe92",
+ "url": "https://api.github.com/repos/symfony/http-client/zipball/cd67fcaf4524ec6ae5d9b2d9497682d7ad3ce57d",
+ "reference": "cd67fcaf4524ec6ae5d9b2d9497682d7ad3ce57d",
"shasum": ""
},
"require": {
@@ -1247,7 +1247,7 @@
"http"
],
"support": {
- "source": "https://github.com/symfony/http-client/tree/v6.3.6"
+ "source": "https://github.com/symfony/http-client/tree/v6.3.7"
},
"funding": [
{
@@ -1263,7 +1263,7 @@
"type": "tidelift"
}
],
- "time": "2023-10-06T10:08:56+00:00"
+ "time": "2023-10-29T12:41:36+00:00"
},
{
"name": "symfony/http-client-contracts",
@@ -1345,16 +1345,16 @@
},
{
"name": "symfony/http-foundation",
- "version": "v6.3.6",
+ "version": "v6.3.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "c186627f52febe09c6d5270b04f8462687a250a6"
+ "reference": "59d1837d5d992d16c2628cd0d6b76acf8d69b33e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/c186627f52febe09c6d5270b04f8462687a250a6",
- "reference": "c186627f52febe09c6d5270b04f8462687a250a6",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/59d1837d5d992d16c2628cd0d6b76acf8d69b33e",
+ "reference": "59d1837d5d992d16c2628cd0d6b76acf8d69b33e",
"shasum": ""
},
"require": {
@@ -1402,7 +1402,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-foundation/tree/v6.3.6"
+ "source": "https://github.com/symfony/http-foundation/tree/v6.3.7"
},
"funding": [
{
@@ -1418,20 +1418,20 @@
"type": "tidelift"
}
],
- "time": "2023-10-17T11:32:53+00:00"
+ "time": "2023-10-28T23:55:27+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v6.3.6",
+ "version": "v6.3.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "4945f5001b06ff9080cd3d8f1f9f069094c0d156"
+ "reference": "6d4098095f93279d9536a0e9124439560cc764d0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4945f5001b06ff9080cd3d8f1f9f069094c0d156",
- "reference": "4945f5001b06ff9080cd3d8f1f9f069094c0d156",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6d4098095f93279d9536a0e9124439560cc764d0",
+ "reference": "6d4098095f93279d9536a0e9124439560cc764d0",
"shasum": ""
},
"require": {
@@ -1515,7 +1515,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-kernel/tree/v6.3.6"
+ "source": "https://github.com/symfony/http-kernel/tree/v6.3.7"
},
"funding": [
{
@@ -1531,7 +1531,7 @@
"type": "tidelift"
}
],
- "time": "2023-10-21T13:12:51+00:00"
+ "time": "2023-10-29T14:31:45+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -2818,16 +2818,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
- "version": "v3.35.1",
+ "version": "v3.37.1",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
- "reference": "ec1ccc264994b6764882669973ca435cf05bab08"
+ "reference": "c3fe76976081ab871aa654e872da588077e19679"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/ec1ccc264994b6764882669973ca435cf05bab08",
- "reference": "ec1ccc264994b6764882669973ca435cf05bab08",
+ "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/c3fe76976081ab871aa654e872da588077e19679",
+ "reference": "c3fe76976081ab871aa654e872da588077e19679",
"shasum": ""
},
"require": {
@@ -2899,7 +2899,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
- "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.35.1"
+ "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.37.1"
},
"funding": [
{
@@ -2907,7 +2907,7 @@
"type": "github"
}
],
- "time": "2023-10-12T13:47:26+00:00"
+ "time": "2023-10-29T20:51:23+00:00"
},
{
"name": "myclabs/deep-copy",
@@ -3137,16 +3137,16 @@
},
{
"name": "phpstan/phpstan",
- "version": "1.10.39",
+ "version": "1.10.40",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4"
+ "reference": "93c84b5bf7669920d823631e39904d69b9c7dc5d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d9dedb0413f678b4d03cbc2279a48f91592c97c4",
- "reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/93c84b5bf7669920d823631e39904d69b9c7dc5d",
+ "reference": "93c84b5bf7669920d823631e39904d69b9c7dc5d",
"shasum": ""
},
"require": {
@@ -3195,7 +3195,7 @@
"type": "tidelift"
}
],
- "time": "2023-10-17T15:46:26+00:00"
+ "time": "2023-10-30T14:48:31+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -3619,6 +3619,62 @@
],
"time": "2023-09-19T05:39:22+00:00"
},
+ {
+ "name": "psr/link",
+ "version": "2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/link.git",
+ "reference": "84b159194ecfd7eaa472280213976e96415433f7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/link/zipball/84b159194ecfd7eaa472280213976e96415433f7",
+ "reference": "84b159194ecfd7eaa472280213976e96415433f7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.0.0"
+ },
+ "suggest": {
+ "fig/link-util": "Provides some useful PSR-13 utilities"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Link\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for HTTP links",
+ "homepage": "https://github.com/php-fig/link",
+ "keywords": [
+ "http",
+ "http-link",
+ "link",
+ "psr",
+ "psr-13",
+ "rest"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/link/tree/2.0.1"
+ },
+ "time": "2021-03-11T23:00:27+00:00"
+ },
{
"name": "sebastian/cli-parser",
"version": "1.0.1",
@@ -5274,6 +5330,89 @@
],
"time": "2023-09-18T10:38:32+00:00"
},
+ {
+ "name": "symfony/web-link",
+ "version": "v6.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/web-link.git",
+ "reference": "0989ca617d0703cdca501a245f10e194ff22315b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/web-link/zipball/0989ca617d0703cdca501a245f10e194ff22315b",
+ "reference": "0989ca617d0703cdca501a245f10e194ff22315b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/link": "^1.1|^2.0"
+ },
+ "conflict": {
+ "symfony/http-kernel": "<5.4"
+ },
+ "provide": {
+ "psr/link-implementation": "1.0|2.0"
+ },
+ "require-dev": {
+ "symfony/http-kernel": "^5.4|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\WebLink\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kévin Dunglas",
+ "email": "dunglas@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Manages links between resources",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "dns-prefetch",
+ "http",
+ "http2",
+ "link",
+ "performance",
+ "prefetch",
+ "preload",
+ "prerender",
+ "psr13",
+ "push"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/web-link/tree/v6.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-04-21T14:41:17+00:00"
+ },
{
"name": "theseer/tokenizer",
"version": "1.2.1",
diff --git a/src/Asset/EntrypointRenderer.php b/src/Asset/EntrypointRenderer.php
index 968fd23..b3d78b0 100644
--- a/src/Asset/EntrypointRenderer.php
+++ b/src/Asset/EntrypointRenderer.php
@@ -11,6 +11,7 @@ class EntrypointRenderer
private EntrypointsLookupCollection $entrypointsLookupCollection;
private TagRendererCollection $tagRendererCollection;
private bool $useAbsoluteUrl;
+ private string $preload;
private ?RouterInterface $router;
private ?EventDispatcherInterface $eventDispatcher;
@@ -18,18 +19,23 @@ class EntrypointRenderer
private $returnedReactRefresh = [];
private $returnedViteLegacyScripts = [];
- private $renderedFiles = [];
+ private $renderedFiles = [
+ 'scripts' => [],
+ 'styles' => [],
+ ];
public function __construct(
EntrypointsLookupCollection $entrypointsLookupCollection,
TagRendererCollection $tagRendererCollection,
- bool $useAbsoluteUrl,
+ bool $useAbsoluteUrl = false,
+ string $preload = 'link-tag',
RouterInterface $router = null,
EventDispatcherInterface $eventDispatcher = null
) {
$this->entrypointsLookupCollection = $entrypointsLookupCollection;
$this->tagRendererCollection = $tagRendererCollection;
$this->useAbsoluteUrl = $useAbsoluteUrl;
+ $this->preload = $preload;
$this->router = $router;
$this->eventDispatcher = $eventDispatcher;
}
@@ -71,12 +77,25 @@ public function getMode(string $configName = null): ?string
return $entrypointsLookup->isBuild() ? 'build' : 'dev';
}
- public function reset()
+ public function reset(): void
{
$this->returnedViteClients = [];
$this->returnedReactRefresh = [];
$this->returnedViteLegacyScripts = [];
- $this->renderedFiles = [];
+ $this->renderedFiles = [
+ 'scripts' => [],
+ 'styles' => [],
+ ];
+ }
+
+ public function getRenderedScripts(): array
+ {
+ return $this->renderedFiles['scripts'];
+ }
+
+ public function getRenderedStyles(): array
+ {
+ return $this->renderedFiles['styles'];
}
public function renderScripts(
@@ -141,7 +160,7 @@ public function renderScripts(
/* normal js scripts */
foreach ($entrypointsLookup->getJSFiles($entryName) as $filePath) {
- if (false === \in_array($filePath, $this->renderedFiles, true)) {
+ if (false === \in_array($filePath, $this->renderedFiles['scripts'], true)) {
$tags[] = $tagRenderer->createScriptTag(
array_merge(
[
@@ -153,7 +172,7 @@ public function renderScripts(
)
);
- $this->renderedFiles[] = $filePath;
+ $this->renderedFiles['scripts'][] = $filePath;
}
}
@@ -162,7 +181,7 @@ public function renderScripts(
$id = self::pascalToKebab("vite-legacy-entry-$entryName");
$filePath = $entrypointsLookup->getLegacyJSFile($entryName);
- if (false === \in_array($filePath, $this->renderedFiles, true)) {
+ if (false === \in_array($filePath, $this->renderedFiles['scripts'], true)) {
$tags[] = $tagRenderer->createScriptTag(
[
'nomodule' => true,
@@ -175,7 +194,7 @@ public function renderScripts(
InlineContent::getSystemJSInlineCode($id)
);
- $this->renderedFiles[] = $filePath;
+ $this->renderedFiles['scripts'][] = $filePath;
}
}
@@ -201,35 +220,35 @@ public function renderLinks(
$tags = [];
foreach ($entrypointsLookup->getCSSFiles($entryName) as $filePath) {
- if (false === \in_array($filePath, $this->renderedFiles, true)) {
+ if (false === \in_array($filePath, $this->renderedFiles['styles'], true)) {
$tags[] = $tagRenderer->createLinkStylesheetTag(
$this->completeURL($filePath, $useAbsoluteUrl),
array_merge(['integrity' => $entrypointsLookup->getFileHash($filePath)], $options['attr'] ?? [])
);
- $this->renderedFiles[] = $filePath;
+ $this->renderedFiles['styles'][] = $filePath;
}
}
if ($isBuild) {
foreach ($entrypointsLookup->getJavascriptDependencies($entryName) as $filePath) {
- if (false === \in_array($filePath, $this->renderedFiles, true)) {
+ if (false === \in_array($filePath, $this->renderedFiles['scripts'], true)) {
$tags[] = $tagRenderer->createModulePreloadLinkTag(
$this->completeURL($filePath, $useAbsoluteUrl),
['integrity' => $entrypointsLookup->getFileHash($filePath)]
);
- $this->renderedFiles[] = $filePath;
+ $this->renderedFiles['scripts'][] = $filePath;
}
}
}
if ($isBuild && isset($options['preloadDynamicImports']) && true === $options['preloadDynamicImports']) {
foreach ($entrypointsLookup->getJavascriptDynamicDependencies($entryName) as $filePath) {
- if (false === \in_array($filePath, $this->renderedFiles, true)) {
+ if (false === \in_array($filePath, $this->renderedFiles['scripts'], true)) {
$tags[] = $tagRenderer->createModulePreloadLinkTag(
$this->completeURL($filePath, $useAbsoluteUrl),
['integrity' => $entrypointsLookup->getFileHash($filePath)]
);
- $this->renderedFiles[] = $filePath;
+ $this->renderedFiles['scripts'][] = $filePath;
}
}
}
@@ -245,6 +264,12 @@ public function renderTags(array $tags, $isBuild, $toString)
}
}
+ if ('link-tag' !== $this->preload) {
+ $tags = array_filter($tags, function (Tag $tag) {
+ return !$tag->isModulePreload();
+ });
+ }
+
return $toString
? implode('', array_map(function ($tagEvent) {
return TagRenderer::generateTag($tagEvent);
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
index 8ebec11..0640a4b 100644
--- a/src/DependencyInjection/Configuration.php
+++ b/src/DependencyInjection/Configuration.php
@@ -35,6 +35,11 @@ public function getConfigTreeBuilder(): TreeBuilder
->info('Prepend the rendered link and script tags with an absolute URL.')
->defaultValue(false)
->end()
+ ->enumNode('preload')
+ ->values(['none', 'link-tag', 'link-header'])
+ ->info('preload all rendered script and link tags automatically via the http2 Link header. (symfony/web-link is required) Instead will be used.')
+ ->defaultValue('link-tag')
+ ->end()
->arrayNode('script_attributes')
->info('Key/value pair of attributes to render on all script tags')
->example('{ defer: true, referrerpolicy: "origin" }')
diff --git a/src/DependencyInjection/PentatrionViteExtension.php b/src/DependencyInjection/PentatrionViteExtension.php
index 6405185..e86d9a7 100644
--- a/src/DependencyInjection/PentatrionViteExtension.php
+++ b/src/DependencyInjection/PentatrionViteExtension.php
@@ -11,6 +11,7 @@
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+use Symfony\Component\WebLink\EventListener\AddLinkHeaderListener;
class PentatrionViteExtension extends Extension
{
@@ -58,6 +59,15 @@ public function load(array $bundleConfigs, ContainerBuilder $container): void
];
}
+ if ('link-header' === $bundleConfig['preload']) {
+ if (!class_exists(AddLinkHeaderListener::class)) {
+ throw new \LogicException('To use the "preload" option, the WebLink component must be installed. Try running "composer require symfony/web-link".');
+ }
+ } else {
+ $container->removeDefinition('pentatrion_vite.preload_assets_event_listener');
+ }
+ $container->setParameter('pentatrion_vite.preload', $bundleConfig['preload']);
+
$container->setParameter('pentatrion_vite.public_directory', self::preparePublicDirectory($bundleConfig['public_directory']));
$container->setParameter('pentatrion_vite.default_config', $defaultConfigName);
$container->setParameter('pentatrion_vite.configs', $configs);
@@ -73,10 +83,6 @@ public function load(array $bundleConfigs, ContainerBuilder $container): void
$container->getDefinition('pentatrion_vite.tag_renderer_collection')
->addArgument(ServiceLocatorTagPass::register($container, $tagRendererFactories))
->addArgument($defaultConfigName);
-
- // $container->getDefinition('pentatrion_vite.tag_renderer')
- // ->replaceArgument(0, $defaultConfigName)
- // ->replaceArgument(1, $configs);
}
private function entrypointsLookupFactory(
diff --git a/src/EventListener/PreloadAssetsEventListener.php b/src/EventListener/PreloadAssetsEventListener.php
new file mode 100644
index 0000000..729a18b
--- /dev/null
+++ b/src/EventListener/PreloadAssetsEventListener.php
@@ -0,0 +1,65 @@
+entrypointRenderer = $entrypointRenderer;
+ }
+
+ public function onKernelResponse(ResponseEvent $event): void
+ {
+ if (!$event->isMainRequest()) {
+ return;
+ }
+
+ $request = $event->getRequest();
+
+ if (null === $linkProvider = $request->attributes->get('_links')) {
+ $request->attributes->set(
+ '_links',
+ new GenericLinkProvider()
+ );
+ }
+
+ /** @var GenericLinkProvider $linkProvider */
+ $linkProvider = $request->attributes->get('_links');
+
+ foreach ($this->entrypointRenderer->getRenderedScripts() as $href) {
+ $link = $this->createLink('preload', $href)->withAttribute('as', 'script');
+
+ $linkProvider = $linkProvider->withLink($link);
+ }
+
+ foreach ($this->entrypointRenderer->getRenderedStyles() as $href) {
+ $link = $this->createLink('preload', $href)->withAttribute('as', 'style');
+
+ $linkProvider = $linkProvider->withLink($link);
+ }
+
+ $request->attributes->set('_links', $linkProvider);
+ }
+
+ private function createLink(string $rel, string $href): Link
+ {
+ return new Link($rel, $href);
+ }
+
+ public static function getSubscribedEvents()
+ {
+ return [
+ // must run before AddLinkHeaderListener
+ 'kernel.response' => ['onKernelResponse', 50],
+ ];
+ }
+}
diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml
index d04f74f..d646c60 100644
--- a/src/Resources/config/services.yaml
+++ b/src/Resources/config/services.yaml
@@ -23,6 +23,7 @@ services:
- "@pentatrion_vite.entrypoints_lookup_collection"
- "@pentatrion_vite.tag_renderer_collection"
- "%pentatrion_vite.absolute_url%"
+ - "%pentatrion_vite.preload%"
- "@?router"
- "@?event_dispatcher"
@@ -69,3 +70,10 @@ services:
- "%pentatrion_vite.absolute_url%"
- "@?router"
- true
+
+ pentatrion_vite.preload_assets_event_listener:
+ class: Pentatrion\ViteBundle\EventListener\PreloadAssetsEventListener
+ tags: ["kernel.event_subscriber"]
+ arguments:
+ - "@pentatrion_vite.entrypoint_renderer"
+
diff --git a/tests/Asset/EntrypointRendererTest.php b/tests/Asset/EntrypointRendererTest.php
index fff2520..c712c79 100644
--- a/tests/Asset/EntrypointRendererTest.php
+++ b/tests/Asset/EntrypointRendererTest.php
@@ -210,10 +210,7 @@ public function testBasic($config, $entryName, $expectedStrings)
$entrypointRenderer = new EntrypointRenderer(
$this->getEntrypointsLookupCollection($entrypointsLookup),
- $this->getBasicTagRendererCollection(),
- false,
- null,
- null,
+ $this->getBasicTagRendererCollection()
);
$this->assertEquals(
@@ -237,10 +234,7 @@ public function testRenderOnlyOneViteClient()
$entrypointsLookup = $this->getEntrypointsLookup('duplication-dev');
$entrypointRenderer = new EntrypointRenderer(
$this->getEntrypointsLookupCollection($entrypointsLookup),
- $this->getBasicTagRendererCollection(),
- false,
- null,
- null,
+ $this->getBasicTagRendererCollection()
);
$this->assertEquals(
@@ -256,10 +250,7 @@ public function testRenderOnlyOneReactRefresh()
$entrypointsLookup = $this->getEntrypointsLookup('duplication-dev');
$entrypointRenderer = new EntrypointRenderer(
$this->getEntrypointsLookupCollection($entrypointsLookup),
- $this->getBasicTagRendererCollection(),
- false,
- null,
- null,
+ $this->getBasicTagRendererCollection()
);
$this->assertEquals(
@@ -276,10 +267,7 @@ public function testRenderOnlyOneFile()
$entrypointsLookup = $this->getEntrypointsLookup('duplication-build');
$entrypointRenderer = new EntrypointRenderer(
$this->getEntrypointsLookupCollection($entrypointsLookup),
- $this->getBasicTagRendererCollection(),
- false,
- null,
- null,
+ $this->getBasicTagRendererCollection()
);
$expectedScripts = ''
@@ -327,10 +315,7 @@ public function testRenderOnlyOneLegacyInlineContent()
$entrypointsLookup = $this->getEntrypointsLookup('legacy-build');
$entrypointRenderer = new EntrypointRenderer(
$this->getEntrypointsLookupCollection($entrypointsLookup),
- $this->getBasicTagRendererCollection(),
- false,
- null,
- null,
+ $this->getBasicTagRendererCollection()
);
$this->assertEquals(
@@ -378,6 +363,7 @@ public function testRenderWithAbsoluteUrl()
$this->getEntrypointsLookupCollection($entrypointsLookupBasicBuild),
$this->getBasicTagRendererCollection(),
true,
+ 'link-tag',
$router,
null,
);
@@ -391,6 +377,7 @@ public function testRenderWithAbsoluteUrl()
$this->getEntrypointsLookupCollection($entrypointsLookupBasicBuild),
$this->getBasicTagRendererCollection(),
false,
+ 'link-tag',
$router,
null,
);
@@ -404,6 +391,7 @@ public function testRenderWithAbsoluteUrl()
$this->getEntrypointsLookupCollection($entrypointsLookupBasicDev),
$this->getBasicTagRendererCollection(),
true,
+ 'link-tag',
$router,
null,
);
@@ -415,15 +403,46 @@ public function testRenderWithAbsoluteUrl()
);
}
- public function testRenderAndPreloadDynamicImports()
+ public function testRenderWithoutPreload()
{
$entrypointsLookup = $this->getEntrypointsLookup('basic-build');
$entrypointRenderer = new EntrypointRenderer(
$this->getEntrypointsLookupCollection($entrypointsLookup),
$this->getBasicTagRendererCollection(),
false,
- null,
- null,
+ 'none'
+ );
+
+ $this->assertEquals(
+ '',
+ $entrypointRenderer->renderLinks('with-async', [
+ 'preloadDynamicImports' => true,
+ ]),
+ 'render only css files'
+ );
+
+ $entrypointRenderer = new EntrypointRenderer(
+ $this->getEntrypointsLookupCollection($entrypointsLookup),
+ $this->getBasicTagRendererCollection(),
+ false,
+ 'link-header'
+ );
+
+ $this->assertEquals(
+ '',
+ $entrypointRenderer->renderLinks('with-async', [
+ 'preloadDynamicImports' => true,
+ ]),
+ 'render only css files'
+ );
+ }
+
+ public function testRenderAndPreloadDynamicImports()
+ {
+ $entrypointsLookup = $this->getEntrypointsLookup('basic-build');
+ $entrypointRenderer = new EntrypointRenderer(
+ $this->getEntrypointsLookupCollection($entrypointsLookup),
+ $this->getBasicTagRendererCollection()
);
$this->assertEquals(
@@ -472,6 +491,7 @@ public function testRenderWithEvent()
$this->getEntrypointsLookupCollection($entrypointsLookup),
$this->getBasicTagRendererCollection(['defer' => true], ['referrerpolicy' => 'origin']),
false,
+ 'link-tag',
null,
$dispatcher,
);
@@ -527,10 +547,7 @@ public function testMultipleConfigInBuild()
$entrypointRenderer = new EntrypointRenderer(
$entrypointsLookupCollection,
- $tagRendererCollection,
- false,
- null,
- null,
+ $tagRendererCollection
);
$this->assertEquals(
@@ -582,10 +599,7 @@ public function testMultipleConfigInDev()
$entrypointRenderer = new EntrypointRenderer(
$entrypointsLookupCollection,
- $tagRendererCollection,
- false,
- null,
- null,
+ $tagRendererCollection
);
$expectedScripts = ''
diff --git a/tests/fixtures/entrypoints/config2-build/entrypoints.json b/tests/fixtures/entrypoints/config2-build/entrypoints.json
index 6720c31..18bec33 100644
--- a/tests/fixtures/entrypoints/config2-build/entrypoints.json
+++ b/tests/fixtures/entrypoints/config2-build/entrypoints.json
@@ -1,5 +1,5 @@
{
- "base": "/build/",
+ "base": "/build-config2/",
"entryPoints": {
"app-2": {
"assets": [],