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

public-hoist-pattern does not apply to workspace packages #3642

Open
buschtoens opened this issue Aug 3, 2021 · 9 comments
Open

public-hoist-pattern does not apply to workspace packages #3642

buschtoens opened this issue Aug 3, 2021 · 9 comments

Comments

@buschtoens
Copy link

buschtoens commented Aug 3, 2021

pnpm version: 6.11.5

Code to reproduce the issue:

https://github.com/buschtoens/repro-pnpm-workspace-public-hoist-pattern

Expected behavior:

When packages in the the workspace match public-hoist-pattern, they should be hoisted to the root node_modules directory, just like matching external dependencies.

Actual behavior:

Packages in the workspace that match the public-hoist-pattern are completely unaffected and not hoisted to the root node_modules directory, nor hoisted anywhere else.

Only when they are listed in the root package.json, they are "hoisted".

This breaks workspace-internal eslint configs and the like.

Additional information:

  • node -v prints: v14.17.4
  • Windows, macOS, or Linux?: macOS Big Sur 11.04
@zkochan
Copy link
Member

zkochan commented Aug 3, 2021

Hoisting is a feature that was added to fix external dependencies that you don't have control over. There is no legitimate use of it. It is just a workaround for buggy deps. In your case, you should solve your issue properly. You can add dependencies as devDependencies to projects that use them.

@buschtoens
Copy link
Author

Sorry, I just noticed, that my demo isn't actually demonstrating the issue I'm having.

Hoisting is a feature that was added to fix external dependencies that you don't have control over. There is no legitimate use of it. It is just a workaround for buggy deps.

"Technically" I'm already doing everything right (in my "real" project). The issue is eslint's notorious resolution algorithm. What I actually wanted to demonstrate is the resolution of plugins, not configs.

While you can use require.resolve(someConfigDependency) with extends to force eslint to lookup the right dependency, it's not possible for plugins.

plugins only accept package names withou a path prefix and eslint resolves them relative to the CWD IIRC.

So if you host your own eslint-plugin in the monorepo, it cannot be used, unless it's forcefully hoisted by adding it to the root package.json deps. I'll update the reproduction in a bit, when I have soem time.

But here's an issue already, that discusses this problem: eslint/eslint#3458

@zheeeng
Copy link

zheeeng commented Oct 21, 2021

Hoisting is a feature that was added to fix external dependencies that you don't have control over. There is no legitimate use of it. It is just a workaround for buggy deps. In your case, you should solve your issue properly. You can add dependencies as devDependencies to projects that use them.

In vite project, vite.config.ts can't handle importing from symlink. I want to try hoisting workspace but it takes no effects and blocks the testing. see the related issue: vitejs/vite#4180

@zkochan
Copy link
Member

zkochan commented Oct 21, 2021

You can simply put relative dependencies to the root package.json. So for instance, you can add this to the root package.json of the monorepo:

{
  "devDependencies": {
    "eslint-plugin-foo": "link:packages/eslint-plugin-foo"
  }
}

@zheeeng
Copy link

zheeeng commented Oct 22, 2021

Hoisting is a feature that was added to fix external dependencies that you don't have control over. There is no legitimate use of it. It is just a workaround for buggy deps. In your case, you should solve your issue properly. You can add dependencies as devDependencies to projects that use them.

In vite project, vite.config.ts can't handle importing from symlink. I want to try hoisting workspace but it takes no effects and blocks the testing. see the related issue: vitejs/vite#4180

I made an incorrect digging and it turn out that the issue of vite side is not related to symlink. Sorry for providing useless information.

sarayourfriend added a commit to WordPress/gutenberg that referenced this issue Feb 12, 2022
@DmitryMasley
Copy link

Currently, I see that eslint plugins are hoisted in the root of monorepo. But if different packages have different versions of the eslint plugins, eslint will be able to resolve the plugin hoisted in root regardless of the version in the corresponding package. We need a way to tell pnpm to hoist some dependencies on package level, not root of monorepo.

@forty
Copy link

forty commented May 25, 2022

I was having this issue and created this simple repo to reproduce it https://github.com/forty/pnpm-issue-public-hoist-workspace-packages/tree/master/packages

My problem is, as probably with many of you, with locally defined eslint plugins. With external plugins, everything works automagically (thanks to the default public hoisting of *eslint* packages), but for local ones, it's more annoying as I also have to add the import(s) at the root.

@zkochan PNPM itself is using this nice behavior, putting the eslint plugin dependencies in their eslint config package https://github.com/pnpm/pnpm/blob/main/utils/eslint-config/package.json#L31 rather than at the root, and having it work just thanks to the automated public hoisting of those plugins. You don't feel the pain because you don't have custom plugins defined locally, but it's not pretty, you then have to add the plugin at the root, then all the peer dependencies, when having it all hidden in the eslint-config package is much nicer.

@DmitryMasley
Copy link

I was having this issue and created this simple repo to reproduce it https://github.com/forty/pnpm-issue-public-hoist-workspace-packages/tree/master/packages

My problem is, as probably with many of you, with locally defined eslint plugins. With external plugins, everything works automagically (thanks to the default public hoisting of eslint packages), but for local ones, it's more annoying as I also have to add the import(s) at the root.

@zkochan PNPM itself is using this nice behavior, putting the eslint plugin dependencies in their eslint config package https://github.com/pnpm/pnpm/blob/main/utils/eslint-config/package.json#L31 rather than at the root, and having it work just thanks to the automated public hoisting of those plugins. You don't feel the pain because you don't have custom plugins defined locally, but it's not pretty, you then have to add the plugin at the root, then all the peer dependencies, when having it all hidden in the eslint-config package is much nicer.

Everything works fine when all the packages have the same eslint plugin versions. But when each package has own version you need to hoist per package, which seems is not possible right now.

@phawxby
Copy link

phawxby commented Nov 14, 2023

It took far longer than I wish to admit to figure out what was going on then figure out this was the cause of the problem.

Same thing. Monorepo with a config and locally hosted eslint plugins. All the other external plugins were hoisted as expected, the local workspace:* plugins were not. Config package.json correctly defined its dependencies.

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

No branches or pull requests

6 participants