Detect Wrong Package Manager
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
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
packageManagerproperty in package.json is used bycorepack, 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)
Took me a little while... but I'm here with answers. Before let's collect the hypothesis and assumptions:
- @gossi assumed, after
npm i -gthere is apackage-lock.jsonfile is present, turbo detects npm as the package manager. As a next step turbo tries to use npm to search for workspaces - @mehulkar had the hypothesis, that
npm i -gdoesn't create apackage-lock.jsonfile
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?
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.
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.
Can you check packageManager property in your package.json file?
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.
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.