8000 [AssetMapper] Add a "package specifier" to importmap in case import name != package+path by weaverryan · Pull Request #52024 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[AssetMapper] Add a "package specifier" to importmap in case import name != package+path #52024

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 16, 2023

Conversation

weaverryan
Copy link
Member
Q A
Branch? 6.4
Bug fix? yes
New feature? yes
Deprecations? no
Tickets None
License MIT

Hi!

Sorry for the large PR - this tightens up the component after the many recent enhancements.

tl;dr Makes "vendor" importmap entries work identically to "local" entries when it comes to preloading (a bug). Also tightens up ImportMapEntry, which is a tricky class because if an entry is "remote", it has 2 extra, required, properties.

Full changes:

  • Make ImportMapEntry stricter so that, when remote, version & packageModuleSpecifier are always set.
  • Set the "path" property always for ImportMapEntry, making them no different than local files through most of the system.
  • Related, fix a bug where if a vendor .js file imported another module, that other module was not previously preloaded when the vendor module was preloaded.
  • Fix a bug with downloaded package paths if you include a specific package - chart.js - and also a path - chart.js/auto. Previously, this would try to create both a file and directory called chart.js,
  • Fix bug where imports weren't matching if some spaces were missing

Cheers!


return Command::FAILURE;
}
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check is done in ImportMapManager with a nice error

// https://regex101.com/r/5Q38tj/1
private const IMPORT_PATTERN = '/(?:import\s+(?:(?:\*\s+as\s+\w+|[\w\s{},*]+)\s+from\s+)?|\bimport\()\s*[\'"`](\.\/[^\'"`]+|(\.\.\/)*[^\'"`]+)[\'"`]\s*[;\)]?/m';
// https://regex101.com/r/fquriB/1
private const IMPORT_PATTERN = '/(?:import\s*(?:(?:\*\s*as\s+\w+|[\w\s{},*]+)\s*from\s*)?|\bimport\()\s*[\'"`](\.\/[^\'"`]+|(\.\.\/)*[^\'"`]+)[\'"`]\s*[;\)]?/m';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Covered with a test

}

return $assetMapper->getAsset($importMapEntry->path);
return $assetMapper->getAssetFromSourcePath($importMapEntry->path);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g. bootstrap imports @popperjs/core. If bootstrap is ultimately preloaded, this is what allows us to also preload @popperjs/core.


$packageVersion = $entry->importName.($version ? '@'.$version : '');
$packageAudits[$packageVersion] ??= new ImportMapPackageAudit($entry->importName, $version);
$packageVersion = $packageName.'@'.$version;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug fix - e.g. if you have chart.js/auto, $packageName will now be just chart.js, which is what we need for the API call. Covered with a test.

Also, $version is now guaranteed not null here.

@@ -38,7 +40,7 @@ public function getEntries(): ImportMapEntries

$entries = new ImportMapEntries();
foreach ($importMapConfig ?? [] as $importName => $data) {
$validKeys = ['path', 'version', 'type', 'entrypoint', 'url'];
$validKeys = ['path', 'version', 'type', 'entrypoint', 'url', 'package_specifier'];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Supports the rare-use case that you require a package (e.g. bootstrap) but want to have its import called something else - shoestrap - so you can import 'shoestrap'. The importmap:require command supports this directly & it's documented.

public static function createRemote(string $importName, ImportMapType $importMapType, string $path, string $version, string $packageModuleSpecifier, bool $isEntrypoint): self
{
return new self($importName, $importMapType, $path, $isEntrypoint, $version, $packageModuleSpecifier);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private constructor + static factories. Done this way so that IF you are remote, we can guarantee that both $version and $packageModuleSpecifier ARE included.

}
$asset = $this->findAsset($entry->path);
if (!$asset) {
throw $this->createMissingImportMapAssetException($entry);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Example of why it's nice now that ImportMapEntry.path is populated even for vendor/remote assets :)

// remote packages aren't in the asset mapper & so don't have dependencies
if ($entry->isRemotePackage()) {
return $currentImportEntries;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An edge case (that does not currently apply) where vendor assets have relative imports, so we need to add those to the importmap.

More broadly, just another example of not treating the remote packages any differently.

@weaverryan weaverryan added the ❄️ Feature Freeze Important Pull Requests to finish before the next Symfony "feature freeze" label Oct 12, 2023
Copy link
Member
@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trusting you here :)

@fabpot
Copy link
Member
fabpot commented Oct 16, 2023

Thank you @weaverryan.

@fabpot fabpot force-pushed the asset-mapper-module-specifier branch from a0b1e27 to c80a1ab Compare October 16, 2023 20:19
@fabpot fabpot merged commit 8ca6931 into symfony:6.4 Oct 16, 2023
@weaverryan weaverryan deleted the asset-mapper-module-specifier branch October 16, 2023 20:39
This was referenced Oct 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AssetMapper Bug Feature ❄️ Feature Freeze Important Pull Requests to finish before the next Symfony "feature freeze" Status: Reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
0