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

babel/eslint plugins doesn't work in yarn workspaces w/ pnp #6514

Closed
bugzpodder opened this issue Oct 7, 2018 · 7 comments
Closed

babel/eslint plugins doesn't work in yarn workspaces w/ pnp #6514

bugzpodder opened this issue Oct 7, 2018 · 7 comments
Assignees

Comments

@bugzpodder
Copy link
Contributor

bugzpodder commented Oct 7, 2018

create a yarn workspace, one of which is:

{
  "name": "eslint",
  "version": "0.1.0",
  "private": true,
  "main": "src/index.js",
  "scripts": {
    "lint": "eslint --ext .js --ext .jsx src/"
  },
  "devDependencies": {
    "babel-eslint": "10.0.1",
    "eslint": "^5.6.1",
    "eslint-plugin-filenames": "^1.3.2"
  },
  "installConfig": {
    "pnp": true
  }
}

.eslintrc.json

{
  "plugins": ["filenames"]
}

and run yarn --pnp && yarn lint. it fails with ESLint couldn't find the plugin "eslint-plugin-filenames".

Same with babel plugins:

$ babel ./src --out-dir ./dist
{ Error: Cannot find module '@babel/preset-env' from './dev/test/lib'

package.josn

{
  "private": true,
  "name": "lib",
  "version": "0.1.0",
  "scripts": {
    "build": "babel ./src --out-dir ./dist",
    "start": "yarn build"
  },
  "dependencies": {
    "@babel/cli": "^7.1.2",
    "@babel/core": "^7.1.2",
    "@babel/node": "^7.0.0",
    "@babel/preset-env": "^7.1.0"
  },
  "main": "dist/index.js",
  "sideEffects": false,
  "installConfig": {
    "pnp": true
  }
}

and .babelrc

{
  "presets": [
    "@babel/env"
  ]
}

@arcanis

@ghost ghost assigned rally25rs Oct 7, 2018
@ghost ghost added the triaged label Oct 7, 2018
@rally25rs
Copy link
Contributor

I believe this is because eslint doesn't actually have a dependency on eslint-plugin-filenames.

It looks like it tries to dynamically resolve it at runtime: https://github.com/eslint/eslint/blob/caeb223c4f7b0b6fe35e5348ae0df4c6446b5bed/lib/config/config-file.js#L475

PnP doesn't know about this dependency at the time that it resolves them, and when falling back to node's default implementation, node can't find it either because it's not in node_modules.

I think you could resolve this by telling yarn to leave eslint-plugin-filenames in node_modules instead of using it from the cache by "unplugging" it: yarn unplug eslint-plugin-filenames

@rally25rs rally25rs removed the triaged label Oct 8, 2018
@bugzpodder
Copy link
Contributor Author

Obviously it isn't feasible for this to be done manually for each environment. Babel/eslint relies on plugins and there are many of them. I had these plugins in my workspace peer dependencies and that didn't help. Is there a way to specify a regex to specify a list of unplugging modules?

@bugzpodder
Copy link
Contributor Author

bugzpodder commented Oct 8, 2018

I tried unplugging and it didn't seem to really work btw. and I can confirm this is a workspace issue, if I have a standalone repo, pnp works fine as expected.

@arcanis
Copy link
Member

arcanis commented Oct 8, 2018

What happens is this:

  • eslint doesn't depend on eslint-plugin-filenames, as @rally25rs remarked
  • so PnP refuses to satisfy the request
  • however, to make compatibility a tad easier, we have a fallback mechanism : when a package tries to require something it doesn't own, we check to see if this required package is a dependency of the top-level. If it is, then we allow the require (we assume it's a plugin).
  • unfortunately, our current Workspaces implementation doesn't play well this mechanism because contrary to what you might expect the top-level isn't each workspace: it's instead the one and only common root (the location where you have your yarn.lock, if that makes it clearer)
  • since your top-level doesn't list eslint-plugin-filenames, PnP throws, and eslint reports it as the plugin not being found. Tl;dr: Add eslint-plugin-filenames to your top-level package.json and it should work.

There's a few points here:

  • Maybe Yarn could consider each workspace as being independent wrt the fallback. It will be very difficult to implement, and has huge implication in term of the resolution (since all the dependency from each workspace would have to be separated from one another, requiring us to create a bunch of virtual packages - ie symlinks).
  • The real fix would be for you to use require.resolve when passing the plugin to ESLint. So instead of plugins: ["filename"], you'd have plugins: [require.resolve('eslint-plugin-filename')]. By doing this, you'd get a preresolved path, so ESLint should be happy. Unfortunately, ESLint doesn't actually support absolute plugin paths, and will crash ... Proposal for loading plugins relative to the configs that depend on them eslint/eslint#10643
  • However, Babel does support absolute plugins paths, so you can just use this trick in your .babelrc.js and it will work.

@PaulRBerg
Copy link

I had a similar issue with react-scripts@3.0.1 while being used inside a package from a yarn workspaces monorepo. Inside the react app package, I had this .eslintrc:

{
  "extends": ["react-app"]
}

And I was getting this error:

Oops! Something went wrong! :(

ESLint: 6.1.0.

ESLint couldn't find the config "react-app" to extend from. Please check that the name of the config is correct.

The config "react-app" was referenced from the config file in "/Users/paulrberg/Projects/Sablier/Sablier/packages/frontend/.eslintrc".

If you still have problems, please stop by https://gitter.im/eslint/eslint to chat with the team.

Upgrading to react-scripts@3.1.0 and running yarn install again fixed the issue for me!

@bugzpodder
Copy link
Contributor Author

@PaulRBerg did you get yarn pnp to work with yarn workspaces and create-react-app? Did you have to use config modifiers like craco or rewired?

@PaulRBerg
Copy link

PaulRBerg commented Aug 15, 2019

@bugzpodder I didn't use pnp or configs like craco/ rewired. Just basic workspaces + create-react-app.

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

4 participants