Skip to content

Commit d2014eb

Browse files
weaverryanfabpot
authored andcommitted
[AssetMapper] Put importmap in polyfill so it can be hosted locally easily
1 parent 7074da9 commit d2014eb

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
@@ -24,7 +24,6 @@
2424
*/
2525
class ImportMapManager
2626
{
27-
public const POLYFILL_URL = 'https://ga.jspm.io/npm:es-module-shims@1.7.2/dist/es-module-shims.js';
2827
public const IMPORT_MAP_CACHE_FILENAME = 'importmap.json';
2928
public const ENTRYPOINT_CACHE_FILENAME_PATTERN = 'entrypoint.%s.json';
3029

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)