Skip to content

Commit 7cf6f77

Browse files
committed
feature #51828 [AssetMapper] Put importmap in polyfill so it can be hosted locally easily (weaverryan)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [AssetMapper] Put importmap in polyfill so it can be hosted locally easily | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #51302 | License | MIT Note: Built on top of #51786 In #51302, it was asked to allow the polyfill to be an asset mapper path. We could do that, but it would still require the user to "manage" this vendor file locally - i.e. commit it into their repository. So this PR goes a bit further and requires your polyfill to be an item in `importmap.php`. That's a bit odd, but because of #51786, it allows the JS package to be downloaded like any other JS package. The item is actually removed from the `importmap` before it's finally dumped. So the small oddity of having this item in `importmap.php` makes a really nice DX. Cheers! Commits ------- d2014eb [AssetMapper] Put importmap in polyfill so it can be hosted locally easily
2 parents 8ca6931 + d2014eb commit 7cf6f77

File tree

8 files changed

+59
-13
lines changed

8 files changed

+59
-13
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ CHANGELOG
3131
* Deprecate the `framework.asset_mapper.provider` config option
3232
* Add `--exclude` option to the `cache:pool:clear` command
3333
* Add parameters deprecations to the output of `debug:container` command
34+
* Change `framework.asset_mapper.importmap_polyfill` from a URL to the name of an item in the importmap
3435

3536
6.3
3637
---

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -924,8 +924,8 @@ private function addAssetMapperSection(ArrayNodeDefinition $rootNode, callable $
924924
->defaultValue('%kernel.project_dir%/importmap.php')
925925
->end()
926926
->scalarNode('importmap_polyfill')
927-
->info('URL of the ES Module Polyfill to use, false to disable. Defaults to using a CDN URL.')
928-
->defaultValue(null)
927+
->info('The importmap name that will be used to load the polyfill. Set to false to disable.')
928+
->defaultValue('es-module-shims')
929929
->end()
930930
->arrayNode('importmap_script_attributes')
931931
->info('Key-value pair of attributes to add to script tags output for the importmap.')

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
use Symfony\Component\Asset\PackageInterface;
3434
use Symfony\Component\AssetMapper\AssetMapper;
3535
use Symfony\Component\AssetMapper\Compiler\AssetCompilerInterface;
36-
use Symfony\Component\AssetMapper\ImportMap\ImportMapManager;
3736
use Symfony\Component\BrowserKit\AbstractBrowser;
3837
use Symfony\Component\Cache\Adapter\AdapterInterface;
3938
use Symfony\Component\Cache\Adapter\ArrayAdapter;
@@ -1378,7 +1377,7 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde
13781377

13791378
$container
13801379
->getDefinition('asset_mapper.importmap.renderer')
1381-
->replaceArgument(3, $config['importmap_polyfill'] ?? ImportMapManager::POLYFILL_URL)
1380+
->replaceArgument(3, $config['importmap_polyfill'])
13821381
->replaceArgument(4, $config['importmap_script_attributes'])
13831382
;
13841383
}

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public function testAssetMapperCanBeEnabled()
132132
'missing_import_mode' => 'warn',
133133
'extensions' => [],
134134
'importmap_path' => '%kernel.project_dir%/importmap.php',
135-
'importmap_polyfill' => null,
135+
'importmap_polyfill' => 'es-module-shims',
136136
'vendor_dir' => '%kernel.project_dir%/assets/vendor',
137137
'importmap_script_attributes' => [],
138138
];
@@ -668,7 +668,7 @@ protected static function getBundleDefaultConfig()
668668
'missing_import_mode' => 'warn',
669669
'extensions' => [],
670670
'importmap_path' => '%kernel.project_dir%/importmap.php',
671-
'importmap_polyfill' => null,
671+
'importmap_polyfill' => 'es-module-shims',
672672
'vendor_dir' => '%kernel.project_dir%/assets/vendor',
673673
'importmap_script_attributes' => [],
674674
],

src/Symfony/Component/AssetMapper/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ CHANGELOG
1717
* Allow specifying packages to update for the `importmap:update` command
1818
* Add a `importmap:audit` command to check for security vulnerability advisories in dependencies
1919
* Add a `importmap:outdated` command to check for outdated packages
20+
* Change the polyfill used for the importmap renderer from a URL to an entry in the importmap
2021

2122
6.3
2223
---

src/Symfony/Component/AssetMapper/ImportMap/ImportMapManager.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
*/
2626
class ImportMapManager
2727
{
28-
public const POLYFILL_URL = 'https://ga.jspm.io/npm:es-module-shims@1.7.2/dist/es-module-shims.js';
2928
public const IMPORT_MAP_CACHE_FILENAME = 'importmap.json';
3029
public const ENTRYPOINT_CACHE_FILENAME_PATTERN = 'entrypoint.%s.json';
3130

src/Symfony/Component/AssetMapper/ImportMap/ImportMapRenderer.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@
2727
*/
2828
class ImportMapRenderer
2929
{
30+
private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL = 'https://ga.jspm.io/npm:es-module-shims@1.8.0/dist/es-module-shims.js';
31+
3032
public function __construct(
3133
private readonly ImportMapManager $importMapManager,
3234
private readonly ?Packages $assetPackages = null,
3335
private readonly string $charset = 'UTF-8',
34-
private readonly string|false $polyfillUrl = ImportMapManager::POLYFILL_URL,
36+
private readonly string|false $polyfillImportName = false,
3537
private readonly array $scriptAttributes = [],
3638
private readonly ?RequestStack $requestStack = null,
3739
) {
@@ -45,6 +47,7 @@ public function render(string|array $entryPoint, array $attributes = []): string
4547
$importMap = [];
4648
$modulePreloads = [];
4749
$cssLinks = [];
50+
$polyFillPath = null;
4851
foreach ($importMapData as $importName => $data) {
4952
$path = $data['path'];
5053

@@ -53,6 +56,12 @@ public function render(string|array $entryPoint, array $attributes = []): string
5356
$path = $this->assetPackages->getUrl(ltrim($path, '/'));
5457
}
5558

59+
// if this represents the polyfill, hide it from the import map
60+
if ($importName === $this->polyfillImportName) {
61+
$polyFillPath = $path;
62+
continue;
63+
}
64+
5665
$preload = $data['preload'] ?? false;
5766
if ('css' !== $data['type']) {
5867
$importMap[$importName] = $path;
@@ -87,8 +96,17 @@ public function render(string|array $entryPoint, array $attributes = []): string
8796
</script>
8897
HTML;
8998

90-
if ($this->polyfillUrl) {
91-
$url = $this->escapeAttributeValue($this->polyfillUrl);
99+
if (false !== $this->polyfillImportName && null === $polyFillPath) {
100+
if ('es-module-shims' !== $this->polyfillImportName) {
101+
throw new \InvalidArgumentException(sprintf('The JavaScript module polyfill was not found in your import map. Either disable the polyfill or run "php bin/console importmap:require "%s"" to install it.', $this->polyfillImportName));
102+
}
103+
104+
// a fallback for the default polyfill in case it's not in the importmap
105+
$polyFillPath = self::DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL;
106+
}
107+
108+
if ($polyFillPath) {
109+
$url = $this->escapeAttributeValue($polyFillPath);
92110

93111
$output .= <<<HTML
94112

src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapRendererTest.php

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ public function testBasicRender()
5050
'path' => 'https://cdn.example.com/assets/remote-d1g35t.js',
5151
'type' => 'js',
5252
],
53+
'es-module-shim' => [
54+
'path' => 'https://ga.jspm.io/npm:es-module-shims',
55+
'type' => 'js',
56+
],
5357
]);
5458

5559
$assetPackages = $this->createMock(Packages::class);
@@ -64,11 +68,14 @@ public function testBasicRender()
6468
return '/subdirectory/'.$path;
6569
});
6670

67-
$renderer = new ImportMapRenderer($importMapManager, $assetPackages);
71+
$renderer = new ImportMapRenderer($importMapManager, $assetPackages, polyfillImportName: 'es-module-shim');
6872
$html = $renderer->render(['app']);
6973

7074
$this->assertStringContainsString('<script type="importmap">', $html);
71-
$this->assertStringContainsString('https://ga.jspm.io/npm:es-module-shims', $html);
75+
// polyfill is rendered as a normal script tag
76+
$this->assertStringContainsString('<script async src="https://ga.jspm.io/npm:es-module-shims"></script>', $html);
77+
// and is hidden from the import map
78+
$this->assertStringNotContainsString('"es-module-shim"', $html);
7279
$this->assertStringContainsString('import \'app\';', $html);
7380

7481
// preloaded js file
@@ -93,9 +100,26 @@ public function testNoPolyfill()
93100
$this->assertStringNotContainsString('https://ga.jspm.io/npm:es-module-shims', $renderer->render([]));
94101
}
95102

103+
public function testDefaultPolyfillUsedIfNotInImportmap()
104+
{
105+
$importMapManager = $this->createMock(ImportMapManager::class);
106+
$importMapManager->expects($this->once())
107+
->method('getImportMapData')
108+
->with(['app'])
109+
->willReturn([]);
110+
111+
$renderer = new ImportMapRenderer(
112+
$importMapManager,
113+
$this->createMock(Packages::class),
114+
polyfillImportName: 'es-module-shims',
115+
);
116+
$html = $renderer->render(['app']);
117+
$this->assertStringContainsString('<script async src="https://ga.jspm.io/npm:es-module-shims@', $html);
118+
}
119+
96120
public function testCustomScriptAttributes()
97121
{
98-
$renderer = new ImportMapRenderer($this->createBasicImportMapManager(), null, 'UTF-8', 'https://polyfillUrl.example', [
122+
$renderer = new ImportMapRenderer($this->createBasicImportMapManager(), null, 'UTF-8', 'es-module-shims', [
99123
'something' => true,
100124
'data-turbo-track' => 'reload',
101125
]);
@@ -128,6 +152,10 @@ private function createBasicImportMapManager(): ImportMapManager
128152
'path' => 'app.js',
129153
'type' => 'js',
130154
],
155+
'es-module-shims' => [
156+
'path' => 'https://polyfillUrl.example',
157+
'type' => 'js',
158+
],
131159
])
132160
;
133161

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy