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

Avoid circular dependencies in SemVer #957

Merged
merged 4 commits into from Jun 22, 2022

Conversation

sam-b-rose
Copy link
Contributor

Problem

Consumers using bundlers like Rollup or Webpack are hitting a circular dependency error coming from npm/node-semver. This is causing the SemVer,satisfies function to always return false when bundled, resulting in the following error:

semver-satisfies-error

What this PR is doing

A circular dependency between the Range and Comparator classes can cause issues for consumers who are trying to bundle extensions with vscode-languageclient as a dependency.

See related GitHub issue from npm/node-semver

Using Rollup to bundle VS Code extension

When importing all of SemVer When only importing individual functions
Screen Shot 2022-05-23 at 7 15 24 PM No circular deps and the extension works! ✨ Tested in external project using yalc

Verified the build output of client/lib/node/main.js is correctly importing only the needed functions, avoiding the circular dependency:

// client/lib/node/main.js

const semverParse = require("semver/functions/parse");
const semverSatisfies = require("semver/functions/satisfies");

A circular dependency between the Range and Comparator classes can cause
issues for consumers who are trying to bundle extensions with
vscode-languageclient as a dependency.

See related GitHub issue from [npm/node-semver](https://github.com/npm/node-semver)

- [[BUG] the package isn't compatible with Rollup due to require cycle microsoft#381](npm/node-semver#381)
@dbaeumer
Copy link
Member

@samrose3 I see the problem but I am not a fan of merging this in since it puts me at the mercy of the semver directory layout. IMO this should be addressed in semver directly. Wouldn't it make more sense to provide a PR there?

@dbaeumer dbaeumer added the info-needed Issue requires more information from poster label May 24, 2022
@sam-b-rose
Copy link
Contributor Author

I did look into making the fix in npm/node-semver first. However, it looks like it has been discussed quite a bit but no clear path forward on how to avoid the circular dependency given the current architecture between the Range and Comparator classes.

It does look like these are officially supported function paths provided by semver as documented in the Usage section. Seems reasonable that we could rely on these require paths only changing on a major update. And perhaps the circular dependencies in SemVer could be fixed by then if they do 🤞

Related discussion around circular dep issues in semver:

@sam-b-rose
Copy link
Contributor Author

Hi @dbaeumer! Just following up on this 👋

Given that accessing the semverParse and semverSatisfies functions are part of the supported usage for the node-semver package, would it be alright to merge this fix in? I feel pretty confident it is safe using these function paths.

For more context, we are using vscode-languageclient in a VS Code extension. We are needing to bundle node modules with our extension and are using Rollup for all our monorepo package builds.

I have tested this change and verified that it only pulls in the small parts of semver needed for the checkVersion function and allows Rollup to properly tree-shake the dependency. This also results in a smaller bundle size for us (the consumer of vscode-languageclient which is another win 🎉

Any other concerns I can help address? I've tried resolving the circular dep issue within node-semver but it is unfortunately a much bigger refactor than I have the context to solve :(

@sam-b-rose
Copy link
Contributor Author

sam-b-rose commented Jun 21, 2022

Just checking in, wanting to poke this along if possible 😄 any reconsideration to using the individual function imports for SemVer rather than the full package?

This would avoid the circular dep occurring in SemVer and improve the bundle size for those bundling vscode-languageclient in their package.

@dbaeumer
Copy link
Member

I looked at the semver documentation and they indeed advocate using the functions directly. Hope that keep that stable as well :-).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
info-needed Issue requires more information from poster
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants