Skip to content

Commit 85e44d1

Browse files
dunglasfabpot
authored andcommitted
[AssetMapper] add support for assets pre-compression
1 parent a8d0da4 commit 85e44d1

File tree

6 files changed

+93
-0
lines changed

6 files changed

+93
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.3
5+
---
6+
7+
* Add support for assets pre-compression
8+
49
7.2
510
---
611

DependencyInjection/Configuration.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Bundle\FullStack;
1818
use Symfony\Component\Asset\Package;
1919
use Symfony\Component\AssetMapper\AssetMapper;
20+
use Symfony\Component\AssetMapper\Compressor\CompressorInterface;
2021
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
2122
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
2223
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
@@ -924,6 +925,29 @@ private function addAssetMapperSection(ArrayNodeDefinition $rootNode, callable $
924925
->info('The directory to store JavaScript vendors.')
925926
->defaultValue('%kernel.project_dir%/assets/vendor')
926927
->end()
928+
->arrayNode('precompress')
929+
->info('Precompress assets with Brotli, Zstandard and gzip.')
930+
->canBeEnabled()
931+
->fixXmlConfig('format')
932+
->fixXmlConfig('extension')
933+
->children()
934+
->arrayNode('formats')
935+
->info('Array of formats to enable. "brotli", "zstandard" and "gzip" are supported. Defaults to all formats supported by the system. The entire list must be provided.')
936+
->prototype('scalar')->end()
937+
->performNoDeepMerging()
938+
->validate()
939+
->ifTrue(static fn (array $v) => array_diff($v, ['brotli', 'zstandard', 'gzip']))
940+
->thenInvalid('Unsupported format: "brotli", "zstandard" and "gzip" are supported.')
941+
->end()
942+
->end()
943+
->arrayNode('extensions')
944+
->info('Array of extensions to compress. The entire list must be provided, no merging occurs.')
945+
->prototype('scalar')->end()
946+
->performNoDeepMerging()
947+
->defaultValue(interface_exists(CompressorInterface::class) ? CompressorInterface::DEFAULT_EXTENSIONS : [])
948+
->end()
949+
->end()
950+
->end()
927951
->end()
928952
->end()
929953
->end()

DependencyInjection/FrameworkExtension.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use Symfony\Component\Asset\PackageInterface;
3333
use Symfony\Component\AssetMapper\AssetMapper;
3434
use Symfony\Component\AssetMapper\Compiler\AssetCompilerInterface;
35+
use Symfony\Component\AssetMapper\Compressor\CompressorInterface;
3536
use Symfony\Component\BrowserKit\AbstractBrowser;
3637
use Symfony\Component\Cache\Adapter\AdapterInterface;
3738
use Symfony\Component\Cache\Adapter\ArrayAdapter;
@@ -1372,6 +1373,26 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
13721373
->replaceArgument(3, $config['importmap_polyfill'])
13731374
->replaceArgument(4, $config['importmap_script_attributes'])
13741375
;
1376+
1377+
if (interface_exists(CompressorInterface::class)) {
1378+
$compressors = [];
1379+
foreach ($config['precompress']['formats'] as $format) {
1380+
$compressors[$format] = new Reference("asset_mapper.compressor.$format");
1381+
}
1382+
1383+
$container->getDefinition('asset_mapper.compressor')->replaceArgument(0, $compressors ?: null);
1384+
1385+
if ($config['precompress']['enabled']) {
1386+
$container
1387+
->getDefinition('asset_mapper.local_public_assets_filesystem')
1388+
->addArgument(new Reference('asset_mapper.compressor'))
1389+
->addArgument($config['precompress']['extensions'])
1390+
;
1391+
}
1392+
} else {
1393+
$container->removeDefinition('asset_mapper.compressor');
1394+
$container->removeDefinition('asset_mapper.assets.command.compress');
1395+
}
13751396
}
13761397

13771398
/**

Resources/config/asset_mapper.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\AssetMapper\AssetMapperInterface;
1818
use Symfony\Component\AssetMapper\AssetMapperRepository;
1919
use Symfony\Component\AssetMapper\Command\AssetMapperCompileCommand;
20+
use Symfony\Component\AssetMapper\Command\CompressAssetsCommand;
2021
use Symfony\Component\AssetMapper\Command\DebugAssetMapperCommand;
2122
use Symfony\Component\AssetMapper\Command\ImportMapAuditCommand;
2223
use Symfony\Component\AssetMapper\Command\ImportMapInstallCommand;
@@ -28,6 +29,11 @@
2829
use Symfony\Component\AssetMapper\Compiler\CssAssetUrlCompiler;
2930
use Symfony\Component\AssetMapper\Compiler\JavaScriptImportPathCompiler;
3031
use Symfony\Component\AssetMapper\Compiler\SourceMappingUrlsCompiler;
32+
use Symfony\Component\AssetMapper\Compressor\BrotliCompressor;
33+
use Symfony\Component\AssetMapper\Compressor\ChainCompressor;
34+
use Symfony\Component\AssetMapper\Compressor\CompressorInterface;
35+
use Symfony\Component\AssetMapper\Compressor\GzipCompressor;
36+
use Symfony\Component\AssetMapper\Compressor\ZstandardCompressor;
3137
use Symfony\Component\AssetMapper\Factory\CachedMappedAssetFactory;
3238
use Symfony\Component\AssetMapper\Factory\MappedAssetFactory;
3339
use Symfony\Component\AssetMapper\ImportMap\ImportMapAuditor;
@@ -254,5 +260,20 @@
254260
->set('asset_mapper.importmap.command.outdated', ImportMapOutdatedCommand::class)
255261
->args([service('asset_mapper.importmap.update_checker')])
256262
->tag('console.command')
263+
264+
->set('asset_mapper.compressor.brotli', BrotliCompressor::class)
265+
->set('asset_mapper.compressor.zstandard', ZstandardCompressor::class)
266+
->set('asset_mapper.compressor.gzip', GzipCompressor::class)
267+
268+
->set('asset_mapper.compressor', ChainCompressor::class)
269+
->args([
270+
abstract_arg('compressor'),
271+
service('logger'),
272+
])
273+
->alias(CompressorInterface::class, 'asset_mapper.compressor')
274+
275+
->set('asset_mapper.assets.command.compress', CompressAssetsCommand::class)
276+
->args([service('asset_mapper.compressor')])
277+
->tag('console.command')
257278
;
258279
};

Resources/config/schema/symfony-1.0.xsd

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@
206206
<xsd:element name="excluded-pattern" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
207207
<xsd:element name="extension" type="asset_mapper_extension" minOccurs="0" maxOccurs="unbounded" />
208208
<xsd:element name="importmap-script-attribute" type="asset_mapper_attribute" minOccurs="0" maxOccurs="unbounded" />
209+
<xsd:element name="precompress" type="asset_mapper_precompress" minOccurs="0" maxOccurs="1" />
209210
</xsd:sequence>
210211
<xsd:attribute name="enabled" type="xsd:boolean" />
211212
<xsd:attribute name="exclude-dotfiles" type="xsd:boolean" />
@@ -230,6 +231,16 @@
230231
<xsd:attribute name="key" type="xsd:string" use="required" />
231232
</xsd:complexType>
232233

234+
<xsd:complexType name="asset_mapper_precompress">
235+
<xsd:sequence>
236+
<xsd:element name="format" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
237+
<xsd:element name="extension" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
238+
</xsd:sequence>
239+
240+
<xsd:attribute name="enabled" type="xsd:boolean" />
241+
</xsd:complexType>
242+
243+
233244
<xsd:simpleType name="missing-import-mode">
234245
<xsd:restriction base="xsd:string">
235246
<xsd:enumeration value="strict" />

Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PHPUnit\Framework\TestCase;
1616
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Configuration;
1717
use Symfony\Bundle\FullStack;
18+
use Symfony\Component\AssetMapper\Compressor\CompressorInterface;
1819
use Symfony\Component\Cache\Adapter\DoctrineAdapter;
1920
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
2021
use Symfony\Component\Config\Definition\Processor;
@@ -141,6 +142,11 @@ public function testAssetMapperCanBeEnabled()
141142
'vendor_dir' => '%kernel.project_dir%/assets/vendor',
142143
'importmap_script_attributes' => [],
143144
'exclude_dotfiles' => true,
145+
'precompress' => [
146+
'enabled' => false,
147+
'formats' => [],
148+
'extensions' => interface_exists(CompressorInterface::class) ? CompressorInterface::DEFAULT_EXTENSIONS : [],
149+
],
144150
];
145151

146152
$this->assertEquals($defaultConfig, $config['asset_mapper']);
@@ -847,6 +853,11 @@ protected static function getBundleDefaultConfig()
847853
'vendor_dir' => '%kernel.project_dir%/assets/vendor',
848854
'importmap_script_attributes' => [],
849855
'exclude_dotfiles' => true,
856+
'precompress' => [
857+
'enabled' => false,
858+
'formats' => [],
859+
'extensions' => interface_exists(CompressorInterface::class) ? CompressorInterface::DEFAULT_EXTENSIONS : [],
860+
],
850861
],
851862
'cache' => [
852863
'pools' => [],

0 commit comments

Comments
 (0)