yarnpkg/yarn

yarn link does not install package dependencies

OliverUv opened this issue · 23 comments

Bug.

What is the current behavior?

oliveruv@computer~/w/yarnbug> tree .
.
├── library
│   └── package.json
└── user
    └── package.json

2 directories, 2 files

oliveruv@computer~/w/yarnbug> cat user/package.json
{
  "name": "user",
  "version": "1.0.0",
  "description": "Target project for yarn link",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "repository": {
    "type": "git",
    "url": "git://github.com/OrKoN/npm-link-shared.git"
  },
  "private": "true",
  "dependencies": {
    "module-a": "*"
  }
}

oliveruv@computer~/w/yarnbug> cat library/package.json
{
  "name": "library",
  "version": "1.0.0",
  "description": "library that depends on other packages",
  "main": "index.js",
  "repository": {
    "type": "git",
    "url": "git://github.com/OrKoN/npm-link-shared.git"
  },
  "private": "true",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "lodash": "*"
  },
  "devDependencies": {
    "chai": "*"
  }
}

oliveruv@computer~/w/yarnbug> cd library/

oliveruv@computer~/w/y/library> yarn link
yarn link v0.21.3
success Registered "library".
info You can now run `yarn link "library"` in the projects where you want to use this module and it will be used instead.
Done in 0.12s.

oliveruv@computer~/w/y/library> cd ../user/

oliveruv@computer~/w/y/user> yarn link library
yarn link v0.21.3
success Registered "library".
Done in 0.12s.

oliveruv@computer~/w/y/user> cd ..

oliveruv@computer~/w/yarnbug> tree .
.
├── library
│   └── package.json
└── user
    ├── node_modules
    │   └── library -> ../../library
    └── package.json

4 directories, 2 files

oliveruv@computer~/w/yarnbug> yarn --version
0.21.3

oliveruv@computer~/w/yarnbug> node --version
v6.10.0

If the current behavior is a bug, please provide the steps to reproduce.

What is the expected behavior?

The last tree . command should show that library has a node_modules directory with lodash installed into it. npm seems to run install on every linked package.

Please mention your node.js, yarn and operating system version.

oliveruv@computer~> cat /etc/os-release
NAME="Ubuntu"
VERSION="16.10 (Yakkety Yak)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.10"
VERSION_ID="16.10"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="http://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=yakkety
UBUNTU_CODENAME=yakkety

oliveruv@computer~> npm --version
3.10.10

oliveruv@computer~> yarn --version
0.21.3

oliveruv@computer~> uname -srvp
Linux 4.8.0-41-generic #44-Ubuntu SMP Fri Mar 3 15:27:17 UTC 2017 x86_64

Waiting on this here OrKoN/npm-link-shared#10

Ah, sorry, expected behavior is that lodash, chia, and their dependencies will be installed in library/node_modules, not just lodash.

With yarn link --production or yarn link --production=true only lodash should exist.

Note: npm does the installation during the first invocation of npm link while standing in ./library/

Another addition to this:

I have actually found the current behavior to be better than npm's behavior! My use case: Using docker volumes to mount dependencies so that I can npm link them during development. The npm link call inside the docker container will error out, because npm does not have write access to the outside folder (and I would prefer not to a+rwx/0775 it). This allows the developer to execute npm install etc in the environment where they are developing the external module, instead of having npm do this automagically whenever it feels like it.

If you do add implement this to reach feature parity with npm, I would love a method to opt out of this time consuming and, for me, environment breaking behavior, e.g. with a flag like yarn link --no-install.

wclr commented

using yarn link with installing dependency and without changing package.json/yarn.lock would causes inconsistency in dependency set. Actually using yarn/npm link causes kind of inconsistency anyway and brings a lot of other issues. Yarn installes only dependencies that derive from package.json and this is consistent approach. So far I use yalc for working with local packages.

The only way yarn link is actually useful is if it installs dependencies. Most packages have dependencies and if you're testing one package in another, you need those dependencies.

wclr commented

@whitecolor I don't want to

I would want yarn link to also install deps that are linked by the package I'm linking... IOW I might have multiple nested "links" that I want to all link to the working directory for that project. Is this possible? It doesn't seem to be the default behavior.

Hi, any updates on this?
Today it is rather difficult to test a new library (with usage of yarn link because it's not published yet). I can only test it by adding all subdependencies via "yarn add" in the application using my library (application -> library -> subdependencies). After the first publish I have to remove all those subdependencies from the application again.

My workaround so far has been to use a build script that does yarn install on everything that is depended on with link before doing yarn install on the main package which requires them.
It's not ideal, but I think it is a bit simpler than other workarounds.

I would absolutely want link (or even something new like link-install) to automatically do this. Maintaining the build script logic separately undermines some of the benefits of using package management, I feel a bit gross using it 😄.

wclr commented

Today it is rather difficult to test a new library (with usage of yarn link because it's not published yet).

Try yalc - made for this purpose.

The way I was able to handle this is via link:../module in package.json of the module using the lib, and then linking it via yarn link in the modules where it is used from the base path.

I was quite surprised by this behavioural difference between Yarn and NPM. It affectively makes cross-module development using link difficult and confusing. If I link a package, I want its deps too. I can't really think of a scenario where you wouldn't.

@whitecolor Thanks for the Yalc, I started using it and it works like a magic :)

This issue just cost me a lot of time to figure out why a build in a project into which I had linked a dependent package with yarn link broke. It would probably be OK to expecting developers to run yarn install manually after linking, maybe displaying a hint when running running yarn link to save them some time. But the fact that even yarn install does not lead to the expected result is very confusing.

Still no plans to address this?

I'm wondering: It seems like with workspaces yarn is able to handle symlinks and installing their dependencies as well:

The actual packages are symlinked in node_modules – if you change dependencies and run yarn install, it works well.

But when I run a yarn install after linking an external package, the dependency tree for that package seems to be build from the cache, if the package was published.

I tried to work around this by giving the package a version that was not published, but then yarn install forces me to choose a published version.

Grawl commented

I am trying to make some changes to some package. I link it to project where it used, and make changes to it's code and add some dependencies to make it work. But When I run yarn install in project, dependencies added to library is not added to project: Yarn says "Already up to date", but project cannot work with library without required dependencies.

Totally confused. Is there a way to work with dependencies of dependencies?

This is the issue here, yarn seems to resolve the dependencies from it's cache. So if the library has already been published, it will take the published dependencies.

We found a workaround for a monorepo setup:

  • Create a folder where you'll place your links, e.g. .wip (work in progress)
  • Ignore that folder in git
  • Add it to your workspaces: ".wip/*, .wip/@*/*"
  • Link the libraries you're working on: win: mklink /j mylib \Users\…\mylib, *nix: ln -s mylib ~/…/mylib
  • yarn

After that, yarn will treat those dependencies just as packages in the monorepo, link them (again) in node_modules, and also correctly resolve their dependencies.

Grawl commented

It’s what yalc do, right?

Yes, Yalc is what gave us the idea for the work-around. Yalc adds quite some work though, it's always necessary to publish after changing something because of the simulated registry – we didn't need that.

Bug.

What is the current behavior?

oliveruv@computer~/w/yarnbug> tree .
.
├── library
│   └── package.json
└── user
    └── package.json

2 directories, 2 files

oliveruv@computer~/w/yarnbug> cat user/package.json
{
  "name": "user",
  "version": "1.0.0",
  "description": "Target project for yarn link",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "repository": {
    "type": "git",
    "url": "git://github.com/OrKoN/npm-link-shared.git"
  },
  "private": "true",
  "dependencies": {
    "module-a": "*"
  }
}

oliveruv@computer~/w/yarnbug> cat library/package.json
{
  "name": "library",
  "version": "1.0.0",
  "description": "library that depends on other packages",
  "main": "index.js",
  "repository": {
    "type": "git",
    "url": "git://github.com/OrKoN/npm-link-shared.git"
  },
  "private": "true",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "lodash": "*"
  },
  "devDependencies": {
    "chai": "*"
  }
}

oliveruv@computer~/w/yarnbug> cd library/

oliveruv@computer~/w/y/library> yarn link
yarn link v0.21.3
success Registered "library".
info You can now run `yarn link "library"` in the projects where you want to use this module and it will be used instead.
Done in 0.12s.

oliveruv@computer~/w/y/library> cd ../user/

oliveruv@computer~/w/y/user> yarn link library
yarn link v0.21.3
success Registered "library".
Done in 0.12s.

oliveruv@computer~/w/y/user> cd ..

oliveruv@computer~/w/yarnbug> tree .
.
├── library
│   └── package.json
└── user
    ├── node_modules
    │   └── library -> ../../library
    └── package.json

4 directories, 2 files

oliveruv@computer~/w/yarnbug> yarn --version
0.21.3

oliveruv@computer~/w/yarnbug> node --version
v6.10.0

If the current behavior is a bug, please provide the steps to reproduce.

What is the expected behavior?

The last tree . command should show that library has a node_modules directory with lodash installed into it. npm seems to run install on every linked package.

Please mention your node.js, yarn and operating system version.

oliveruv@computer~> cat /etc/os-release
NAME="Ubuntu"
VERSION="16.10 (Yakkety Yak)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.10"
VERSION_ID="16.10"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="http://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=yakkety
UBUNTU_CODENAME=yakkety

oliveruv@computer~> npm --version
3.10.10

oliveruv@computer~> yarn --version
0.21.3

oliveruv@computer~> uname -srvp
Linux 4.8.0-41-generic #44-Ubuntu SMP Fri Mar 3 15:27:17 UTC 2017 x86_64

Not need to $~/w/yarnbug/library> yarn link or $~/w/yarnbug/user> yarn link library, just do $~/w/yarnbug/user> yarn add link:~/w/yarnbug/library, then the dependencies of libray, like lodash will be installed in user/node_modules.

If you want that all the dependencies of libray, like lodash or chia to be installed in library/node_modules, you should do $~/w/yarnbug/library> yarn install.

Closing as fixed in v2 where PnP and the portal: protocol can handle this, node_modules can't as it would need to modify the external target which is unsafe and thus not allowed

https://yarnpkg.com/getting-started/migration