Skip to content

Commit 84b9a15

Browse files
committed
Fixing bug where autoimport CSS from importmap did not use their importmap name
1 parent 1e68d62 commit 84b9a15

19 files changed

+224
-124
lines changed

src/StimulusBundle/src/AssetMapper/AutoImportLocator.php

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ public function __construct(
2828
}
2929

3030
// parts of this method are duplicated & adapted from UxControllersTwigRuntime
31-
public function locateAsset(string $path, UxPackageMetadata $packageMetadata): ?MappedAsset
31+
public function locateAutoImport(string $path, UxPackageMetadata $packageMetadata): MappedControllerAutoImport
3232
{
3333
// see if this is a mapped asset path
3434
if ($asset = $this->assetMapper->getAsset($path)) {
35-
return $asset;
35+
return new MappedControllerAutoImport($asset->sourcePath, false);
3636
}
3737

3838
$slashPosition = strpos($path, '/');
@@ -59,22 +59,14 @@ public function locateAsset(string $path, UxPackageMetadata $packageMetadata): ?
5959
throw new \LogicException(sprintf('An "autoimport" in "controllers.json" refers to "%s". This file was found, but the path is not in the asset mapper. And so, the file cannot be loaded. This is a misconfiguration with the bundle providing this.', $path));
6060
}
6161

62-
return $asset;
62+
return new MappedControllerAutoImport($asset->sourcePath, false);
6363
}
6464

6565
$entry = $this->importMapConfigReader->findRootImportMapEntry($path);
6666
if (!$entry) {
6767
throw new \LogicException(sprintf('The autoimport "%s" could not be found in importmap.php. Try running "importmap:require %s".', $path, $path));
6868
}
6969

70-
if ($asset = $this->assetMapper->getAsset($entry->path)) {
71-
return $asset;
72-
}
73-
74-
if ($asset = $this->assetMapper->getAssetFromSourcePath($entry->path)) {
75-
return $asset;
76-
}
77-
78-
throw new \LogicException(sprintf('The autoimport "%s" is correctly in importmap.php but the file could not be found. Try running the "importmap:install" command.', $path));
70+
return new MappedControllerAutoImport($path, true);
7971
}
8072
}

src/StimulusBundle/src/AssetMapper/ControllersMapGenerator.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ private function loadUxControllers(): array
142142
return $controllersMap;
143143
}
144144

145+
/**
146+
* @return MappedControllerAutoImport[]
147+
*/
145148
private function collectAutoImports(array $autoImports, UxPackageMetadata $currentPackageMetadata): array
146149
{
147150
// @legacy: Backwards compatibility with Symfony 6.3
@@ -152,15 +155,15 @@ private function collectAutoImports(array $autoImports, UxPackageMetadata $curre
152155
throw new \InvalidArgumentException(sprintf('The "autoImportLocator" argument to "%s" is required when using AssetMapper 6.4', self::class));
153156
}
154157

155-
$autoImportAssets = [];
158+
$autoImportItems = [];
156159
foreach ($autoImports as $path => $enabled) {
157160
if (!$enabled) {
158161
continue;
159162
}
160163

161-
$autoImportAssets[] = $this->autoImportLocator->locateAsset($path, $currentPackageMetadata);
164+
$autoImportItems[] = $this->autoImportLocator->locateAutoImport($path, $currentPackageMetadata);
162165
}
163166

164-
return $autoImportAssets;
167+
return $autoImportItems;
165168
}
166169
}

src/StimulusBundle/src/AssetMapper/MappedControllerAsset.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function __construct(
2424
public MappedAsset $asset,
2525
public bool $isLazy,
2626
/**
27-
* @var MappedAsset[]
27+
* @var MappedControllerAutoImport[]
2828
*/
2929
public array $autoImports = [],
3030
) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\UX\StimulusBundle\AssetMapper;
13+
14+
/**
15+
* @experimental
16+
*
17+
* @author Ryan Weaver <[email protected]>
18+
*/
19+
class MappedControllerAutoImport
20+
{
21+
public function __construct(
22+
public string $path,
23+
public bool $isBareImport
24+
) {
25+
}
26+
}

src/StimulusBundle/src/AssetMapper/StimulusLoaderJavaScriptCompiler.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,13 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac
8080
$asset->addDependency($mappedControllerAsset->asset);
8181
}
8282

83-
$autoImportRelativePaths = [];
84-
foreach ($mappedControllerAsset->autoImports as $autoImportAsset) {
85-
$autoImportRelativePaths[] = json_encode(Path::makeRelative($autoImportAsset->sourcePath, \dirname($asset->sourcePath)), \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES);
83+
$autoImportPaths = [];
84+
foreach ($mappedControllerAsset->autoImports as $autoImport) {
85+
if ($autoImport->isBareImport) {
86+
$autoImportPaths[] = json_encode($autoImport->path, \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES);
87+
} else {
88+
$autoImportPaths[] = json_encode(Path::makeRelative($autoImport->path, \dirname($asset->sourcePath)), \JSON_THROW_ON_ERROR | \JSON_UNESCAPED_SLASHES);
89+
}
8690
}
8791

8892
if ($mappedControllerAsset->isLazy) {
@@ -91,7 +95,7 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac
9195
} else {
9296
// import $relativeImportPath and also the auto-imports
9397
// and use a Promise.all() to wait for all of them
94-
$lazyControllers[] = sprintf('%s: () => Promise.all([import(%s), %s]).then((ret) => ret[0])', json_encode($name), $relativeImportPath, implode(', ', array_map(fn ($path) => "import($path)", $autoImportRelativePaths)));
98+
$lazyControllers[] = sprintf('%s: () => Promise.all([import(%s), %s]).then((ret) => ret[0])', json_encode($name), $relativeImportPath, implode(', ', array_map(fn ($path) => "import($path)", $autoImportPaths)));
9599
}
96100

97101
continue;
@@ -104,7 +108,7 @@ public function compile(string $content, MappedAsset $asset, AssetMapperInterfac
104108
$controllerNameForVariable,
105109
$relativeImportPath
106110
);
107-
foreach ($autoImportRelativePaths as $autoImportRelativePath) {
111+
foreach ($autoImportPaths as $autoImportRelativePath) {
108112
$importLines[] = sprintf(
109113
'import %s;',
110114
$autoImportRelativePath

src/StimulusBundle/tests/AssetMapper/AutoImportLocatorTest.php

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,25 @@ protected function setUp(): void
2929
}
3030
}
3131

32-
public function testLocateAssetCanHandleAssetMapperPath()
32+
public function testLocateAutoImportCanHandleAssetMapperPath()
3333
{
3434
$assetMapper = $this->createMock(AssetMapperInterface::class);
35-
$asset = new MappedAsset('foo.css');
3635
$assetMapper->expects($this->once())
3736
->method('getAsset')
3837
->with('foo.css')
39-
->willReturn($asset);
38+
->willReturn(new MappedAsset('foo.css', '/path/to/foo.css'));
4039

4140
$locator = new AutoImportLocator(
4241
$this->createMock(ImportMapConfigReader::class),
4342
$assetMapper,
4443
);
4544
$packageMetadata = new UxPackageMetadata('foo', [], 'bar');
46-
$this->assertSame($asset, $locator->locateAsset('foo.css', $packageMetadata));
45+
$autoImport = $locator->locateAutoImport('foo.css', $packageMetadata);
46+
$this->assertSame('/path/to/foo.css', $autoImport->path);
47+
$this->assertFalse($autoImport->isBareImport);
4748
}
4849

49-
public function testLocateAssetHandlesFileInPackage()
50+
public function testLocateAutoImportHandlesFileInPackage()
5051
{
5152
$packageMetadata = new UxPackageMetadata(
5253
__DIR__.'/../fixtures/vendor/fake-vendor/ux-package1/assets',
@@ -55,78 +56,37 @@ public function testLocateAssetHandlesFileInPackage()
5556
);
5657

5758
$assetMapper = $this->createMock(AssetMapperInterface::class);
58-
$asset = new MappedAsset('styles.css');
5959
$assetMapper->expects($this->once())
6060
->method('getAssetFromSourcePath')
6161
->with(__DIR__.'/../fixtures/vendor/fake-vendor/ux-package1/assets/dist/styles.css')
62-
->willReturn($asset);
62+
->willReturn(new MappedAsset('styles.css', '/path/to/styles.css'));
6363

6464
$locator = new AutoImportLocator(
6565
$this->createMock(ImportMapConfigReader::class),
6666
$assetMapper,
6767
);
6868

69-
$actualAsset = $locator->locateAsset('@fake-vendor/ux-package1/dist/styles.css', $packageMetadata);
70-
$this->assertSame($asset, $actualAsset);
69+
$autoImport = $locator->locateAutoImport('@fake-vendor/ux-package1/dist/styles.css', $packageMetadata);
70+
$this->assertSame('/path/to/styles.css', $autoImport->path);
71+
$this->assertFalse($autoImport->isBareImport);
7172
}
7273

73-
public function testLocateAssetViaLogicalPathFromImportMap()
74+
public function testLocateAutoImportFromImportMap()
7475
{
7576
$importMapConfigReader = $this->createMock(ImportMapConfigReader::class);
7677
$importMapConfigReader->expects($this->once())
7778
->method('findRootImportMapEntry')
7879
->with('tom-select/dist/css/tom-select.default.css')
7980
->willReturn(ImportMapEntry::createRemote('tom-select/dist/css/tom-select.default.css', ImportMapType::CSS, '/path/to/vendor/tom-select.default.css', '1.0.0', 'tom-select/dist/css/tom-select.default.css', false));
8081

81-
$assetMapper = $this->createMock(AssetMapperInterface::class);
82-
$asset = new MappedAsset('styles.css');
83-
$assetMapper->expects($this->any())
84-
->method('getAsset')
85-
->willReturnCallback(function (string $path) use ($asset) {
86-
// don't find the actual auto import path
87-
if ('tom-select/dist/css/tom-select.default.css' === $path) {
88-
return null;
89-
}
90-
91-
if ('/path/to/vendor/tom-select.default.css' === $path) {
92-
return $asset;
93-
}
94-
95-
throw new \LogicException('Unexpected path: '.$path);
96-
});
97-
98-
$locator = new AutoImportLocator(
99-
$importMapConfigReader,
100-
$assetMapper,
101-
);
102-
103-
$packageMetadata = new UxPackageMetadata('foo', [], 'bar');
104-
$actualAsset = $locator->locateAsset('tom-select/dist/css/tom-select.default.css', $packageMetadata);
105-
$this->assertSame($asset, $actualAsset);
106-
}
107-
108-
public function testLocateAssetViaSourcePathFromImportMap()
109-
{
110-
$importMapConfigReader = $this->createMock(ImportMapConfigReader::class);
111-
$importMapConfigReader->expects($this->once())
112-
->method('findRootImportMapEntry')
113-
->with('tom-select/dist/css/tom-select.default.css')
114-
->willReturn(ImportMapEntry::createRemote('tom-select/dist/css/tom-select.default.css', ImportMapType::CSS, '/path/to/vendor/tom-select.default.css', '1.0.0', 'tom-select/dist/css/tom-select.default.css', false));
115-
116-
$assetMapper = $this->createMock(AssetMapperInterface::class);
117-
$asset = new MappedAsset('styles.css');
118-
$assetMapper->expects($this->any())
119-
->method('getAssetFromSourcePath')
120-
->with('/path/to/vendor/tom-select.default.css')
121-
->willReturn($asset);
122-
12382
$locator = new AutoImportLocator(
12483
$importMapConfigReader,
125-
$assetMapper,
84+
$this->createMock(AssetMapperInterface::class),
12685
);
12786

12887
$packageMetadata = new UxPackageMetadata('foo', [], 'bar');
129-
$actualAsset = $locator->locateAsset('tom-select/dist/css/tom-select.default.css', $packageMetadata);
130-
$this->assertSame($asset, $actualAsset);
88+
$autoImport = $locator->locateAutoImport('tom-select/dist/css/tom-select.default.css', $packageMetadata);
89+
$this->assertSame('tom-select/dist/css/tom-select.default.css', $autoImport->path);
90+
$this->assertTrue($autoImport->isBareImport);
13191
}
13292
}

src/StimulusBundle/tests/AssetMapper/ControllerMapGeneratorTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\AssetMapper\MappedAsset;
1818
use Symfony\UX\StimulusBundle\AssetMapper\AutoImportLocator;
1919
use Symfony\UX\StimulusBundle\AssetMapper\ControllersMapGenerator;
20+
use Symfony\UX\StimulusBundle\AssetMapper\MappedControllerAutoImport;
2021
use Symfony\UX\StimulusBundle\Ux\UxPackageReader;
2122

2223
class ControllerMapGeneratorTest extends TestCase
@@ -48,14 +49,14 @@ public function testGetControllersMap()
4849
$autoImportLocator = $this->createMock(AutoImportLocator::class);
4950
if (class_exists(ImportMapConfigReader::class)) {
5051
$autoImportLocator->expects($this->any())
51-
->method('locateAsset')
52+
->method('locateAutoImport')
5253
->willReturnCallback(function ($path) {
53-
return new MappedAsset($path, '/path/to'.$path);
54+
return new MappedControllerAutoImport('/path/to'.$path, false);
5455
});
5556
} else {
5657
// @legacy for AssetMapper 6.3
5758
$autoImportLocator->expects($this->never())
58-
->method('locateAsset');
59+
->method('locateAutoImport');
5960
}
6061

6162
$generator = new ControllersMapGenerator(

0 commit comments

Comments
 (0)