diff --git a/src/Asset/EntrypointLookup.php b/src/Asset/EntrypointLookup.php index 8f435b94..4dfa60ae 100644 --- a/src/Asset/EntrypointLookup.php +++ b/src/Asset/EntrypointLookup.php @@ -29,11 +29,14 @@ class EntrypointLookup implements EntrypointLookupInterface, IntegrityDataProvid private $cache; - public function __construct(string $entrypointJsonPath, CacheItemPoolInterface $cache = null, string $cacheKey = null) + private $strictMode; + + public function __construct(string $entrypointJsonPath, CacheItemPoolInterface $cache = null, string $cacheKey = null, bool $strictMode = true) { $this->entrypointJsonPath = $entrypointJsonPath; $this->cache = $cache; $this->cacheKey = $cacheKey; + $this->strictMode = $strictMode; } public function getJavaScriptFiles(string $entryName): array @@ -69,7 +72,7 @@ private function getEntryFiles(string $entryName, string $key): array { $this->validateEntryName($entryName); $entriesData = $this->getEntriesData(); - $entryData = $entriesData['entrypoints'][$entryName]; + $entryData = $entriesData['entrypoints'][$entryName] ?? []; if (!isset($entryData[$key])) { // If we don't find the file type then just send back nothing. @@ -87,7 +90,7 @@ private function getEntryFiles(string $entryName, string $key): array private function validateEntryName(string $entryName) { $entriesData = $this->getEntriesData(); - if (!isset($entriesData['entrypoints'][$entryName])) { + if (!isset($entriesData['entrypoints'][$entryName]) && $this->strictMode) { $withoutExtension = substr($entryName, 0, strrpos($entryName, '.')); if (isset($entriesData['entrypoints'][$withoutExtension])) { @@ -113,6 +116,9 @@ private function getEntriesData(): array } if (!file_exists($this->entrypointJsonPath)) { + if (!$this->strictMode) { + return []; + } throw new \InvalidArgumentException(sprintf('Could not find the entrypoints file from Webpack: the file "%s" does not exist.', $this->entrypointJsonPath)); } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 3c150dc2..da1ffbd3 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -43,6 +43,10 @@ public function getConfigTreeBuilder() ->info('Enable caching of the entry point file(s)') ->defaultFalse() ->end() + ->booleanNode('strict_mode') + ->info('Throw an exception if the entrypoints.json file is missing or an entry is missing from the data') + ->defaultTrue() + ->end() ->arrayNode('builds') ->useAttributeAsKey('name') ->normalizeKeys(false) diff --git a/src/DependencyInjection/WebpackEncoreExtension.php b/src/DependencyInjection/WebpackEncoreExtension.php index 338c598c..98fed30e 100644 --- a/src/DependencyInjection/WebpackEncoreExtension.php +++ b/src/DependencyInjection/WebpackEncoreExtension.php @@ -36,12 +36,12 @@ public function load(array $configs, ContainerBuilder $container) $cacheKeys = []; if (false !== $config['output_path']) { - $factories['_default'] = $this->entrypointFactory($container, '_default', $config['output_path'], $config['cache']); + $factories['_default'] = $this->entrypointFactory($container, '_default', $config['output_path'], $config['cache'], $config['strict_mode']); $cacheKeys['_default'] = $config['output_path'].'/'.self::ENTRYPOINTS_FILE_NAME; } foreach ($config['builds'] as $name => $path) { - $factories[$name] = $this->entrypointFactory($container, $name, $path, $config['cache']); + $factories[$name] = $this->entrypointFactory($container, $name, $path, $config['cache'], $config['strict_mode']); $cacheKeys[rawurlencode($name)] = $path.'/'.self::ENTRYPOINTS_FILE_NAME; } @@ -64,10 +64,15 @@ public function load(array $configs, ContainerBuilder $container) ->replaceArgument(2, $defaultAttributes); } - private function entrypointFactory(ContainerBuilder $container, string $name, string $path, bool $cacheEnabled): Reference + private function entrypointFactory(ContainerBuilder $container, string $name, string $path, bool $cacheEnabled, bool $strictMode): Reference { $id = $this->getEntrypointServiceId($name); - $arguments = [$path.'/'.self::ENTRYPOINTS_FILE_NAME, $cacheEnabled ? new Reference('webpack_encore.cache') : null, $name]; + $arguments = [ + $path.'/'.self::ENTRYPOINTS_FILE_NAME, + $cacheEnabled ? new Reference('webpack_encore.cache') : null, + $name, + $strictMode, + ]; $container->setDefinition($id, new Definition(EntrypointLookup::class, $arguments)); return new Reference($id); diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 18dbbaf9..456ae1e8 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -106,6 +106,32 @@ public function testCacheWarmer() $this->assertEquals(['_default' => 0, 'different_build' => 1], $data[0]); } + /** + * @expectedException \Twig\Error\RuntimeError + * @expectedExceptionMessageRegExp /Could not find the entrypoints file/ + */ + public function testEnabledStrictMode_throwsException_ifBuildMissing() + { + $kernel = new WebpackEncoreIntegrationTestKernel(true); + $kernel->outputPath = 'missing_build'; + $kernel->builds = ['different_build' => 'missing_build']; + $kernel->boot(); + $container = $kernel->getContainer(); + $container->get('twig')->render('@integration_test/template.twig'); + } + + public function testDisabledStrictMode_ignoresMissingBuild() + { + $kernel = new WebpackEncoreIntegrationTestKernel(true); + $kernel->outputPath = 'missing_build'; + $kernel->strictMode = false; + $kernel->builds = ['different_build' => 'missing_build']; + $kernel->boot(); + $container = $kernel->getContainer(); + $html = $container->get('twig')->render('@integration_test/template.twig'); + self::assertSame('', trim($html)); + } + public function testAutowireableInterfaces() { $kernel = new WebpackEncoreIntegrationTestKernel(true); @@ -118,6 +144,11 @@ public function testAutowireableInterfaces() class WebpackEncoreIntegrationTestKernel extends Kernel { private $enableAssets; + public $strictMode = true; + public $outputPath = __DIR__.'/fixtures/build'; + public $builds = [ + 'different_build' => __DIR__.'/fixtures/different_build' + ]; public function __construct($enableAssets) { @@ -152,12 +183,11 @@ public function registerContainerConfiguration(LoaderInterface $loader) ]); $container->loadFromExtension('webpack_encore', [ - 'output_path' => __DIR__.'/fixtures/build', + 'output_path' => $this->outputPath, 'cache' => true, 'crossorigin' => false, - 'builds' => [ - 'different_build' => __DIR__.'/fixtures/different_build', - ], + 'builds' => $this->builds, + 'strict_mode' => $this->strictMode, ]); $container->register(WebpackEncoreCacheWarmerTester::class)