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
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
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?
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.
What happens is this:
eslint doesn't depend on eslint-plugin-filenames, as @rally25rs remarkedeslint-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:
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 ... https://github.com/eslint/eslint/issues/10643.babelrc.js and it will work.I had a similar issue with [email protected] 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 [email protected] and running yarn install again fixed the issue for me!
@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?
@bugzpodder I didn't use pnp or configs like craco/ rewired. Just basic workspaces + create-react-app.
Most helpful comment
What happens is this:
eslintdoesn't depend oneslint-plugin-filenames, as @rally25rs remarkedeslint-plugin-filenames, PnP throws, and eslint reports it as the plugin not being found. Tl;dr: Addeslint-plugin-filenamesto your top-level package.json and it should work.There's a few points here:
require.resolvewhen passing the plugin to ESLint. So instead ofplugins: ["filename"], you'd haveplugins: [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 ... https://github.com/eslint/eslint/issues/10643.babelrc.jsand it will work.