turbo icon indicating copy to clipboard operation
turbo copied to clipboard

Detect Wrong Package Manager

Open gossi opened this issue 3 years ago • 6 comments

What version of Turborepo are you using?

1.3.1

What package manager are you using / does the bug impact?

pnpm

What operating system are you using?

Mac

Describe the Bug

I tried to use turbo with pnpm on cloudflare pages (but basically any server operating similar to cloudflare here).

By default, only npm is available to couldflare and the first thing you do with that is to install pnpm. My full build command is this:

npm install -g pnpm && pnpm i && pnpm build

so, the npm install -g pnpm will actually create a package-lock.json file. Well, that's the assumptive part here, because I don't see the file system here, but this explains the whole behavior here.

Because now, a package-lock.json file is present, turbo detects npm as the package manager. As a next step turbo tries to use npm to search for workspaces... which result in the error:

ERROR  workspace configuration error: package.json: no workspaces found. Turborepo requires npm workspaces to be defined in the root package.json

which is kinda "correct", because I use pnpm and its workspaces. I added a packageManager in my root package.json which then hints turbo to detect the correct package manager.

It took me a couple of hours and reading turbo source code (and go for the first time). So I think it depends on the order in which package managers are detected:

https://github.com/vercel/turborepo/blob/2b1a15d55ad5ddd518a2e7f792d7291a469410a5/cli/internal/packagemanager/packagemanager.go#L52-L57

Would it make sense to push npm as a "fallback" to the end of the list (if that is free off side-effects)?

Expected Behavior

Properly detects pnpm based on pnpm-lock.yaml instead of npm (which was used to install pnpm and created a package-lock.json file).

To Reproduce

Deploy any pnpm monorepo with turbo to cloudflare pages (or similar), using the build command above

gossi avatar Aug 04 '22 22:08 gossi

so, the npm install -g pnpm will actually create a package-lock.json file. Well, that's the assumptive part here, because I don't see the file system here, but this explains the whole behavior here.

try adding ls -al into your command to see the file system? npm i -g shouldn't create a local lock file afaik!

To Reproduce

Deploy any pnpm monorepo with turbo

I'm still learning the codebase, so if you have a repo that reproduces, it would help me out dig into this!


Couple points for what it's worth,

  • this repo (vercel/turborepo) also uses pmpm, and for our CI builds, we also need to install pnpm first, and I don't think we have the same problem.
  • The packageManager property in package.json is used by corepack, which we've been experimenting with recently. It may be the right/accepted/desired way forward in the Node.js ecosystem generally (vs using the existence of a lockfiles)

mehulkar avatar Aug 10 '22 17:08 mehulkar

Took me a little while... but I'm here with answers. Before let's collect the hypothesis and assumptions:

  1. @gossi assumed, after npm i -g there is a package-lock.json file is present, turbo detects npm as the package manager. As a next step turbo tries to use npm to search for workspaces
  2. @mehulkar had the hypothesis, that npm i -g doesn't create a package-lock.json file

Well, we where both right, I'd say, here is my explanation.

Ad 2) npm i -g does create a package-lock.json file -> in the global npm folder. Ad 1) Yes there is a package-lock.json present, because npm i -g created one, here is the ls -al snippet:

23:43:18.316 | drwxr-xr-x  8 buildbot nogroup   4096 Aug 31 21:42 .git
23:43:18.316 | -rw-r--r--  1 buildbot nogroup     21 Aug 31 21:42 .gitignore
23:43:18.316 | drwxr-xr-x  3 buildbot nogroup   4096 Aug 31 21:42 .netlify
23:43:18.316 | drwxr-xr-x  7 buildbot nogroup   4096 Aug 31 21:43 node_modules
23:43:18.316 | -rw-r--r--  1 buildbot nogroup     98 Aug 31 21:42 .npmrc
23:43:18.316 | -rw-r--r--  1 buildbot nogroup    327 Aug 31 21:42 package.json
23:43:18.316 | -rw-r--r--  1 buildbot nogroup  12142 Aug 31 21:42 package-lock.json
23:43:18.316 | -rw-r--r--  1 buildbot nogroup 580271 Aug 31 21:42 pnpm-lock.yaml
23:43:18.317 | -rw-r--r--  1 buildbot nogroup     55 Aug 31 21:42 pnpm-workspace.yaml

Why are we both right? Well I assume, that global npm folder is the same as the local one on cloudflare, that's why a package-lock.json appears.

As a package-lock.json file is present, I think my initial assumptions stands as is (I sound like a referee in football now 😂).


  • this repo (vercel/turborepo) also uses pmpm, and for our CI builds, we also need to install pnpm first, and I don't think we have the same problem.

I think, the installation happens different than on cloudflare, so my guess would be if you do an ls -al, there is no package-lock.json available.


is there any other diagnosis I can do?

gossi avatar Aug 31 '22 22:08 gossi

I added a packageManager in my root package.json which then hints turbo to detect the correct package manager.

So did this solve the issue for you @gossi ? because if so, I think this behavior is intentional.

TL;DR we have a heuristic for detecting a package manager, but we also have a way for you to tell us what package manager you use so it is deterministic.

mehulkar avatar Sep 08 '22 00:09 mehulkar

we have a heuristic for detecting a package manager

... and I think, this heuristic has a problem. The detection mechanism isn't detecting the proper package manager - that's the whole point of this issue.

I added a packageManager in my root package.json which then hints turbo to detect the correct package manager.

So did this solve the issue for you @gossi ? because if so, I think this behavior is intentional.

The feeling of adding this is more like the bugfix to turbo's heuristic problem. It's a hack, a workaround - but not the solution. I should not have to add this, imho.

gossi avatar Sep 08 '22 10:09 gossi

Can you check packageManager property in your package.json file?

DmytroYeremieiev avatar Oct 05 '22 14:10 DmytroYeremieiev

In this scenario you have a pnpm-lock.yaml and a package-lock.json in the root.

No matter what we attempt to detect it will make somebody unhappy. There is no reasonable way for us to ensure that we guess correctly in this situation.

We provide a method to skip that inference by specifying packageManager and no matter what we decide to do, that will be a requirement in this scenario.

The only other thing we can do here is to attempt inference for all possible package managers, and if we match multiples throw a hard error.

nathanhammond avatar Nov 02 '22 08:11 nathanhammond

That's fine, if you cannot properly detect the expected package manager, then throw an error 👍

I was about to close, but then saw this issue is reference, so keep that open until solved.

gossi avatar Jun 10 '23 14:06 gossi