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

Usage in a monorepo #58

Open
alecmev opened this issue Aug 20, 2022 · 0 comments
Open

Usage in a monorepo #58

alecmev opened this issue Aug 20, 2022 · 0 comments

Comments

@alecmev
Copy link

alecmev commented Aug 20, 2022

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:

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?

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

No branches or pull requests

1 participant