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

Yarn workspace fails to add local package as dependency #4878

Open
kohlikohl opened this issue Nov 8, 2017 · 21 comments · May be fixed by #6012
Open

Yarn workspace fails to add local package as dependency #4878

kohlikohl opened this issue Nov 8, 2017 · 21 comments · May be fixed by #6012
Assignees
Labels

Comments

@kohlikohl
Copy link

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

Bug. (could be expected behavior)

What is the current behavior?
When trying to install a local package using yarn workspace <workspace-name> add <package-name> adding the package fails. It however succeeds when specifying the exact version of the local package.

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

Example repo: https://github.com/kohlikohl/yarn-workspace-install-local-package

Failure case

$ yarn workspace @scope/a add @scope/b
yarn workspace v1.3.2
yarn add v1.3.2
[1/4] Resolving packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/@scope%2fb: Not found".
info If you think this is a bug, please open a bug report with the information provided in "C:\\dev\\playground\\yarn-workspace-add-package\\packages\\a\\yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
error Command failed.
Exit code: 1
Command: C:\Program Files\nodejs\node.exe
Arguments: C:\Users\maknoll\AppData\Roaming\nvm\v8.6.0\node_modules\yarn\lib\cli.js add @scope/b
Directory: C:\dev\playground\yarn-workspace-add-package\packages\a
Output:

info Visit https://yarnpkg.com/en/docs/cli/workspace for documentation about this command.

✔️ Working case (version of package is specified)

$ yarn workspace @scope/a add @scope/[email protected]
yarn workspace v1.3.2
yarn add v1.3.2
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 2 new dependencies.
├─ @scope/[email protected]
└─ @scope/[email protected]
Done in 0.17s.
Done in 0.69s.

What is the expected behavior?
When running yarn workspace @scope/a add @scope/b and not specifying a version, I would expect yarn to resolve @scope/b to the locally available version and add it as dependency to @scope/a's package.json.

I can, however, see that installing the package from the registry by default is a nice functionality. In which case it might be good to add a flag that forces a local install. yarn workspace @scope/a add @scope/b --local 🤔

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

Node version:
8.6.0

Platform:
win32 x64 (windows 10)

@ghost ghost assigned arcanis Nov 8, 2017
@ghost ghost added the triaged label Nov 8, 2017
@jonaskello
Copy link

jonaskello commented Dec 22, 2017

This seems similar to #3973.

@nemoDreamer
Copy link

The workspace docs mention that cd'ing into a packages' folder and running yarn add [-D] whatever should add that dependency to the package's package.json [dev]Dependencies, but no file change occurs...

@onehorsetown
Copy link

Still an issue in yarn 1.6.0 (MacOS).

Does not work (tries to find local workspace package in NPM):

yarn workspace x add y

[1/4] 🔍 Resolving packages...
error Couldn't find package "y" on the "npm" registry.

If you specify the version, it works just like you'd expect:

yarn workspace x add y@^1.0.0

Neither local @ scoped or unscoped packages work for me without a corresponding version.

@arcanis
Copy link
Member

arcanis commented May 4, 2018

As @kohlikohl noted, Yarn always tries to resolve from the registry when the version is missing (it tries to find the latest one and use it). If someone is willing to open a PR to first check whether there's a workspace of the specified name it would be appreciated 🙂

@supukarmin
Copy link

Had the same problem with npm + lerna + docker. I ended up writing a small script which checks for package.json's in the upper directories and copies the deps+right versions into package.json. Just run it inside your Dockerfile (or whatever you try to deploy).

First specify the needed packages inside your package.json: (the version is being ignored).

	"dependencies": {
		"micro": "^9.3.2",
		"mkdirp": "^0.5.1",
		"money": "^0.2.0",
		"open-exchange-rates": "^0.3.0",
		"winston": "3.0.0-rc5"
	},
	"workspaceDependencies": {
		"moment": "*",
		"dotenv": "*"
	}

This makes it also easy to keep track of used packages inside your project, which makes maintenance much easier. And the script:

const path = require('path');
const fs = require('fs');

const getTargetPackage = ({ targetPackagePath }) => {
  if (!fs.existsSync(targetPackagePath)) {
    return false;
  }
  const targetPackage = JSON.parse(fs.readFileSync(targetPackagePath, 'utf8'));
  if (typeof targetPackage.workspaceDependencies !== 'object') {
    return false;
  }
  if (typeof targetPackage.dependencies !== 'object') {
    targetPackage.dependencies = {};
  }
  return targetPackage;
};

const checkUpperPackageJson = ({ dir, targetPackage, neededWsDeps }) => {
  const pkgPath = path.join(dir, 'package.json');
  if (fs.existsSync(pkgPath)) {
    const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
    if (pkg.dependencies) {
      for (const [name, version] of Object.entries(neededWsDeps)) {
        if (pkg.dependencies[name]) {
          targetPackage.dependencies[name] = pkg.dependencies[name];
          delete neededWsDeps[name];
        }
      }
    }
  }
};

const copyWorkspaceDepsIntoDeps = () => {
  let dir = path.join(process.cwd());
  const targetPackagePath = path.join(dir, 'package.json');
  const targetPackage = getTargetPackage({ targetPackagePath });
  if (targetPackage) {
    const neededWsDeps = { ...targetPackage.workspaceDependencies };
    do {
      checkUpperPackageJson({ dir, targetPackage, neededWsDeps });
      dir = path.resolve(dir, '..');
    } while (dir !== '/' && Object.keys(neededWsDeps).length);
    fs.writeFileSync(targetPackagePath, JSON.stringify(targetPackage, null, "\t"), 'utf8');
    console.log(
      `Copying .workspaceDependencies finished. Not copied: ${Object.keys(neededWsDeps).length}.`,
      neededWsDeps
    );
  }
};

copyWorkspaceDepsIntoDeps();

Results into:

	"dependencies": {
		"micro": "^9.3.2",
		"mkdirp": "^0.5.1",
		"money": "^0.2.0",
		"open-exchange-rates": "^0.3.0",
		"winston": "3.0.0-rc5",
		"moment": "^2.22.2",
		"dotenv": "^6.0.0"
	},
	"workspaceDependencies": {
		"moment": "*",
		"dotenv": "*"
	}

However this should be somehow supported by default. (workspaceDependencies + yarn command for copying lock/versions) Has there ever been some feature requests regarding the change of the "dependencies syntax"? It would be great if we could change it to something like this:

"dependencies": {
  "micro": {
    "dev": false, //default: false
    "optional": false, //default: false
    "peer": false, //default: false
    "version": "^9.3.2", //can be omitted
  },
  "mkdirp": {
    "dev": true,
    "optional": false,
    "workspace": true, //default: false
  },
  "money": "^0.2.0"
},

The current syntax doesn't reflect the existing complexity, like optional dev dependencies, or the fact that peer deps are often also dev deps, etc.

rally25rs added a commit to rally25rs/yarn that referenced this issue Jun 20, 2018
…pace packages

Previously for a requested dependency pattern to match a package in a workspace, it's name had to
match and so did the semver range. If a request specified a non-semver range (like a github url)
then it would not match, causing the resolver to attempt to resolve the package on the registry
instead of use the workspace package. This change will match a workspace package just on it's name
if no valid semver range was found on the requested pattern.

fixes yarnpkg#4878
fixes yarnpkg#3973
affects yarnpkg#5726
@leoselig
Copy link

leoselig commented Aug 25, 2018

I had a similar (same?) issue where the registry was contacted although I was expecting yarn to link locally. In my case, the issue was a leading ./ in the top-level workspaces-field.

I.e.:
Wrong:

{
  "workspaces": [
    "./packages/*"
  ]
}

Right:

{
  "workspaces": [
    "packages/*"
  ]
}

@TidyIQ
Copy link

TidyIQ commented Sep 23, 2019

I have the same issue. Everything was working fine then I took a holiday, came back and tried to run yarn outdated to see what packages need updating. I get an error message saying:

Outdated lockfile. Please run `yarn install` and try again.

Then when I run yarn install, I get the error:

Error: Couldn't find package "@scope/package*" required by "@scope/anotherPackage" on the "npm" registry.

@scope/package and @scope/anotherPackage are both workspaces, so they shouldn't be trying to find them on the npm registry.

The only real change I made to my computer between the time it was working and now was that I installed Firefox but I don't see how that would affect this issue.

Any advice?

@RobMayer
Copy link

RobMayer commented Oct 25, 2019

same issue here.
in @scoped/somelib

somelib/ > yarn link
success use yarn link "@scoped/somelib"
someproject/ > yarn link "@scoped/somelib"
success using linked package
someproject/ > yarn install
can't find "@scoped/somelib" on npm

@jtimmons
Copy link

I hit a similar issue to @leoselig with their comment above while using yarn 1.22.4. My issue was with a trailing slash that was causing yarn to reach out to the registry to find a local package during install time.

Changing:

{
  "workspaces": {
    "packages": ["packages/*/"]
  }
}

to:

{
  "workspaces": {
    "packages": ["packages/*"]
  }
}

fixed the issue for me.

@GilbertSun
Copy link

you can always use a unpublish @scope/b version. only the version is in the local package.json

@m4rvr
Copy link

m4rvr commented Sep 15, 2020

Is there a workaround yet for the issue that it can't find local packages with latest?

@jgod
Copy link

jgod commented Sep 19, 2021

Is there a workaround yet for the issue that it can't find local packages with latest?

Yeah, I was migrating a project to use yarn workspaces and figured I could use latest to refer to these internal-packages and I guess not...

@bengotow
Copy link

Struggled with this one for half an hour and it turns out the workspaces glob in your root package.json file must not start with a ./.

Bad:

  "workspaces": [
    "./packages/*"
  ],

Works:

  "workspaces": [
    "packages/*"
  ],

@Igloczek
Copy link

Igloczek commented Nov 1, 2022

@bengotow exactly the same thing was posted by @leoselig 4 years ago #4878 (comment)

@Tobjoern
Copy link

Tobjoern commented Jun 9, 2023

I migrated from pnpm to yarn, and switching from
"@acme/api": "workspace:^",
to
"@acme/api": "*",

did the trick for me.

@diogomartino
Copy link

I migrated from pnpm to yarn, and switching from "@acme/api": "workspace:^", to "@acme/api": "*",

did the trick for me.

Somehow this worked, thanks.

@AaronMBMorse
Copy link

@Tobjoern worked for me as well. Thanks!

@chenbrian
Copy link

yarn workspace @scope/a add @scope/b --peer worked for me

@foges
Copy link

foges commented Sep 30, 2023

🤦 I spent 6 hours on a Saturday trying to get this to work and all that was needed was to add @1.0.0 to the end of yarn workspace x add y -- Would definitely be great to fix this since I'm sure some ridiculous amount of dev-hours have been spent on this😅

@shyrynaz
Copy link

@chenbrian worked for me. Thanks

@heywon0909
Copy link

why... 😂 It didn't worked for me....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.