Skip to content

Commit 243c87f

Browse files
committed
Cache Entry Point Files
- Altered entry point lookup to check if cache has been added and if it has then cache the file - Altered collection to set the cache for every lookup - Altered services file to create a cache service - Updated tests to test caching - Updated cache warming to warm all the builds Github Issue: #3
1 parent 9c89795 commit 243c87f

File tree

7 files changed

+165
-5
lines changed

7 files changed

+165
-5
lines changed

src/Asset/EntrypointLookup.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace Symfony\WebpackEncoreBundle\Asset;
1111

12+
use Psr\Cache\CacheItemPoolInterface;
1213
use Symfony\WebpackEncoreBundle\Exception\EntrypointNotFoundException;
1314

1415
/**
@@ -26,6 +27,8 @@ class EntrypointLookup implements EntrypointLookupInterface
2627

2728
private $returnedFiles = [];
2829

30+
private $cache;
31+
2932
public function __construct(string $entrypointJsonPath)
3033
{
3134
$this->entrypointJsonPath = $entrypointJsonPath;
@@ -41,6 +44,11 @@ public function getCssFiles(string $entryName): array
4144
return $this->getEntryFiles($entryName, 'css');
4245
}
4346

47+
public function setCache(CacheItemPoolInterface $cache)
48+
{
49+
$this->cache = $cache;
50+
}
51+
4452
/**
4553
* Resets the state of this service.
4654
*/
@@ -84,6 +92,13 @@ private function validateEntryName(string $entryName)
8492

8593
private function getEntriesData(): array
8694
{
95+
if ($this->cache) {
96+
$cached = $this->cache->getItem('entrypoint_lookup.data.'.$this->getCacheName());
97+
if ($cached->isHit()) {
98+
return $cached->get();
99+
}
100+
}
101+
87102
if (null === $this->entriesData) {
88103
if (!file_exists($this->entrypointJsonPath)) {
89104
throw new \InvalidArgumentException(sprintf('Could not find the entrypoints file from Webpack: the file "%s" does not exist.', $this->entrypointJsonPath));
@@ -100,6 +115,29 @@ private function getEntriesData(): array
100115
}
101116
}
102117

118+
if ($this->cache) {
119+
$cached->set($this->entriesData);
120+
$this->cache->save($cached);
121+
}
122+
103123
return $this->entriesData;
104124
}
125+
126+
private function getCacheName()
127+
{
128+
return str_replace('/', '.', $this->entrypointJsonPath);
129+
}
130+
131+
public function warmUp($cacheDir)
132+
{
133+
// If cache is enabled then run through the parser since it will save the results to cache
134+
if (!$this->cache) {
135+
return;
136+
}
137+
try {
138+
$this->getEntriesData();
139+
} catch (\InvalidArgumentException $e) {
140+
// If the fails are invalid for any reason just ignore it.
141+
}
142+
}
105143
}

src/Asset/EntrypointLookupInterface.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99

1010
namespace Symfony\WebpackEncoreBundle\Asset;
1111

12+
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
1213
use Symfony\Contracts\Service\ResetInterface;
1314
use Symfony\WebpackEncoreBundle\Exception\EntrypointNotFoundException;
1415

15-
interface EntrypointLookupInterface extends ResetInterface
16+
interface EntrypointLookupInterface extends ResetInterface, WarmableInterface
1617
{
1718
/**
1819
* @throws EntrypointNotFoundException if an entry name is passed that does not exist in entrypoints.json

src/Asset/TagRenderer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function __construct(
2626
@trigger_error(sprintf('The "$entrypointLookupCollection" argument in method "%s()" must be an instance of EntrypointLookupCollection.', __METHOD__), E_USER_DEPRECATED);
2727

2828
$this->entrypointLookupCollection = new EntrypointLookupCollection(
29-
new ServiceLocator(['_default' => function() use ($entrypointLookupCollection) {
29+
new ServiceLocator(['_default' => function () use ($entrypointLookupCollection) {
3030
return $entrypointLookupCollection;
3131
}])
3232
);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony WebpackEncoreBundle package.
5+
* (c) Fabien Potencier <[email protected]>
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
namespace Symfony\WebpackEncoreBundle\CacheWarmer;
11+
12+
use Symfony\Component\DependencyInjection\ContainerInterface;
13+
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
14+
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookupCollection;
15+
16+
class EntrypointCacheWarmer implements CacheWarmerInterface
17+
{
18+
private $builds;
19+
private $container;
20+
21+
public function __construct(array $builds, ContainerInterface $container)
22+
{
23+
$this->builds = $builds;
24+
$this->container = $container;
25+
}
26+
27+
public function isOptional()
28+
{
29+
return true;
30+
}
31+
32+
public function warmUp($cacheDir)
33+
{
34+
$entryPointCollection = $this->container->get('webpack_encore.entrypoint_lookup_collection');
35+
36+
if ($entryPointCollection instanceof EntrypointLookupCollection) {
37+
foreach ($this->builds as $build => $path) {
38+
$fullPath = $path.'/entrypoints.json';
39+
40+
// If the file does not exist then just skip past this entry point.
41+
if (!file_exists($fullPath)) {
42+
continue;
43+
}
44+
45+
$entryPointLookup = $entryPointCollection->getEntrypointLookup($build);
46+
$entryPointLookup->warmUp($cacheDir);
47+
}
48+
}
49+
}
50+
}

src/DependencyInjection/WebpackEncoreExtension.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,18 @@ public function load(array $configs, ContainerBuilder $container)
2929
$config = $this->processConfiguration($configuration, $configs);
3030

3131
$factories = [
32-
'_default' => new Reference($this->entrypointFactory($container, '_default', $config['output_path']))
32+
'_default' => new Reference($this->entrypointFactory($container, '_default', $config['output_path'])),
3333
];
3434
foreach ($config['builds'] as $name => $path) {
3535
$factories[$name] = new Reference($this->entrypointFactory($container, $name, $path));
36-
};
36+
}
37+
38+
$builds = [
39+
'_default' => $config['output_path'],
40+
];
41+
$builds = array_merge($builds, $config['builds']);
42+
$container->getDefinition('webpack_encore.entrypoint_lookup.warmer')
43+
->setArgument(0, $builds);
3744

3845
$container->getDefinition('webpack_encore.entrypoint_lookup')
3946
->replaceArgument(0, $factories['_default']);
@@ -44,7 +51,11 @@ public function load(array $configs, ContainerBuilder $container)
4451
private function entrypointFactory(ContainerBuilder $container, string $name, string $path): string
4552
{
4653
$id = sprintf('webpack_encore.entrypoint_lookup[%s]', $name);
47-
$container->setDefinition($id, new Definition(EntrypointLookup::class, [$path.'/entrypoints.json']));
54+
$cache = $container->findDefinition('webpack_encore.cache');
55+
$definition = new Definition(EntrypointLookup::class, [$path.'/entrypoints.json']);
56+
$definition->addMethodCall('setCache', [$cache]);
57+
$container->setDefinition($id, $definition);
58+
4859
return $id;
4960
}
5061
}

src/Resources/config/services.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
<service id="webpack_encore.entrypoint_lookup" class="Symfony\WebpackEncoreBundle\Asset\EntrypointLookup">
1111
<argument /> <!-- entrypoints.json path -->
12+
<call method="setCache">
13+
<argument key="$cache" type="service" id="webpack_encore.cache" />
14+
</call>
1215
</service>
1316
<service id="webpack_encore.entrypoint_lookup_collection" class="Symfony\WebpackEncoreBundle\Asset\EntrypointLookupCollection">
1417
<argument /> <!-- build list of entrypoints path -->
@@ -32,5 +35,22 @@
3235
</service>
3336
</argument>
3437
</service>
38+
39+
<service id="webpack_encore.entrypoint_lookup.warmer" class="Symfony\WebpackEncoreBundle\CacheWarmer\EntrypointCacheWarmer">
40+
<tag name="kernel.cache_warmer" />
41+
<argument />
42+
<argument type="service" id="Symfony\Component\DependencyInjection\ContainerInterface" />
43+
</service>
44+
45+
<service id="webpack_encore.cache_fallback" class="Symfony\Component\Cache\Adapter\FilesystemAdapter">
46+
<argument />
47+
<argument>0</argument>
48+
<argument key="$directory">%kernel.cache_dir%/encore/</argument>
49+
</service>
50+
51+
<service id="webpack_encore.cache" class="Symfony\Component\Cache\Adapter\PhpArrayAdapter">
52+
<argument key="$file">%kernel.cache_dir%/encore/lookup.cache</argument>
53+
<argument key="$fallbackPool" type="service" id="webpack_encore.cache_fallback"/>
54+
</service>
3555
</services>
3656
</container>

tests/Asset/EntrypointLookupTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Symfony\WebpackEncoreBundle\Tests\Asset;
44

5+
use Symfony\Component\Cache\Adapter\ArrayAdapter;
6+
use Symfony\Component\Cache\Adapter\NullAdapter;
57
use Symfony\WebpackEncoreBundle\Asset\EntrypointLookup;
68
use PHPUnit\Framework\TestCase;
79
use Symfony\WebpackEncoreBundle\Exception\EntrypointNotFoundException;
@@ -144,4 +146,42 @@ public function testExceptionOnEntryWithExtension()
144146
{
145147
$this->entrypointLookup->getJavaScriptFiles('my_entry.js');
146148
}
149+
150+
public function testCachingEntryPointLookupCacheMissed()
151+
{
152+
$filename = tempnam(sys_get_temp_dir(), 'WebpackEncoreBundle');
153+
file_put_contents($filename, self::$testJson);
154+
155+
$cache = new ArrayAdapter();
156+
$entrypointLookup = new EntrypointLookup($filename);
157+
$entrypointLookup->setCache($cache);
158+
159+
$this->assertEquals(
160+
['file1.js', 'file2.js'],
161+
$entrypointLookup->getJavaScriptFiles('my_entry')
162+
);
163+
// Test it saved the result to cache
164+
$cached = $cache->getItem('entrypoint_lookup.data.' . str_replace('/', '.', $filename));
165+
$this->assertTrue($cached->isHit());
166+
$this->assertEquals(json_decode(self::$testJson, true), $cached->get());
167+
}
168+
169+
public function testCachingEntryPointLookupCacheHit()
170+
{
171+
$filename = tempnam(sys_get_temp_dir(), 'WebpackEncoreBundle');
172+
file_put_contents($filename, self::$testJson);
173+
174+
$cache = new ArrayAdapter();
175+
$entrypointLookup = new EntrypointLookup($filename);
176+
$entrypointLookup->setCache($cache);
177+
178+
$cached = $cache->getItem('entrypoint_lookup.data');
179+
$cached->set(json_decode(self::$testJson, true));
180+
$cache->save($cached);
181+
182+
$this->assertEquals(
183+
['file1.js', 'file2.js'],
184+
$entrypointLookup->getJavaScriptFiles('my_entry')
185+
);
186+
}
147187
}

0 commit comments

Comments
 (0)