yarn icon indicating copy to clipboard operation
yarn copied to clipboard

Yarn workspace fails to add local package as dependency

Open kohlikohl opened this issue 6 years ago • 21 comments

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)

kohlikohl avatar Nov 08 '17 02:11 kohlikohl

This seems similar to #3973.

jonaskello avatar Dec 22 '17 20:12 jonaskello

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...

nemoDreamer avatar Jan 10 '18 17:01 nemoDreamer

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.

onehorsetown avatar May 04 '18 13:05 onehorsetown

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 🙂

arcanis avatar May 04 '18 15:05 arcanis

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.

supukarmin avatar Jun 04 '18 09:06 supukarmin

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/*"
  ]
}

leoselig avatar Aug 25 '18 13:08 leoselig

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?

TidyIQ avatar Sep 23 '19 00:09 TidyIQ

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

RobMayer avatar Oct 25 '19 15:10 RobMayer

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.

jtimmons avatar Apr 20 '20 17:04 jtimmons

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

GilbertSun avatar Jun 19 '20 07:06 GilbertSun

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

m4rvr avatar Sep 15 '20 13:09 m4rvr

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...

jgod avatar Sep 19 '21 15:09 jgod

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/*"
  ],

bengotow avatar Jun 21 '22 03:06 bengotow

@bengotow exactly the same thing was posted by @leoselig 4 years ago https://github.com/yarnpkg/yarn/issues/4878#issuecomment-415969535

Igloczek avatar Nov 01 '22 10:11 Igloczek

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

did the trick for me.

Tobjoern avatar Jun 09 '23 11:06 Tobjoern

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

did the trick for me.

Somehow this worked, thanks.

diogomartino avatar Jun 17 '23 16:06 diogomartino

@Tobjoern worked for me as well. Thanks!

AaronMBMorse avatar Jul 12 '23 19:07 AaronMBMorse

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

chenbrian avatar Jul 13 '23 06:07 chenbrian

🤦 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😅

foges avatar Sep 30 '23 13:09 foges

@chenbrian worked for me. Thanks

shyrynaz avatar Oct 20 '23 12:10 shyrynaz