8000 bug #52519 [AssetMapper] If assets are served from a subdirectory or … · jschaedl/symfony@fa4726f · GitHub
[go: up one dir, main page]

Skip to content

Commit fa4726f

Browse files
bug symfony#52519 [AssetMapper] If assets are served from a subdirectory or CDN, also adjust importmap keys (weaverryan)
This PR was merged into the 6.4 branch. Discussion ---------- [AssetMapper] If assets are served from a subdirectory or CDN, also adjust importmap keys | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | none | Issues | Fixes symfony#52520 (extra points for opening the PR before the issue was submitted? Anyone?) | License | MIT Hi! Subdirectories & CDN paths are tricky. Suppose you have: ``` // assets/app.js import './foo.js'; ``` When we see that relative import to `foo.js`, we automatically add an entry in the `importmap` - e.g.: ``` "/assets/foo.js": "/assets/foo-abcd1234digest.js" ``` So, when the browser downloads `/assets/app-abcd1234diegest.js`, it follows the `./foo.js` relative path to resolve to `/assets/foo.js`. It then sees that *key* in the `importmap`, and downloads the final file. However, suppose you're under a subdirectory so that the browser downloads `/subdir/assets/app-abcd1234diegest.js`. In that case, it will resolve the relative import to `/subdir/assets/foo.js`. And so, the *key* in the importmap also needs to have the `/subdir` inside of it. Additionally, for a CDN, if the browser downloads `https://cdn.com/assets/app.js`, then it will resolve the import to `https://cdn.com/assets/bar.js`. If the key in the importmap is `/assets/bar.js`, that will NOT be used, as this is interpreted as the URL of the site - e.g. `https://myfrontendsite.com/assets/bar.js`. So even in this case, the key needs to be the full `https://cdn.com/assets/bar.js` so that it's used. I tested this locally on a subdirectory project as well as a CDN, where you set `framework.asset.base_urls` to some `https://cdn.com/` type of URL. Cheers! Commits ------- 85c85d3 [AssetMapper] If assets are served from a subdirectory or CDN, also adjust importmap keys
2 parents 3128c60 + 85c85d3 commit fa4726f

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ public function render(string|array $entryPoint, array $attributes = []): string
6262
continue;
6363
}
6464

65+
// for subdirectories or CDNs, the import name needs to be the full URL
66+
if (str_starts_with($importName, '/') && $this->assetPackages) {
67+
$importName = $this->assetPackages->getUrl(ltrim($importName, '/'));
68+
}
69+
6570
$preload = $data['preload'] ?? false;
6671
if ('css' !== $data['type']) {
6772
$importMap[$importName] = $path;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ public function testBasicRender()
5454
'path' => 'https://ga.jspm.io/npm:es-module-shims',
5555
'type' => 'js',
5656
],
57+
'/assets/implicitly-added' => [
58+
'path' => '/assets/implicitly-added-d1g35t.js',
59+
'type' => 'js',
60+
],
5761
]);
5862

5963
$assetPackages = $this->createMock(Packages::class);
@@ -92,6 +96,8 @@ public function testBasicRender()
9296
$this->assertStringNotContainsString('<link rel="stylesheet" href="/subdirectory/assets/styles/app-nopreload-d1g35t.css">', $html);
9397
// remote js
9498
$this->assertStringContainsString('"remote_js": "https://cdn.example.com/assets/remote-d1g35t.js"', $html);
99+
// both the key and value are prefixed with the subdirectory
100+
$this->assertStringContainsString('"/subdirectory/assets/implicitly-added": "/subdirectory/assets/implicitly-added-d1g35t.js"', $html);
95101
}
96102

97103
public function testNoPolyfill()

0 commit comments

Comments
 (0)
0