Yarn: Broken install for local dependencies with relative paths

Created on 26 Apr 2018  ยท  3Comments  ยท  Source: yarnpkg/yarn

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

The project is located in /home/user/Projects/yarn-test/.

Having local dependencies like in monorepo, which are specified by a relative path in package.json gives an error message:

$ yarn
yarn install v1.6.0
info No lockfile found.
[1/4] Resolving packages...
error Package "network" refers to a non-existing file '"/home/user/Projects/network"'.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
Error: Package "utils" refers to a non-existing file '"/home/user/Projects/utils"'.
    at MessageError.ExtendableBuiltin (/usr/share/yarn/lib/cli.js:237:66)
    at new MessageError (/usr/share/yarn/lib/cli.js:266:123)
    at FileResolver.<anonymous> (/usr/share/yarn/lib/cli.js:51386:15)
    at Generator.next (<anonymous>)
    at step (/usr/share/yarn/lib/cli.js:98:30)
    at /usr/share/yarn/lib/cli.js:109:13

Basically, what happens is that relative paths inside dependencies are resolved from the project root instead of the dependency itself. So, searching for network in controls instead of /home/user/Projects/yarn-test/packages/controlls/../network it goes by /home/user/Projects/yarn-test/../network.

What's interesting, installing inside controls directory works fine (as it should). But only if the root package.json (the on in the yarn-test) has no workspaces set up. In other case it fails with the same issue.

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

Example: https://github.com/the-spyke/issues_yarn-install

What is the expected behavior?

  1. It should anywhere install without errors.
  2. With or without workspaces in the root directory.

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

Node: 10.0.0
npm: 6.0.0
Yarn: 1.6.0
OS: Ubuntu 17.10.1 x86_64 (4.13.0-39-generic)
triaged

Most helpful comment

After much tracing through the code, I finally found the code that handles this. Incase anyone comes back to this issue later looking for answers or later decides this is a bug:

This code:
https://github.com/yarnpkg/yarn/blob/master/src/util/normalize-manifest/resolve-relative.js#L32-L38
only fixes relative paths is they start with file: or link:

So if someone later wanted to handle "bare" relative paths, they could change that here.

Just be aware that by npm rules, a dependency like foo/bar is _not_ a relative path. It is a github link to user foo repository bar so you can't just see if something looks like a path. You would most likely want to check for a leading ./ or ../

All 3 comments

You should be specifying file: as the dependency type instead of just a relative path, as in the npm docs for specifying local paths.

~/Projects/issues_yarn-install (master *) ๐Ÿ’   git diff
diff --git a/package.json b/package.json
index 110188b..8b953c6 100644
--- a/package.json
+++ b/package.json
@@ -10,8 +10,8 @@
   "author": "",
   "license": "The Unlicense",
   "dependencies": {
-      "controls": "./packages/controls",
-      "network": "./packages/network",
-      "utils": "./packages/utils"
+      "controls": "file:./packages/controls",
+      "network": "file:./packages/network",
+      "utils": "file:./packages/utils"
   }
 }
diff --git a/packages/controls/package.json b/packages/controls/package.json
index 6ae85cc..33734f9 100644
--- a/packages/controls/package.json
+++ b/packages/controls/package.json
@@ -9,7 +9,7 @@
   "author": "",
   "license": "The Unlicense",
   "dependencies": {
-      "network": "../network",
-      "utils": "../utils"
+      "network": "file:../network",
+      "utils": "file:../utils"
   }
 }
diff --git a/packages/network/package.json b/packages/network/package.json
index 7d2a118..69fb860 100644
--- a/packages/network/package.json
+++ b/packages/network/package.json
@@ -9,6 +9,6 @@
   "author": "",
   "license": "The Unlicense",
   "dependencies": {
-      "utils": "../utils"
+      "utils": "file:../utils"
   }
 }

~/Projects/issues_yarn-install (master *) ๐Ÿ’   yarn
yarn install v1.6.0
[1/4] ๐Ÿ”  Resolving packages...
[2/4] ๐Ÿšš  Fetching packages...
[3/4] ๐Ÿ”—  Linking dependencies...
[4/4] ๐Ÿ“ƒ  Building fresh packages...
โœจ  Done in 0.12s.

~/Projects/issues_yarn-install (master *) ๐Ÿ’   tree node_modules/
node_modules/
โ”œโ”€โ”€ controls
โ”‚ย ย  โ”œโ”€โ”€ index.js
โ”‚ย ย  โ””โ”€โ”€ package.json
โ”œโ”€โ”€ network
โ”‚ย ย  โ”œโ”€โ”€ index.js
โ”‚ย ย  โ””โ”€โ”€ package.json
โ””โ”€โ”€ utils
    โ”œโ”€โ”€ index.js
    โ””โ”€โ”€ package.json

3 directories, 6 files

Thank you. I got used to omitting type for local paths with npm.

After much tracing through the code, I finally found the code that handles this. Incase anyone comes back to this issue later looking for answers or later decides this is a bug:

This code:
https://github.com/yarnpkg/yarn/blob/master/src/util/normalize-manifest/resolve-relative.js#L32-L38
only fixes relative paths is they start with file: or link:

So if someone later wanted to handle "bare" relative paths, they could change that here.

Just be aware that by npm rules, a dependency like foo/bar is _not_ a relative path. It is a github link to user foo repository bar so you can't just see if something looks like a path. You would most likely want to check for a leading ./ or ../

Was this page helpful?
0 / 5 - 0 ratings