Skip to content

Commit a5a31cb

Browse files
[AssetMapper] Add support for loading JSON using import statements
1 parent e59b73b commit a5a31cb

File tree

6 files changed

+12
-11
lines changed

6 files changed

+12
-11
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ protected function configure(): void
4343
{
4444
$this
4545
->addArgument('name', InputArgument::OPTIONAL, 'An asset name (or a path) to search for (e.g. "app")')
46-
->addOption('ext', null, InputOption::VALUE_REQUIRED, 'Filter assets by extension (e.g. "css")', null, ['js', 'css', 'png'])
46+
->addOption('ext', null, InputOption::VALUE_REQUIRED, 'Filter assets by extension (e.g. "css")', null, ['js', 'css', 'json'])
4747
->addOption('full', null, null, 'Whether to show the full paths')
4848
->addOption('vendor', null, InputOption::VALUE_NEGATABLE, 'Only show assets from vendor packages')
4949
->setHelp(<<<'EOT'

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function getEntries(): ImportMapEntries
4949
throw new \InvalidArgumentException(\sprintf('The following keys are not valid for the importmap entry "%s": "%s". Valid keys are: "%s".', $importName, implode('", "', $invalidKeys), implode('", "', $validKeys)));
5050
}
5151

52-
$type = isset($data['type']) ? ImportMapType::tryFrom($data['type']) : ImportMapType::JS;
52+
$type = ImportMapType::tryFrom($data['type'] ?? 'js') ?? ImportMapType::JS;
5353
$isEntrypoint = $data['entrypoint'] ?? false;
5454

5555
if (isset($data['path'])) {

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public function requirePackages(array $packagesToRequire, ImportMapEntries $impo
162162

163163
$newEntry = ImportMapEntry::createLocal(
164164
$requireOptions->importName,
165-
self::getImportMapTypeFromFilename($requireOptions->path),
165+
ImportMapType::tryFrom(pathinfo($path, \PATHINFO_EXTENSION)) ?? ImportMapType::JS,
166166
$path,
167167
$requireOptions->entrypoint,
168168
);
@@ -200,11 +200,6 @@ private function cleanupPackageFiles(ImportMapEntry $entry): void
200200
}
201201
}
202202

203-
private static function getImportMapTypeFromFilename(string $path): ImportMapType
204-
{
205-
return str_ends_with($path, '.css') ? ImportMapType::CSS : ImportMapType::JS;
206-
}
207-
208203
/**
209204
* Finds the MappedAsset allowing for a "logical path", relative or absolute filesystem path.
210205
*/

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ class ImportMapRenderer
3131
private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_URL = 'https://ga.jspm.io/npm:es-module-shims@1.10.0/dist/es-module-shims.js';
3232
private const DEFAULT_ES_MODULE_SHIMS_POLYFILL_INTEGRITY = 'sha384-ie1x72Xck445i0j4SlNJ5W5iGeL3Dpa0zD48MZopgWsjNB/lt60SuG1iduZGNnJn';
3333

34+
private const LOADER_JSON = "export default (async()=>await(await fetch('%s')).json())()";
35+
private const LOADER_CSS = "document.head.appendChild(Object.assign(document.createElement('link'),{rel:'stylesheet',href:'%s'}))";
36+
3437
public function __construct(
3538
private readonly ImportMapGenerator $importMapGenerator,
3639
private readonly ?Packages $assetPackages = null,
@@ -70,7 +73,9 @@ public function render(string|array $entryPoint, array $attributes = []): string
7073
}
7174

7275
$preload = $data['preload'] ?? false;
73-
if ('css' !== $data['type']) {
76+
if ('json' === $data['type']) {
77+
$importMap[$importName] = 'data:application/javascript,'.\sprintf(self::LOADER_JSON, addslashes($path));
78+
} elseif ('css' !== $data['type']) {
7479
$importMap[$importName] = $path;
7580
if ($preload) {
7681
$modulePreloads[] = $path;
@@ -80,7 +85,7 @@ public function render(string|array $entryPoint, array $attributes = []): string
8085
// importmap entry is a noop
8186
$importMap[$importName] = 'data:application/javascript,';
8287
} else {
83-
$importMap[$importName] = 'data:application/javascript,'.rawurlencode(\sprintf('document.head.appendChild(Object.assign(document.createElement("link"),{rel:"stylesheet",href:"%s"}))', addslashes($path)));
88+
$importMap[$importName] = 'data:application/javascript,'.\sprintf(self::LOADER_CSS, addslashes($path));
8489
}
8590
}
8691

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ enum ImportMapType: string
1515
{
1616
case JS = 'js';
1717
case CSS = 'css';
18+
case JSON = 'json';
1819
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public function testBasicRender()
9292
$this->assertStringContainsString('"app_css_preload": "data:application/javascript,', $html);
9393
$this->assertStringContainsString('<link rel="stylesheet" href="/subdirectory/assets/styles/app-preload-d1g35t.css">', $html);
9494
// non-preloaded CSS file
95-
$this->assertStringContainsString('"app_css_no_preload": "data:application/javascript,document.head.appendChild%28Object.assign%28document.createElement%28%22link%22%29%2C%7Brel%3A%22stylesheet%22%2Chref%3A%22%2Fsubdirectory%2Fassets%2Fstyles%2Fapp-nopreload-d1g35t.css%22%7D', $html);
95+
$this->assertStringContainsString('"app_css_no_preload": "data:application/javascript,document.head.appendChild(Object.assign(document.createElement(\'link\'),{rel:\'stylesheet\',href:\'/subdirectory/assets/styles/app-nopreload-d1g35t.css\'}))', $html);
9696
$this->assertStringNotContainsString('<link rel="stylesheet" href="/subdirectory/assets/styles/app-nopreload-d1g35t.css">', $html);
9797
// remote js
9898
$this->assertStringContainsString('"remote_js": "https://cdn.example.com/assets/remote-d1g35t.js"', $html);

0 commit comments

Comments
 (0)