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

[WIP] Add options to improve development with linked modules #3753

Closed
wants to merge 3 commits into from

Conversation

devongovett
Copy link
Contributor

Summary

Currently, setting up and maintaining links between many modules in local development is very painful. Not only do you have to manually link modules together, but once you do you can easily end up with many duplicate dependencies. This leads to errors e.g. when multiple copies of react are loaded if several linked dependencies also depend on react. A workaround is to install react globally and link to that from every place that uses it, but doing this everywhere is painful.

This pull introduces two options to help with these problems:

  1. yarn link --deep - Instead of linking the global copy to the current directory itself, this creates a link for every file/directory inside the current directory excluding ignored files (most importantly node_modules). This means that when you install a linked module, the dependencies are not duplicated (see 2). It does mean that if you add a file in the root of the linked module, you must run yarn link --deep again to add a link to it globally, however. This is kinda like the knit proposal.
  2. yarn install --link - This automatically sets up links to all dependencies that are linked globally and installs their dependencies. This means that once you've setup global links for all of the dependencies in your project with yarn link (e.g. after cloning from git), you can just run this one command to setup all of the links and install all normal dependencies in one go. If those links are produced with the --deep option, dependencies will be fully deduped.

As mentioned above, this is similar to the knit proposal. (1) is pretty much the same idea as plain yarn knit. (2) is different in that it automatically installs all linked dependencies rather than needing to manually call yarn knit dep for each one. I think this is important to enable easy setup of projects using many linked modules. However, I should note that you can also call yarn add dep --link as well, which is more similar to yarn knit dep.

I know workspaces are also being worked on at the moment, however I think this solves a different problem. Where workspaces are great for a tree of related modules (e.g. in a monorepo), the options in this pull are for linking together modules in separate trees, e.g. something that might be shared between multiple workspaces.

Test plan

If this is something the yarn community is interested in including, I'll clean up this PR, add tests and such. So far I'm just playing around, but it seems to work for my needs.

Creates a symlink for each file/directory inside a package instead of the directory itself. This has the effect of excluding node_modules (and other files excluded by filters).
This will automatically link dependencies to the globally linked copy when installing. Avoids having to manually setup links when setting up a project locally.
@devongovett
Copy link
Contributor Author

One current issue is with the way the node require resolution algorithm works. Dependencies of symlinked modules are resolved relative to the realpath, not the symlink. This means that you'll still get duplicates if both modules depend on a third dependency, or errors if that dependency is not installed in either place.

One option to solve this is to use hard links instead of soft links. Hard links are not without their problems though. One is that you can't hard link directories on some systems I think (works on OS X, but I don't think on Linux?).

Another is the recently added runtime option for node --preserve-symlinks, which skips getting the realpath when resolving modules. Something similar would need to be added to browserify/webpack to solve this there as well. Not sure that's super great as it relies on users enabling an option for linked modules to work correctly.

@devongovett
Copy link
Contributor Author

Made a pull to add support for --preserve-symlinks to browserify: browserify/browserify#1742

@arcanis
Copy link
Member

arcanis commented Jun 29, 2017

I think you might be interested by the workspace (two other parts can be found in the same repository) proposal, that is currently implemented behind a flag.

@devongovett
Copy link
Contributor Author

@arcanis yep, workspaces are cool, but serve a different purpose I think. See my note about it in the PR description.

@bestander
Copy link
Member

Hey, @devongovett, great job at looking into this!

My concern is that yarn may have too many ways to link projects and we need to make an effort to consolidate a few.

Do you want maybe to take over knit RFC yarnpkg/rfcs#41?
It is not being worked on right now, maybe you could send an RFC PR updating knit command with more stress on comparing with other ways to link projects (link command, file:, link:, workspaces, pack/install)

@devongovett
Copy link
Contributor Author

@bestander sounds like a good idea. I'll take a look next week when I'm back from vacation!

@devongovett
Copy link
Contributor Author

Updated the knit RFC here: yarnpkg/rfcs#73

@BYK
Copy link
Member

BYK commented Nov 14, 2017

@devongovett what is the current status of your work and this PR? Shall we close it or try to help you get it merged?

@arcanis
Copy link
Member

arcanis commented Feb 27, 2018

Hi! I'm really grateful for the work you put in this PR, but unfortunately the project moved forward since you submitted it and I fear it can be merged in this current state. I'm going to close it, but please feel free to check if the problem still exists, and to rebase your work on top of the current master and open a new PR if it's the case. Again, sorry we didn't got around merging it sooner!

@arcanis arcanis closed this Feb 27, 2018
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

5 participants