Skip to content

Commit fda9ddb

Browse files
smnandrefabpot
authored andcommitted
[AssetMapper] Fix eager imports are not deduplicated
1 parent 93e7adc commit fda9ddb

File tree

2 files changed

+41
-11
lines changed

2 files changed

+41
-11
lines changed

ImportMap/ImportMapGenerator.php

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -217,25 +217,36 @@ private function findAsset(string $path): ?MappedAsset
217217
return $this->assetMapper->getAssetFromSourcePath($this->importMapConfigReader->convertPathToFilesystemPath($path));
218218
}
219219

220+
/**
221+
* Finds recursively all the non-lazy modules imported by an asset.
222+
*
223+
* @return array<string> The array of deduplicated import names
224+
*/
220225
private function findEagerImports(MappedAsset $asset): array
221226
{
222227
$dependencies = [];
223-
foreach ($asset->getJavaScriptImports() as $javaScriptImport) {
224-
if ($javaScriptImport->isLazy) {
225-
continue;
226-
}
228+
$queue = [$asset];
227229

228-
$dependencies[] = $javaScriptImport->importName;
230+
while ($asset = array_shift($queue)) {
231+
foreach ($asset->getJavaScriptImports() as $javaScriptImport) {
232+
if ($javaScriptImport->isLazy) {
233+
continue;
234+
}
235+
if (isset($dependencies[$javaScriptImport->importName])) {
236+
continue;
237+
}
238+
$dependencies[$javaScriptImport->importName] = true;
229239

230-
// Follow its imports!
231-
if (!$nextAsset = $this->assetMapper->getAsset($javaScriptImport->assetLogicalPath)) {
232-
// should not happen at this point, unless something added a bogus JavaScriptImport to this asset
233-
throw new LogicException(sprintf('Cannot find imported JavaScript asset "%s" in asset mapper.', $javaScriptImport->assetLogicalPath));
240+
// Follow its imports!
241+
if (!$javaScriptAsset = $this->assetMapper->getAsset($javaScriptImport->assetLogicalPath)) {
242+
// should not happen at this point, unless something added a bogus JavaScriptImport to this asset
243+
throw new LogicException(sprintf('Cannot find JavaScript asset "%s" (imported in "%s") in asset mapper.', $javaScriptImport->assetLogicalPath, $asset->logicalPath));
244+
}
245+
$queue[] = $javaScriptAsset;
234246
}
235-
$dependencies = array_merge($dependencies, $this->findEagerImports($nextAsset));
236247
}
237248

238-
return $dependencies;
249+
return array_keys($dependencies);
239250
}
240251

241252
private function createMissingImportMapAssetException(ImportMapEntry $entry): \InvalidArgumentException

Tests/ImportMap/ImportMapGeneratorTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,25 @@ public function getEagerEntrypointImportsTests(): iterable
671671
['/assets/imports_simple.js', '/assets/simple.js'],
672672
[$simpleAsset, $importsSimpleAsset],
673673
];
674+
675+
$importsSimpleAsset2 = new MappedAsset(
676+
'imports_simple2.js',
677+
'/path/to/imports_simple2.js',
678+
publicPathWithoutDigest: '/assets/imports_simple2.js',
679+
javaScriptImports: [new JavaScriptImport('/assets/simple.js', assetLogicalPath: $simpleAsset->logicalPath, assetSourcePath: $simpleAsset->sourcePath, isLazy: false)]
680+
);
681+
yield 'an entry recursive dependencies are deduplicated' => [
682+
new MappedAsset(
683+
'app.js',
684+
publicPath: '/assets/app.js',
685+
javaScriptImports: [
686+
new JavaScriptImport('/assets/imports_simple.js', assetLogicalPath: $importsSimpleAsset->logicalPath, assetSourcePath: $importsSimpleAsset->sourcePath, isLazy: false),
687+
new JavaScriptImport('/assets/imports_simple2.js', assetLogicalPath: $importsSimpleAsset2->logicalPath, assetSourcePath: $importsSimpleAsset2->sourcePath, isLazy: false),
688+
]
689+
),
690+
['/assets/imports_simple.js', '/assets/imports_simple2.js', '/assets/simple.js'],
691+
[$simpleAsset, $importsSimpleAsset, $importsSimpleAsset2],
692+
];
674693
}
675694

676695
public function testFindEagerEntrypointImportsUsesCacheFile()

0 commit comments

Comments
 (0)