Prioritize direct dependency if available#192
Conversation
|
|
||
| try { | ||
| const yarnLock = fs.readFileSync(file, 'utf8'); | ||
| const packageJson = packageJsonPath ? fs.readFileSync(packageJsonPath, 'utf8') : undefined; |
There was a problem hiding this comment.
Nit: I rather use null instead of undefined in this case. It feels more explicit to me.
| version "0.1.0" | ||
| resolved "http://example.com/a-package/0.1.0" | ||
|
|
||
| other-package@>=1.0.0: |
There was a problem hiding this comment.
We should remove any mention to other-package in this test, as it is not related to the test intention.
There was a problem hiding this comment.
This is actually important as it verifies that packages that are not in package.json fall back to the highest strategy.
|
|
||
| test('prioritizes direct requirements if present', () => { | ||
| const yarn_lock = outdent` | ||
| a-package@*: |
There was a problem hiding this comment.
Ideally (and I acknowledge this is slightly out of the scope of the PR), we should use a similar yarn.lock to test all strategies (i.e. the first two tests in this file). That way it's more clear what's the different behaviour of each strategy.
|
Interesting idea. I do see the problem you are trying to solve, and this seems like a neat solution. You mentioned I think this should be its own strategy, let's call it On a higher level, this PR highlight the deeper problem of not having control of which version is used to deduplicate. Using strategies is just a proxy to automatically select the versions. Using Before merging this PR I'd like to see:
I may help with those if you want, but I can't commit to a timeline right now. |
| for (const packageInstance of packageInstances) { | ||
| if (versions.has(packageInstance.installedVersion)) continue; | ||
| if (versions.has(packageInstance.installedVersion)) { | ||
| const existingPackage = versions.get(packageInstance.installedVersion)!; |
There was a problem hiding this comment.
I don't get why we need to add isDirectDependency to every dep in the tree.
Wouldn't checking directDependencies.has(entryName) when sorting the versions (line 177) suffice? Especially when we encapsulate this logic into its own strategy.
There was a problem hiding this comment.
I've moved this down here so only Version needs the isDirectDependency flag. There's no entryName to check in the version sorting step so it's not that easy to do it there. If we absolutely want to avoid having this, I suppose it's possible to loop over satisfies in the sorting function and check if any requested version is a direct dependency but that'd just be worse for performance.
thatsmydoing
left a comment
There was a problem hiding this comment.
Thanks for the feedback, I'll rework it into a strategy instead.
| version "0.1.0" | ||
| resolved "http://example.com/a-package/0.1.0" | ||
|
|
||
| other-package@>=1.0.0: |
There was a problem hiding this comment.
This is actually important as it verifies that packages that are not in package.json fall back to the highest strategy.
0412618 to
489381a
Compare
| .option( | ||
| '-s, --strategy <strategy>', | ||
| 'deduplication strategy. Valid values: fewer, highest. Default is "highest"', | ||
| 'deduplication strategy. Valid values: fewer, highest, direct.', |
There was a problem hiding this comment.
commander already shows the default value so I removed Default is "highest" as it was redundant.
| for (const packageInstance of packageInstances) { | ||
| if (versions.has(packageInstance.installedVersion)) continue; | ||
| if (versions.has(packageInstance.installedVersion)) { | ||
| const existingPackage = versions.get(packageInstance.installedVersion)!; |
There was a problem hiding this comment.
I've moved this down here so only Version needs the isDirectDependency flag. There's no entryName to check in the version sorting step so it's not that easy to do it there. If we absolutely want to avoid having this, I suppose it's possible to loop over satisfies in the sorting function and check if any requested version is a direct dependency but that'd just be worse for performance.
|
Sorry, I haven't been available to review this change. I'll have a look as soon as possible. |
|
This would actually be nice to have :) |
This is more of a proof of concept and request for comments. This PR adds support for prioritizing direct dependencies (ones listed in
package.json).For example, if our
package.jsonhas the followingat the time of writing, this will result in these yarn.lock entries
@types/react-reduxpulls in@types/react@*which is correct since it does work with any react version. However, this is problematic for us since when we use the react-redux types, it leaks in the newer react 18 types which are not compatible with the react 17 types. So we absolutely want both to resolve to17.0.49.This can be worked around using yarn resolutions which is what we're doing now but it would be nice if yarn-deduplicate could do this for us.
With the default
higheststrategy, these won't be deduplicated. We could usefewerto deduplicate here but that affects everything else but we'd rather it apply only to direct dependencies like@types/reacthere.This PR adds a
--package-jsonflag which you can point to an existingpackage.jsonwhere it can get information on which versions are direct dependencies and then prioritizes those on top of whatever strategy is picked.Is this sound? I'm not too confident with how this interacts with strategies (and should this be a strategy in itself?)