Skip to content
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

feat: add initial internal npm client and dependency resolver #15446

Merged
merged 4 commits into from
Aug 10, 2022

Conversation

dsherret
Copy link
Member

@dsherret dsherret commented Aug 10, 2022

Adds an initial very basic npm client and dependency resolver. It is missing a lot of things (ex. peer dependency support) and differs from npm's cli resolution—we're going to start with this implementation then work on improving it and building it up.

There are no tests for this yet because we're going to test this in integration once the other parts have landed.

Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

LGTM, just some minor nitpicks

@@ -841,10 +842,11 @@ dependencies = [
"ring",
"rustyline",
"rustyline-derive",
"semver-parser 0.10.2",
"semver 1.0.13",
Copy link
Member

Choose a reason for hiding this comment

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

Try to force a single 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.

It seems like some crates are using a very old version.

cli/fs_util.rs Show resolved Hide resolved
cli/npm/cache.rs Show resolved Hide resolved
cli/npm/cache.rs Show resolved Hide resolved
if package_folder.exists()
// if this file exists, then the package didn't successfully extract
// the first time, or another process is currently extracting the zip file
&& !package_folder.join(NPM_PACKAGE_SYNC_LOCK_FILENAME).exists()
Copy link
Member

Choose a reason for hiding this comment

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

What will happen if a process locks and then errors out? Won't this lock file block all subsequent tries?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, right now it doesn't block any processes. There's a larger comment explaining it here and how it can be improved in the future for when there are multiple processes trying to extract the same package at the exact same time: https://github.com/denoland/deno/pull/15446/files#diff-c38e5f78351feb4850428062e3a3cc3796ca8ede71130bc2dd3b4760c9f2aa80R39-R46

cli/npm/cache.rs Show resolved Hide resolved
cli/npm/mod.rs Outdated Show resolved Hide resolved
cli/npm/registry.rs Show resolved Hide resolved
cli/npm/resolution.rs Outdated Show resolved Hide resolved
None => bail!(
concat!(
"Could not find package '{}' matching {}{}. ",
"Try retreiving the latest npm package information by running with --reload",
Copy link
Member

Choose a reason for hiding this comment

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

We should consider making --reload work just for npm packages like --reload=npm:

Copy link
Member Author

@dsherret dsherret Aug 10, 2022

Choose a reason for hiding this comment

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

Oh, yeah definitely. I wrote this down as a todo.

@dsherret dsherret merged commit d9fae38 into denoland:main Aug 10, 2022
@dsherret dsherret deleted the initial_npm_client branch August 10, 2022 19:24
@isaacs
Copy link

isaacs commented Aug 10, 2022

Feel free to ignore/dismiss/hide this suggestion if it's off topic. I don't use deno personally outside of some play projects, so I don't have a huge stake in this really, but I think this direction is cool, and have a bit of experience in this space.

One thing occurs to me, though, you mentioned that the dependency resolver isn't complete, doesn't support peer dep resolution, etc. Have you considered the approach of porting @npmcli/arborist to rust?

It'd be a relatively straightforward way to ensure that you are working with the same approach that npm uses, which for better or worse, has had a ton of play-testing, reflecting well over a decade of focused time and energy. So, like, even the less "elegant" ways it approaches some things got to be that way by modeling how users actually expect it to work (which is, quite often, completely irrational and inelegant! But humans gonna human.)

Plus, it seems like there's a super good chance that a rust implementation of Arborist would be significantly faster and more memory efficient, and perhaps even be a way to speed up npm (that is, if it replaced the JS version entirely or in part). And even taking it on and failing would be a really great way to get fresh eyes on a lot of what it does, some of which quite frankly has probably never really gotten a thorough review. Probably a lot more work, but the result could be amazing for the whole JS community, and it'd be a very impressive project.

If you do decide dig into it and have questions (or just complaints lol), I'd be happy to provide answers if I can.

@dsherret
Copy link
Member Author

Hey @isaacs, thanks for the suggestion! We're planning on improving the approach to align more with npm's resolution in the future, but for this experiment we just want something quick to try it out. What we're building overall, doesn't exactly align with how npm works (more details in the coming weeks) and so I don't believe a straight port of arborist would work in this case, though it would be beneficial to look at the code to align the resolution more. With our upcomming approach, there will be packages that won't work, so we want to get an idea of just how incompatible it is (that said, I would expect it to be a lot more compatible than Deno currently is). If we find it doesn't work then we can pivot.

@isaacs
Copy link

isaacs commented Aug 11, 2022

Ah, I should have probably specified, I'm only suggesting the abstract tree building/resolution aspects of arborist might benefit from being ported for deno's use. The reification, packing, etc is probably mostly inapplicable.

@dsherret
Copy link
Member Author

@isaacs yeah, definitely! We’d like to align the resolution as much as possible. We’re just going to get the high level pieces in place first, evaluate the approach, then start diving into these details. Probably won’t be for a few weeks though.

@isaacs
Copy link

isaacs commented Aug 11, 2022

Probably won’t be for a few weeks though.

No rush. Given my pace of OSS engagement lately, "a few weeks" may as well be "right now" 😅

@isaacs
Copy link

isaacs commented Aug 11, 2022

If you have any questions about how npm does any of the other stuff, though, or just run into sticky puzzling situations, I'm happy to help if I can.

@dsherret
Copy link
Member Author

Thanks! We'll definitely keep that in mind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants