Skip to content

Commit 4c5fb18

Browse files
committed
feat: use cache file to replace Symfony commands
1 parent 8c0ca89 commit 4c5fb18

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Storybook\CacheWarmer;
6+
7+
use Symfony\Component\Config\ConfigCacheFactory;
8+
use Symfony\Component\Config\ConfigCacheFactoryInterface;
9+
use Symfony\Component\Config\ConfigCacheInterface;
10+
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
11+
12+
class StorybookCacheWarmer implements CacheWarmerInterface
13+
{
14+
private ConfigCacheFactory $configCacheFactory;
15+
16+
public function __construct(
17+
private readonly ?string $cacheDir,
18+
private readonly bool $debug,
19+
private readonly string $projectDir,
20+
private readonly array $storybookConfig,
21+
private readonly array $twigConfig,
22+
private readonly array $twigComponentConfig,
23+
) {
24+
}
25+
26+
public function isOptional(): bool
27+
{
28+
return true;
29+
}
30+
31+
public function warmUp(string $cacheDir, ?string $buildDir = null): array
32+
{
33+
$this->getConfigCacheFactory()->cache(
34+
$this->cacheDir.'/symfony_parameters.json',
35+
function (ConfigCacheInterface $cache) {
36+
$this->generateSymfonyParameters($cache);
37+
}
38+
);
39+
40+
return [];
41+
}
42+
43+
/**
44+
* Provides the ConfigCache factory implementation, falling back to a
45+
* default implementation if necessary.
46+
*/
47+
private function getConfigCacheFactory(): ConfigCacheFactoryInterface
48+
{
49+
$this->configCacheFactory ??= new ConfigCacheFactory($this->debug);
50+
51+
return $this->configCacheFactory;
52+
}
53+
54+
private function generateSymfonyParameters(ConfigCacheInterface $cache): void
55+
{
56+
$parameters = [
57+
'kernel_project_dir' => $this->projectDir,
58+
'storybook_config' => $this->storybookConfig,
59+
'twig_config' => $this->twigConfig,
60+
'twig_component_config' => $this->twigComponentConfig,
61+
];
62+
63+
$cache->write(json_encode($parameters, JSON_PRETTY_PRINT));
64+
}
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Storybook\DependencyInjection\Compiler;
6+
7+
use Symfony\Component\Config\Definition\ConfigurationInterface;
8+
use Symfony\Component\Config\Definition\Processor;
9+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
10+
use Symfony\Component\DependencyInjection\ContainerBuilder;
11+
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
12+
13+
class CacheWarmerPass implements CompilerPassInterface
14+
{
15+
private ?array $extensionConfig = null;
16+
17+
public function process(ContainerBuilder $container): void
18+
{
19+
$cacheWarmerDefinition = $container->getDefinition('storybook.cache_warmer');
20+
21+
$cacheWarmerDefinition
22+
->setArgument(3, $this->getConfig($container, $container->getExtension('storybook')))
23+
->setArgument(4, $this->getConfig($container, $container->getExtension('twig')))
24+
->setArgument(5, $this->getConfig($container, $container->getExtension('twig_component')))
25+
;
26+
}
27+
28+
private function getConfigForExtension(ExtensionInterface $extension, ContainerBuilder $container)
29+
{
30+
$extensionAlias = $extension->getAlias();
31+
32+
if (isset($this->extensionConfig[$extensionAlias])) {
33+
return $this->extensionConfig[$extensionAlias];
34+
}
35+
36+
$configs = $container->getExtensionConfig($extensionAlias);
37+
38+
$configuration = $extension instanceof ConfigurationInterface ? $extension : $extension->getConfiguration($configs, $container);
39+
40+
return $this->extensionConfig[$extensionAlias] = (new Processor())->processConfiguration($configuration, $configs);
41+
}
42+
43+
private function getConfig(ContainerBuilder $container, ExtensionInterface $extension): array
44+
{
45+
return $container->resolveEnvPlaceholders(
46+
$container->getParameterBag()->resolveValue(
47+
$this->getConfigForExtension($extension, $container)
48+
), true
49+
);
50+
}
51+
}

src/DependencyInjection/StorybookExtension.php

+10
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
use Storybook\ArgsProcessor\StorybookArgsProcessor;
66
use Storybook\Attributes\AsArgsProcessor;
77
use Storybook\Attributes\AsComponentMock;
8+
use Storybook\CacheWarmer\StorybookCacheWarmer;
89
use Storybook\Command\GeneratePreviewCommand;
910
use Storybook\Command\StorybookInitCommand;
1011
use Storybook\Controller\StorybookController;
12+
use Storybook\DependencyInjection\Compiler\CacheWarmerPass;
1113
use Storybook\DependencyInjection\Compiler\ComponentMockPass;
1214
use Storybook\EventListener\ProxyRequestListener;
1315
use Storybook\Exception\UnauthorizedStoryException;
@@ -159,6 +161,14 @@ static function (ChildDefinition $definition, AsComponentMock $attributeInstance
159161
->setArgument(0, new Reference('request_stack'))
160162
->setArgument(1, new Reference('event_dispatcher'))
161163
->addTag('kernel.event_subscriber');
164+
165+
$container->register('storybook.cache_warmer', StorybookCacheWarmer::class)
166+
->setArgument(0, $container->getParameter('kernel.cache_dir').'/storybook')
167+
->setArgument(1, $container->getParameter('kernel.debug'))
168+
->setArgument(2, $container->getParameter('kernel.project_dir'))
169+
->setArgument(3, new AbstractArgument(\sprintf('Provided in "%s".', CacheWarmerPass::class)))
170+
->setArgument(4, new AbstractArgument(\sprintf('Provided in "%s".', CacheWarmerPass::class)))
171+
->addTag('kernel.cache_warmer');
162172
}
163173

164174
public function getConfigTreeBuilder(): TreeBuilder

src/StorybookBundle.php

+3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
namespace Storybook;
44

55
use Storybook\DependencyInjection\Compiler\ArgsProcessorPass;
6+
use Storybook\DependencyInjection\Compiler\CacheWarmerPass;
67
use Storybook\DependencyInjection\Compiler\ComponentMockPass;
78
use Storybook\DependencyInjection\StorybookExtension;
9+
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
810
use Symfony\Component\DependencyInjection\ContainerBuilder;
911
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
1012
use Symfony\Component\HttpKernel\Bundle\Bundle;
@@ -18,6 +20,7 @@ public function build(ContainerBuilder $container): void
1820
{
1921
$container->addCompilerPass(new ArgsProcessorPass());
2022
$container->addCompilerPass(new ComponentMockPass());
23+
$container->addCompilerPass(new CacheWarmerPass());
2124
}
2225

2326
public function getContainerExtension(): ?ExtensionInterface

0 commit comments

Comments
 (0)