Skip to content

Commit f624325

Browse files
[AssetMapper] Fix wiring resolvers, send requests in parallel and rewrite AssetMapper
1 parent de44614 commit f624325

34 files changed

+484
-550
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class UnusedTagsPass implements CompilerPassInterface
2525
'annotations.cached_reader',
2626
'assets.package',
2727
'asset_mapper.compiler',
28+
'asset_mapper.importmap.resolver',
2829
'auto_alias',
2930
'cache.pool',
3031
'cache.pool.clearer',

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,7 @@ private function addAssetMapperSection(ArrayNodeDefinition $rootNode, callable $
902902
->defaultValue('%kernel.project_dir%/assets/vendor')
903903
->end()
904904
->scalarNode('provider')
905-
->info('The provider (CDN) to use'.class_exists(ImportMapManager::class) ? sprintf(' (e.g.: "%s").', implode('", "', ImportMapManager::PROVIDERS)) : '.')
905+
->info('The provider (CDN) to use'.(class_exists(ImportMapManager::class) ? sprintf(' (e.g.: "%s").', implode('", "', ImportMapManager::PROVIDERS)) : '.'))
906906
->defaultValue('jsdelivr.esm')
907907
->end()
908908
->end()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use Symfony\Component\AssetMapper\AssetMapper;
3535
use Symfony\Component\AssetMapper\Compiler\AssetCompilerInterface;
3636
use Symfony\Component\AssetMapper\ImportMap\ImportMapManager;
37+
use Symfony\Component\AssetMapper\ImportMap\Resolver\PackageResolverInterface;
3738
use Symfony\Component\BrowserKit\AbstractBrowser;
3839
use Symfony\Component\Cache\Adapter\AdapterInterface;
3940
use Symfony\Component\Cache\Adapter\ArrayAdapter;
@@ -1316,14 +1317,8 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
13161317
->replaceArgument(3, $config['vendor_dir'])
13171318
;
13181319

1319-
$importMapProviderId = 'asset_mapper.importmap.provider.jspm_provider';
1320-
if (ImportMapManager::PROVIDER_JSDELIVR_ESM === $config['provider']) {
1321-
$importMapProviderId = 'asset_mapper.importmap.provider.js_delivr_esm_provider';
1322-
}
1323-
$container->setAlias('asset_mapper.importmap.provider', new Alias($importMapProviderId));
1324-
13251320
$container
1326-
->getDefinition('asset_mapper.importmap.provider.jspm_provider')
1321+
->getDefinition('asset_mapper.importmap.resolver')
13271322
->replaceArgument(0, $config['provider'])
13281323
;
13291324

@@ -1332,6 +1327,9 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
13321327
->replaceArgument(2, $config['importmap_polyfill'] ?? ImportMapManager::POLYFILL_URL)
13331328
->replaceArgument(3, $config['importmap_script_attributes'])
13341329
;
1330+
1331+
$container->registerForAutoconfiguration(PackageResolverInterface::class)
1332+
->addTag('asset_mapper.importmap.resolver');
13351333
}
13361334

13371335
/**

src/Symfony/Bundle/FrameworkBundle/Resources/config/asset_mapper.php

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@
2929
use Symfony\Component\AssetMapper\Factory\MappedAssetFactory;
3030
use Symfony\Component\AssetMapper\ImportMap\ImportMapManager;
3131
use Symfony\Component\AssetMapper\ImportMap\ImportMapRenderer;
32-
use Symfony\Component\AssetMapper\ImportMap\Providers\JsDelivrEsmImportMapProvider;
33-
use Symfony\Component\AssetMapper\ImportMap\Providers\JspmImportMapProvider;
32+
use Symfony\Component\AssetMapper\ImportMap\Resolver\JsDelivrEsmResolver;
33+
use Symfony\Component\AssetMapper\ImportMap\Resolver\JspmResolver;
34+
use Symfony\Component\AssetMapper\ImportMap\Resolver\PackageResolver;
3435
use Symfony\Component\AssetMapper\MapperAwareAssetPackage;
3536
use Symfony\Component\AssetMapper\Path\PublicAssetsPathResolver;
3637
use Symfony\Component\HttpKernel\Event\RequestEvent;
@@ -138,17 +139,39 @@
138139
service('asset_mapper.public_assets_path_resolver'),
139140
abstract_arg('importmap.php path'),
140141
abstract_arg('vendor directory'),
141-
// dynamic alias to the chosen provider
142-
service('asset_mapper.importmap.provider'),
142+
service('asset_mapper.importmap.resolver'),
143143
])
144144
->alias(ImportMapManager::class, 'asset_mapper.importmap.manager')
145145

146-
->set('asset_mapper.importmap.provider.jspm_provider', JspmImportMapProvider::class)
146+
->set('asset_mapper.importmap.resolver', PackageResolver::class)
147147
->args([
148148
abstract_arg('provider'),
149+
tagged_locator('asset_mapper.importmap.resolver'),
149150
])
150151

151-
->set('asset_mapper.importmap.provider.js_delivr_esm_provider', JsDelivrEsmImportMapProvider::class)
152+
->set('asset_mapper.importmap.resolver.jsdelivr_esm', JsDelivrEsmResolver::class)
153+
->args([service('http_client')])
154+
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_JSDELIVR_ESM])
155+
156+
->set('asset_mapper.importmap.resolver.jspm', JspmResolver::class)
157+
->args([service('http_client'), ImportMapManager::PROVIDER_JSPM])
158+
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_JSPM])
159+
160+
->set('asset_mapper.importmap.resolver.jspm_system', JspmResolver::class)
161+
->args([service('http_client'), ImportMapManager::PROVIDER_JSPM_SYSTEM])
162+
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_JSPM_SYSTEM])
163+
164+
->set('asset_mapper.importmap.resolver.skypack', JspmResolver::class)
165+
->args([service('http_client'), ImportMapManager::PROVIDER_SKYPACK])
166+
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_SKYPACK])
167+
168+
->set('asset_mapper.importmap.resolver.jsdelivr', JspmResolver::class)
169+
->args([service('http_client'), ImportMapManager::PROVIDER_JSDELIVR])
170+
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_JSDELIVR])
171+
172+
->set('asset_mapper.importmap.resolver.unpkg', JspmResolver::class)
173+
->args([service('http_client'), ImportMapManager::PROVIDER_UNPKG])
174+
->tag('asset_mapper.importmap.resolver', ['resolver' => ImportMapManager::PROVIDER_UNPKG])
152175

153176
->set('asset_mapper.importmap.renderer', ImportMapRenderer::class)
154177
->args([

src/Symfony/Component/AssetMapper/AssetMapper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public function getPublicPath(string $logicalPath): ?string
7474

7575
$asset = $this->getAsset($logicalPath);
7676

77-
return $asset?->getPublicPath();
77+
return $asset?->publicPath;
7878
}
7979

8080
private function loadManifest(): array

src/Symfony/Component/AssetMapper/AssetMapperCompiler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ public function __construct(private readonly iterable $assetCompilers, private r
3232
{
3333
}
3434

35-
public function compile(string $content, MappedAsset $mappedAsset): string
35+
public function compile(string $content, MappedAsset $asset): string
3636
{
3737
foreach ($this->assetCompilers as $compiler) {
38-
if (!$compiler->supports($mappedAsset)) {
38+
if (!$compiler->supports($asset)) {
3939
continue;
4040
}
4141

42-
$content = $compiler->compile($content, $mappedAsset, $this->assetMapper ??= ($this->assetMapperFactory)());
42+
$content = $compiler->compile($content, $asset, $this->assetMapper ??= ($this->assetMapperFactory)());
4343
}
4444

4545
return $content;

src/Symfony/Component/AssetMapper/AssetMapperDevServerSubscriber.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,15 @@ public function onKernelRequest(RequestEvent $event): void
128128
throw new NotFoundHttpException(sprintf('Asset with public path "%s" not found.', $pathInfo));
129129
}
130130

131-
$mediaType = $this->getMediaType($asset->getPublicPath());
131+
$mediaType = $this->getMediaType($asset->publicPath);
132132
$response = (new Response(
133-
$asset->getContent(),
133+
$asset->content,
134134
headers: $mediaType ? ['Content-Type' => $mediaType] : [],
135135
))
136136
->setPublic()
137137
->setMaxAge(604800)
138138
->setImmutable()
139-
->setEtag($asset->getDigest())
139+
->setEtag($asset->digest)
140140
;
141141

142142
$event->setResponse($response);
@@ -164,15 +164,15 @@ private function findAssetFromCache(string $pathInfo): ?MappedAsset
164164
$cachedAsset = $this->cacheMapCache->getItem(hash('xxh128', $pathInfo));
165165
$asset = $cachedAsset->isHit() ? $this->assetMapper->getAsset($cachedAsset->get()) : null;
166166

167-
if (null !== $asset && $asset->getPublicPath() === $pathInfo) {
167+
if (null !== $asset && $asset->publicPath === $pathInfo) {
168168
return $asset;
169169
}
170170
}
171171

172172
// we did not find a match
173173
$asset = null;
174174
foreach ($this->assetMapper->allAssets() as $assetCandidate) {
175-
if ($pathInfo === $assetCandidate->getPublicPath()) {
175+
if ($pathInfo === $assetCandidate->publicPath) {
176176
$asset = $assetCandidate;
177177
break;
178178
}
@@ -183,7 +183,7 @@ private function findAssetFromCache(string $pathInfo): ?MappedAsset
183183
}
184184

185185
if (null !== $cachedAsset) {
186-
$cachedAsset->set($asset->getLogicalPath());
186+
$cachedAsset->set($asset->logicalPath);
187187
$this->cacheMapCache->save($cachedAsset);
188188
}
189189

src/Symfony/Component/AssetMapper/Command/AssetMapperCompileCommand.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,14 @@ private function createManifestAndWriteFiles(SymfonyStyle $io, string $publicDir
122122
$manifest = [];
123123
foreach ($allAssets as $asset) {
124124
// $asset->getPublicPath() will start with a "/"
125-
$targetPath = $publicDir.$asset->getPublicPath();
125+
$targetPath = $publicDir.$asset->publicPath;
126126

127127
if (!is_dir($dir = \dirname($targetPath))) {
128128
$this->filesystem->mkdir($dir);
129129
}
130130

131-
$this->filesystem->dumpFile($targetPath, $asset->getContent());
132-
$manifest[$asset->getLogicalPath()] = $asset->getPublicPath();
131+
$this->filesystem->dumpFile($targetPath, $asset->content);
132+
$manifest[$asset->logicalPath] = $asset->publicPath;
133133
}
134134
ksort($manifest);
135135
$io->comment(sprintf('Compiled <info>%d</info> assets', \count($manifest)));

src/Symfony/Component/AssetMapper/Command/DebugAssetMapperCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
7070

7171
$rows = [];
7272
foreach ($allAssets as $asset) {
73-
$logicalPath = $asset->getLogicalPath();
74-
$sourcePath = $this->relativizePath($asset->getSourcePath());
73+
$logicalPath = $asset->logicalPath;
74+
$sourcePath = $this->relativizePath($asset->sourcePath);
7575

7676
if (!$input->getOption('full')) {
7777
$logicalPath = $this->shortenPath($logicalPath);

src/Symfony/Component/AssetMapper/Compiler/CssAssetUrlCompiler.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,31 +45,31 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac
4545
{
4646
return preg_replace_callback(self::ASSET_URL_PATTERN, function ($matches) use ($asset, $assetMapper) {
4747
try {
48-
$resolvedPath = $this->resolvePath(\dirname($asset->getLogicalPath()), $matches[1]);
48+
$resolvedPath = $this->resolvePath(\dirname($asset->logicalPath), $matches[1]);
4949
} catch (RuntimeException $e) {
50-
$this->handleMissingImport(sprintf('Error processing import in "%s": "%s"', $asset->getSourcePath(), $e->getMessage()), $e);
50+
$this->handleMissingImport(sprintf('Error processing import in "%s": ', $asset->sourcePath).$e->getMessage(), $e);
5151

5252
return $matches[0];
5353
}
5454
$dependentAsset = $assetMapper->getAsset($resolvedPath);
5555

5656
if (null === $dependentAsset) {
57-
$this->handleMissingImport(sprintf('Unable to find asset "%s" referenced in "%s".', $matches[1], $asset->getSourcePath()));
57+
$this->handleMissingImport(sprintf('Unable to find asset "%s" referenced in "%s".', $matches[1], $asset->sourcePath));
5858

5959
// return original, unchanged path
6060
return $matches[0];
6161
}
6262

6363
$asset->addDependency(new AssetDependency($dependentAsset));
64-
$relativePath = $this->createRelativePath($asset->getPublicPathWithoutDigest(), $dependentAsset->getPublicPath());
64+
$relativePath = $this->createRelativePath($asset->publicPathWithoutDigest, $dependentAsset->publicPath);
6565

6666
return 'url("'.$relativePath.'")';
6767
}, $content);
6868
}
6969

7070
public function supports(MappedAsset $asset): bool
7171
{
72-
return 'css' === $asset->getPublicExtension();
72+
return 'css' === $asset->publicExtension;
7373
}
7474

7575
private function handleMissingImport(string $message, \Throwable $e = null): void

src/Symfony/Component/AssetMapper/Compiler/JavaScriptImportPathCompiler.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,17 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac
4545
{
4646
return preg_replace_callback(self::IMPORT_PATTERN, function ($matches) use ($asset, $assetMapper) {
4747
try {
48-
$resolvedPath = $this->resolvePath(\dirname($asset->getLogicalPath()), $matches[1]);
48+
$resolvedPath = $this->resolvePath(\dirname($asset->logicalPath), $matches[1]);
4949
} catch (RuntimeException $e) {
50-
$this->handleMissingImport(sprintf('Error processing import in "%s": "%s"', $asset->getSourcePath(), $e->getMessage()), $e);
50+
$this->handleMissingImport(sprintf('Error processing import in "%s": ', $asset->sourcePath).$e->getMessage(), $e);
5151

5252
return $matches[0];
5353
}
5454

5555
$dependentAsset = $assetMapper->getAsset($resolvedPath);
5656

5757
if (!$dependentAsset) {
58-
$message = sprintf('Unable to find asset "%s" imported from "%s".', $matches[1], $asset->getSourcePath());
58+
$message = sprintf('Unable to find asset "%s" imported from "%s".', $matches[1], $asset->sourcePath);
5959

6060
if (null !== $assetMapper->getAsset(sprintf('%s.js', $resolvedPath))) {
6161
$message .= sprintf(' Try adding ".js" to the end of the import - i.e. "%s.js".', $matches[1]);
@@ -73,7 +73,7 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac
7373

7474
$asset->addDependency(new AssetDependency($dependentAsset, $isLazy, false));
7575

76-
$relativeImportPath = $this->createRelativePath($asset->getPublicPathWithoutDigest(), $dependentAsset->getPublicPathWithoutDigest());
76+
$relativeImportPath = $this->createRelativePath($asset->publicPathWithoutDigest, $dependentAsset->publicPathWithoutDigest);
7777
$relativeImportPath = $this->makeRelativeForJavaScript($relativeImportPath);
7878

7979
return str_replace($matches[1], $relativeImportPath, $matches[0]);
@@ -85,7 +85,7 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac
8585

8686
public function supports(MappedAsset $asset): bool
8787
{
88-
return 'js' === $asset->getPublicExtension();
88+
return 'js' === $asset->publicExtension;
8989
}
9090

9191
private function makeRelativeForJavaScript(string $path): string

src/Symfony/Component/AssetMapper/Compiler/SourceMappingUrlsCompiler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ final class SourceMappingUrlsCompiler implements AssetCompilerInterface
3030

3131
public function supports(MappedAsset $asset): bool
3232
{
33-
return \in_array($asset->getPublicExtension(), ['css', 'js'], true);
33+
return \in_array($asset->publicExtension, ['css', 'js'], true);
3434
}
3535

3636
public function compile(string $content, MappedAsset $asset, AssetMapperInterface $assetMapper): string
3737
{
3838
return preg_replace_callback(self::SOURCE_MAPPING_PATTERN, function ($matches) use ($asset, $assetMapper) {
39-
$resolvedPath = $this->resolvePath(\dirname($asset->getLogicalPath()), $matches[2]);
39+
$resolvedPath = $this->resolvePath(\dirname($asset->logicalPath), $matches[2]);
4040

4141
$dependentAsset = $assetMapper->getAsset($resolvedPath);
4242
if (!$dependentAsset) {
@@ -45,7 +45,7 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac
4545
}
4646

4747
$asset->addDependency(new AssetDependency($dependentAsset));
48-
$relativePath = $this->createRelativePath($asset->getPublicPathWithoutDigest(), $dependentAsset->getPublicPath());
48+
$relativePath = $this->createRelativePath($asset->publicPathWithoutDigest, $dependentAsset->publicPath);
4949

5050
return $matches[1].'# sourceMappingURL='.$relativePath;
5151
}, $content);

src/Symfony/Component/AssetMapper/Factory/CachedMappedAssetFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private function getCacheFilePath(string $logicalPath, string $sourcePath): stri
6060
private function collectResourcesFromAsset(MappedAsset $mappedAsset): array
6161
{
6262
$resources = array_map(fn (string $path) => new FileResource($path), $mappedAsset->getFileDependencies());
63-
$resources[] = new FileResource($mappedAsset->getSourcePath());
63+
$resources[] = new FileResource($mappedAsset->sourcePath);
6464

6565
foreach ($mappedAsset->getDependencies() as $dependency) {
6666
if (!$dependency->isContentDependency) {

0 commit comments

Comments
 (0)