-
-
Notifications
You must be signed in to change notification settings - Fork 13
Description
I'm using this in a monorepo, where 99% of the development deps are declared in the root workspace, including ESLint and this config. If I go and run ESLint in one of the sub-workspaces (with yarn run -T eslint), I get the following:
Oops! Something went wrong! :(
eslint-config-auto could not find the following package
eslint-config-adjunct
To install the missing package, please run the following command:
npm install eslint-config-adjunct@latest --save-dev
I tried aliasing hasAnyDep to moduleNotAvailable, but that has its own fatal side effects. So I went here:
eslint-config-auto/lib/utils.js
Lines 12 to 15 in 0eae8ba
| const { packageJson: pkg, path: packagePath } = readPkgUp.sync({ | |
| // eslint-disable-next-line security/detect-non-literal-fs-filename | |
| cwd: fs.realpathSync(process.cwd()), | |
| }) |
And prepended process.cwd() with process.env.npm_package_json ?? , and everything started to work as expected. It's available in npm 7+ and Yarn 3.2.2+. Why did it help? Because -T in yarn run -T means --top-level, so it executes the ESLint binary from the root of the monorepo, and npm_package_json resolves to the package.json which "owns" that binary. I'm not sure how npm handles run commands, but I know that they do hoisting too, so I imagine the behavior should be the same.
This assumes that a project-level eslint is used, not a system-level one, and that eslint-config-auto is installed alongside eslint, not in a sub-workspace, along with every single dependency that eslint-config-auto might look for.
The above is a quick fix that will make monorepos work now, but it's not a complete solution. For example, eslint-config-auto might be installed in the root, and one of the packages might depend on react, and even with this fix it will not pick up React, because hasAnyDep will look only in the root package.json.
The real solution is to find the root of the monorepo, and then go down the tree, merging all dependencies. Note that workspaces can be nested infinitely, it's not just one level. Unfortunately, I wasn't able to find any existing package that does this correctly (they all go down only one level). But I think a good enough version could be to just do a find-up of either yarn.lock, pnpm-lock.yaml or package-lock.json. Here's how Yarn does it, and pnpm. If no lock file is found then fall back to the current behavior.
Or could use a flawed existing library (ignore the "yarn" in its name, it works for any package manager). It's easy and it covers 99.(9)% of use cases, I haven't seen a 3+ level workspace yet.
Thoughts?