-
-
Notifications
You must be signed in to change notification settings - Fork 669
[Feature]: Support resolve the modules with hard-links #5912
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
Comments
Relate pnpm hardlinks Pnpm use symlinks from package node_modules to workspace node_modules, and use hardlinks from workspace node_modules files to global files. Currently resolver can only deal with symlinks and get the node_modules of workspace. So this issue should occur when cc @Boshen |
This isn't a bundler problem. Your codebase is no longer a monorepo, it's just different packages put inside the same codebase, and then you enabled compilation from source. I don't have an exact solution, but you can try:
|
there's no source or target role around paths sharing the same inode, thus i believe it's impossible to determine the resolved path without a rule. in your plugin, the resolved path is determined by the first request. i think it is unstable. |
I agree that having such a huge monorepo with a bunch of pnpm workspaces inside is not a good way. But this helps us to collaborate between different teams efficiently. And our build tools based on I don't think Not to mention |
I'm not sure what do you mean by "there's no source or target role around paths sharing the same inode". Could you please explain that to me in detail? Thanks!
I agree that it is not 100% stable, but it is correct(at least from our experience). |
as you know, a symbolic link represents a link file linking to another file, when a resolver resolves a request that points to a symbolic link with option like while a "hard link" just represents a path to an inode node. in your case, there's two "hard links" linked to a same inode node. the two paths are of equal status thus a resolver cannot say "who it prefer". so i do think, other than just "resolving paths with same inode number to one path", we need an explicit option to tell "which path the resolver should choose when resolving paths with same inode number to one path" |
"use the first coming result" might not be a good idea as it will change. it might cause problem when there're different loaders/plugins logic against the two paths sharing the same inode number. though it's rarely common in node_modules scene. |
Another concern I have is that the term "inode" is closely associated with filesystems, so I'm not sure if it will function properly in filesystems without inode feature, such NTFS (though it has a similiar feature). just to address some concerns, I know nothing about filesystem( also not intended to reject any possible feature |
@colinaaa Can you provide a github test repository that replicates this project structure? |
@Boshen Check this out! https://github.com/colinaaa/rspack-hardlink-repro |
I agree that using the first coming result is not an ideal way. But we have to return results for each request, and there is no way to know if there are requests to come in the future. So the only way to make it work is to return the first coming result. |
In my opinion, "use the first coming result" or inode check of hardlink are both business-specific logic that can be ensured by the business itself. They are not suitable to implement in OXC. But in Rspack, the before_resolve hook cannot get the resolved path, and the after_resolve hook would generate full request, which leading to a substantial increase in transmission costs. Rspack does indeed need a low-cost way to modify the resolve result. |
Is this replicated correctly? |
Did you run the |
@Boshen Sorry! Should run ![]() |
Done in #5924 |
What problem does this feature solve?
pnpm creates hard links from the global store to the project's node_modules folders.
For example, imagine you have the following directory structure:
packages/a
andpackages/b
have the same version oflodash
as a dependency. But they are different symlink that points to different files.Since two
lodash/lodash.js
points to different files, bothrspack
(oroxc
internally) andwebpack
(orenhanced-resolve
internally) treat the two files as unrelated. So at build time, two copies oflodash
code will be packaged in the output bundle, even if their content is the same.However, it can be found that in the file system, the two
lodash.js
point exactly to the same inode node. Which means they are the same file in physical storage.To solve the problem, we created a
webpack
plugin to cache the request:And it works as expected in
webpack
, the duplicated modules have been eliminated.But when we are trying to migrate to
rspack
, we found thatresolve.plugins
is not supported(#3890).So it would be great if
rspack
oroxc
supports dealing with hard links like this by default(I would like to file an issue toenhanced-resolve
, too).What does the proposed API of configuration look like?
It would be great if this is enabled by default(just like
symlinks
options ofenhanced-resolve
).It is acceptable if this is an
experimental
configuration or a sub-configuration inresolve
. E.g.:The text was updated successfully, but these errors were encountered: