Skip to content

Commit 244604f

Browse files
committed
feature #50264 [AssetMapper] Flexible public paths + relative path imports + possibility of "building" assets (weaverryan)
This PR was squashed before being merged into the 6.3 branch. Discussion ---------- [AssetMapper] Flexible public paths + relative path imports + possibility of "building" assets | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | None | License | MIT | Doc PR | Still a TODO in general Hi! Working hard to see where AssetMapper adjustments need to be made. 3 changes proposed here: 1) AssetMapper's "public output path" awareness was moved to a new `PublicAssetsPathResolver` service 2) The asset compilers were updated to use relative paths when adjusting paths in files. 3) Drop the "mime type" stuff entirely - except for the "dev server" so it can set the content-type. Asset compiler's can use `$mappedAsset->getPublicExtension()` instead. ### Why these changes? 1) **Allow public/assets/ structure to flatten/change** The new `PublicAssetsPathResolver` + the "adjustment" of import/url paths in the compilers allows the "output" directory structure to be decoupled from the source structure. Currently the output structure matches your "source" structure, so you get things like `public/assets/styles/app.css` or `public/assets/bundles/easyadmin/foo.css`. We could add an option in the future (or the user could decorate `PublicAssetsPathResolver` immediately) to "flatten" everything into just `public/assets/`. 2) **Allow for building of certain files, like `.scss` or `.jsx`** These changes allow users to create... more controversial functionality that could build certain files automatically. For example, you could have: ```twig <link rel="stylesheet" href="{{ asset('styles/app.scss') }}"> ``` Locally, I have a custom compiler that executes the `dart-sass` binary to convert this to CSS. Then, by decorating `PublicAssetsPathResolver`, I'm changing the public path for `styles/app.scss` so that it ends with `.css`. This is about 50 lines of code that results in the sass-compiled CSS file being properly rendered onto the page. I have a similar compiler + path decorator locally that compiles `.jsx` => `.js` using the babel binary. Usage: ```javascript // assets/app.js import HelloWorldComponent from './HelloReact.jsx'; // ... render like normal ``` I realize usage like this is more controversial... however it's also super pragmatic if you DO use Sass or have some React components. The alternative would be to run the `sass` binary manually, import the built `.css` file and probably ignore that file from `git`. Thanks for your consideration :). Cheers! Commits ------- 53e297db92 [AssetMapper] Flexible public paths + relative path imports + possibility of "building" assets
2 parents 5c2072b + 2e62222 commit 244604f

File tree

3 files changed

+33
-18
lines changed

3 files changed

+33
-18
lines changed

DependencyInjection/FrameworkExtension.php

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,13 +1271,6 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
12711271
$container->removeDefinition('asset_mapper.asset_package');
12721272
}
12731273

1274-
$publicDirName = $this->getPublicDirectoryName($container);
1275-
$container->getDefinition('asset_mapper')
1276-
->setArgument(3, $config['public_prefix'])
1277-
->setArgument(4, $publicDirName)
1278-
->setArgument(5, $config['extensions'])
1279-
;
1280-
12811274
$paths = $config['paths'];
12821275
foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) {
12831276
if ($container->fileExists($dir = $bundle['path'].'/Resources/public') || $container->fileExists($dir = $bundle['path'].'/public')) {
@@ -1287,11 +1280,20 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
12871280
$container->getDefinition('asset_mapper.repository')
12881281
->setArgument(0, $paths);
12891282

1283+
$publicDirName = $this->getPublicDirectoryName($container);
1284+
$container->getDefinition('asset_mapper.public_assets_path_resolver')
1285+
->setArgument(1, $config['public_prefix'])
1286+
->setArgument(2, $publicDirName);
1287+
12901288
$container->getDefinition('asset_mapper.command.compile')
1291-
->setArgument(4, $publicDirName);
1289+
->setArgument(5, $publicDirName);
12921290

12931291
if (!$config['server']) {
12941292
$container->removeDefinition('asset_mapper.dev_server_subscriber');
1293+
} else {
1294+
$container->getDefinition('asset_mapper.dev_server_subscriber')
1295+
->setArgument(1, $config['public_prefix'])
1296+
->setArgument(2, $config['extensions']);
12951297
}
12961298

12971299
$container->getDefinition('asset_mapper.compiler.css_asset_url_compiler')
@@ -1302,9 +1304,9 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
13021304

13031305
$container
13041306
->getDefinition('asset_mapper.importmap.manager')
1305-
->replaceArgument(1, $config['importmap_path'])
1306-
->replaceArgument(2, $config['vendor_dir'])
1307-
->replaceArgument(3, $config['provider'])
1307+
->replaceArgument(2, $config['importmap_path'])
1308+
->replaceArgument(3, $config['vendor_dir'])
1309+
->replaceArgument(4, $config['provider'])
13081310
;
13091311

13101312
$container

Resources/config/asset_mapper.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use Symfony\Component\AssetMapper\ImportMap\ImportMapManager;
2929
use Symfony\Component\AssetMapper\ImportMap\ImportMapRenderer;
3030
use Symfony\Component\AssetMapper\MapperAwareAssetPackage;
31+
use Symfony\Component\AssetMapper\Path\PublicAssetsPathResolver;
3132
use Symfony\Component\HttpKernel\Event\RequestEvent;
3233

3334
return static function (ContainerConfigurator $container) {
@@ -36,17 +37,23 @@
3637
->args([
3738
service('asset_mapper.repository'),
3839
service('asset_mapper_compiler'),
39-
param('kernel.project_dir'),
40-
abstract_arg('asset public prefix'),
41-
abstract_arg('public directory name'),
42-
abstract_arg('extensions map'),
40+
service('asset_mapper.public_assets_path_resolver'),
4341
])
4442
->alias(AssetMapperInterface::class, 'asset_mapper')
43+
4544
->set('asset_mapper.repository', AssetMapperRepository::class)
4645
->args([
4746
abstract_arg('array of asset mapper paths'),
4847
param('kernel.project_dir'),
4948
])
49+
50+
->set('asset_mapper.public_assets_path_resolver', PublicAssetsPathResolver::class)
51+
->args([
52+
param('kernel.project_dir'),
53+
abstract_arg('asset public prefix'),
54+
abstract_arg('public directory name'),
55+
])
56+
5057
->set('asset_mapper.asset_package', MapperAwareAssetPackage::class)
5158
->decorate('assets._default_package')
5259
->args([
@@ -57,11 +64,14 @@
5764
->set('asset_mapper.dev_server_subscriber', AssetMapperDevServerSubscriber::class)
5865
->args([
5966
service('asset_mapper'),
67+
abstract_arg('asset public prefix'),
68+
abstract_arg('extensions map'),
6069
])
6170
->tag('kernel.event_subscriber', ['event' => RequestEvent::class])
6271

6372
->set('asset_mapper.command.compile', AssetMapperCompileCommand::class)
6473
->args([
74+
service('asset_mapper.public_assets_path_resolver'),
6575
service('asset_mapper'),
6676
service('asset_mapper.importmap.manager'),
6777
service('filesystem'),
@@ -102,6 +112,7 @@
102112
->set('asset_mapper.importmap.manager', ImportMapManager::class)
103113
->args([
104114
service('asset_mapper'),
115+
service('asset_mapper.public_assets_path_resolver'),
105116
abstract_arg('importmap.php path'),
106117
abstract_arg('vendor directory'),
107118
abstract_arg('provider'),

Tests/DependencyInjection/XmlFrameworkExtensionTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,11 @@ public function testAssetMapper()
7878
{
7979
$container = $this->createContainerFromFile('asset_mapper');
8080

81-
$definition = $container->getDefinition('asset_mapper');
82-
$this->assertSame('/assets_path/', $definition->getArgument(3));
83-
$this->assertSame(['zip' => 'application/zip'], $definition->getArgument(5));
81+
$definition = $container->getDefinition('asset_mapper.public_assets_path_resolver');
82+
$this->assertSame('/assets_path/', $definition->getArgument(1));
83+
84+
$definition = $container->getDefinition('asset_mapper.dev_server_subscriber');
85+
$this->assertSame(['zip' => 'application/zip'], $definition->getArgument(2));
8486

8587
$definition = $container->getDefinition('asset_mapper.importmap.renderer');
8688
$this->assertSame(['data-turbo-track' => 'reload'], $definition->getArgument(3));

0 commit comments

Comments
 (0)