-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[AssetMapper] Warn of missing or incompat dependencies #51849
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 < 8000 a class="Link--inTextBlock" href="https://docs.github.com/terms" target="_blank">terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AssetMapper] Warn of missing or incompat dependencies #51849
Conversation
why not installing the missing dependency automatically instead of doing it manually? |
They will be installed automatically when you first require the package - e.g. |
7fefbbe
to
0ad63e7
Compare
@@ -35,7 +35,7 @@ public function resolvePackages(array $packagesToRequire): array; | |||
* | |||
* @param array<string, ImportMapEntry> $importMapEntries | |||
* | |||
* @return array<string, string> | |||
* @return array<string, array{content: string, dependencies: string[]}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not ideal... not sure if it merits a new object - as this is entirely internal, unless someone makes their own package resolver.
return substr($importName, 0, $i); | ||
} | ||
|
||
return $importName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit of duplication with JsDelivrEsmResolver
, but we have a plan to centralize this in a future PR.
588a4df
to
c7df5dc
Compare
src/Symfony/Component/AssetMapper/ImportMap/PackageVersionProblem.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/AssetMapper/ImportMap/ImportMapVersionChecker.php
Outdated
Show resolved
Hide resolved
$dependencyVersionConstraint = $packageDependencies[$dependencyName] ?? null; | ||
|
||
if (null === $dependencyVersionConstraint) { | ||
// odd that this would happen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes me nervous 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, good point - that comment was a bit ominous. It would be an unexpected but not dangerous situation where we see that a vendor file has import 'foo'
, but then when we check the metadata for that package, it doesn't list foo
as a dependency at all. I have no idea if this will ever happen under normal circumstances - I can't think of a way (some misconfigured package ?).
But, to be safe, I've changed this to also issue a warning (like the other warnings) so the user is aware of it.
c7df5dc
to
d95d406
Compare
5e7a66d
to
db17147
Compare
@@ -17,6 +17,7 @@ | |||
], | |||
"require": { | |||
"php": ">=8.1", | |||
"composer/semver": "^3.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Be careful about that. The constraints are not 100% compatible between the npm and composer ecosystems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, is there an alternative? Checking into this quickly, differences I found:
- npm has a
1.0.0 - 2.0.0
syntax. - npm seems to have a
5.4.x
syntax which means5.4.*
.
I think this feature is pretty important, without it, it gets easy for your dependencies to "drift" out of sync (e.g. you install boostrap
today and we also give you @popper/core
, then you upgrade bootstrap but forget to upgrade popper and have no warning). So perhaps, IF we run into problems with odd, npm-specific dependency things we can handle those manually? Or maybe we can handle the above 2 items right now manually.
EDIT: I'll add a bit of pre-processing and tests to cover the edge-case differences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, the ~
operator does not work the same either
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a simple conversion system using all of the differences I could find. There are some edge-case things that can't be converted - e.g. stable
or https://example.com/file.js
, but I think that's ok. This is just a system to warn users of potential problems (like the peer dependency warning in npm). And if we're missing some real-world cases, we can find out about them and patch them. The "conversion" code is fairly minimal, as the differences don't appear to be too many.
Thanks for catching this!
d88507f
to
00f269f
Compare
|
e741d13
to
08b6059
Compare
@stof I'd love your thoughts on this PR now. A few notes: A) I do think this PR is important, so that your dependency versions don't drift away from each other. We're not building a full-blown package manager, but this seems like a pragmatic precaution. B) I think i've covered the npm-specific version constraint differences nicely C) In practice, it seems that when some packages are published, their dependencies in But, I do still think this PR is ready to go |
For C, it is a choice of each package maintainer.
Note that the fact that the JS ecosystem does not require flat dependencies means that it might be impossible to resolve dependencies in a flat way (and doing that requires a composer-like solver anyway and would fail in cases of a dependency hell). And this means that your installer should be able to support the case of having several versions of the same package to respect constraints otherwise it might cause issues. |
That's exactly the insight I was hoping for! 🙏
I think this is possible, via the importmap scopes. But I'd like to see if we actually need this. The consequence is that, right now, the system will work in the simple, "flat dependencies" kind of way. And I think that's fine. This PR would at least help users discover this potential problem more readily, then we can chat in the future about solving it. |
@@ -17,6 +17,7 @@ | |||
], | |||
"require": { | |||
"php": ">=8.1", | |||
"composer/semver": "^3.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about making this an optional dep and throw a useful LogicException in the command when used?
nvm, it's not an optional feat
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that... but we don't use it in a specific command, we run this in the background when using importmap:require
or importmap:update
. So in practice, it WILL be needed. And if we just didn't show the warning if this wasn't installed, then nobody would have it installed and it wouldn't do anything. I couldn't find a nice way to avoid it :)
src/Symfony/Component/AssetMapper/ImportMap/ImportMapVersionChecker.php
Outdated
Show resolved
Hide resolved
08b6059
to
42dfb9a
Compare
Thank you @weaverryan. |
Hi!
The aim of the
importmap.php
system is to be a simple way to manage your JS dependencies. But to make it robust enough for production use, it does need a few things - like theimportmap:audit
command in #51650. This PR adds a check, duringimportmap:require
andimportmap:update
, that reports any missing dependencies or dependencies with invalid versions. This is necessary so that, if packageA
requires packageB
, their versions don't "drift" over time without you being aware (e.g. you update packageA
to v3 but keep packageB
at v1, even though v3 ofA
requires v2 ofB
).Built on top of #51786.
Cheers!