vercel
vercel copied to clipboard
[email protected] broke preBuilds in monorepo
Recreated #11097 as requested by @TooTallNate,
We are using the preBuild option in our monorepo but after updating to [email protected] it no longer works, when trying to do the deploy we get the following error:
[debug] [2024-01-26T09:52:00.561Z] Error: Error: ENOENT: no such file or directory, lstat '/home/runner/work/<org>/<project>/dist/apps/<app-name>/node_modules/styled-jsx/index.js'
Error: ENOENT: no such file or directory, lstat '/home/runner/work/<org>/<project>/dist/apps/<app-name>/node_modules/styled-jsx/index.js'
When comparing it with the previous version it looks like the functions don't have the node_modules anymore. How can we solve this?
Steps:
npx vercel pull --yes --environment=production --debugnpx vercel build --output dist/<project dist>/.vercel/output --prod --debugnpx vercel deploy --prebuilt --prod --regions=fra1 --debug, this one is run inside thedist/<project dist>3.anpx vercel deploy <path> --prebuilt --prod --regions=fra1 --debug, ran in the root creates the same result.
In your case, the problem is that there is currently no counterpart in vercel deploy to correlate with the --output option in vercel build (it was never really intended for public use - it is used internally when doing a build on Vercel infra).
Is there a particular reason you are using that --output option? We certainly can add the missing counterpart (probably would be something like vercel deploy --prebuilt --prebuilt-dir "dist/<project dist>/.vercel/output" in your case, invoked from the root of the repo), but I want to understand your use case first.
Absent that, I would expect the proper usage for you to look something like (all commands invoked from the root of the repo):
npx vercel pull --yes --environment=production --debugnpx vercel build --prod --debugnpx vercel deploy --prebuilt --prod --regions fra1 --debug
Our use case is: we have multiple sites in our mono repo (10+ sites) that we build in our own CI and then want to deploy as prebuilt to Vercel.
So after we pull we also update the generated files with the needed ENV variables, we generate the project.json with the needed configuration for that project so that the npx vercel build can generate the correct project. After that we run deploy inside that directory (or provide the path to it) and deploy the code
I linked the code of the Nx plugin that is being used to run this, currently we have hardcoded the version so the build is still being made the way it was.
Absent that, I would expect the proper usage for you to look something like (all commands invoked from the root of the repo):
npx vercel pull --yes --environment=production --debugnpx vercel build --prod --debugnpx vercel deploy --prebuilt --prod --regions fra1 --debug
It would be great if we can add something like the --prebuilt-dir to step 3 so the node_modules can be found correctly again.
I see from the script that you linked that you are not setting the rootDirectory property. This is almost certainly going to be incorrect in a monorepo setup. Each project should have that setting pointing to the subdirectory within the monorepo where the particular project is located.
Aside from that, it sounds like your setup would work, but since there can only be one .vercel/project.json file defined at a time, you need to do all three steps in a row, per project. If you try to build all projects first before deploying then the .vercel/output directories would be overwritten (you probably already know this, which is why you're trying to use --output). Maybe a simple change in order of operations would solve this for you.
However, there is yet another option which sounds like it would be more appropriate for you, which is vc link --repo. This command produces a .vercel/repo.json file (you could also craft this file manually) which is an alternative linking style that allows you to be linked to multiple projects simultaneously. When this linking style is active, you actually do run the relevant Vercel CLI commands from within the project subdirectories and the build outputs can coexist simultaneously because they are stored in <project subdirectory>/.vercel/output instead of at the root level.
I'd be happy to jump on a call to sort this all out with you btw. It would need to be next week after the US Holiday break however.
I see from the script that you linked that you are not setting the rootDirectory property. This is almost certainly going to be incorrect in a monorepo setup. Each project should have that setting pointing to the subdirectory within the monorepo where the particular project is located.
I cannot seem to find any information about that option? (looking in the --help of the commands)
Aside from that, it sounds like your setup would work, but since there can only be one .vercel/project.json file defined at a time, you need to do all three steps in a row, per project. If you try to build all projects first before deploying then the .vercel/output directories would be overwritten (you probably already know this, which is why you're trying to use --output). Maybe a simple change in order of operations would solve this for you.
This is indeed know, when we release the sites we do not run it in parallel but instead scale the amount of jobs, each job then deploys one site.
However, there is yet another option which sounds like it would be more appropriate for you, which is vc link --repo. This command produces a .vercel/repo.json file (you could also craft this file manually) which is an alternative linking style that allows you to be linked to multiple projects simultaneously. When this linking style is active, you actually do run the relevant Vercel CLI commands from within the project subdirectories and the build outputs can coexist simultaneously because they are stored in
/.vercel/output instead of at the root level. I'd be happy to jump on a call to sort this all out with you btw. It would need to be next week after the US Holiday break however.
I'm going to give this a try. I'll let you know if I need any additional help.
I cannot seem to find any information about that option? (looking in the
--helpof the commands)
You can set this in the Project Settings page on the vercel.com dashboard (it can also be configured when a new project is being created using the CLI, but that's probably not relevant to you at this point since the projects already exist. there's currently no way to modify that project setting in the CLI for an existing project).
I'm seeing the same issue.
If I set the rootDirectory of the project and try to build from the monorepo root - cli can't find the project settings (.vercel) that I previously linked because it searches in the root folder of the monorepo, not in the rootDirectory of the project.
If I pass --cwd foo/bar with rootDirectory set to foo/bar, it tries to cd into foo/bar/foo/bar and fails.
If I delete rootDirectory and try to run vercel build from the root directory of the repo with the cwd provided - it succeeds.
However, vercel deploy in the same context fails with:
ENOENT: no such file or directory, lstat '/node_modules/styled-jsx/index.js'
Setting rootDirectory when I opted-out of the repo connection doesn't make sense. There's no point in vercel knowing my repo structure when the repo is not connected. In the context of this use-case, I should be able to link the app from the folder of choice, build it, and deploy artifacts from this directory.
❯ vercel link --yes --cwd clients/web/apps/platform --project web-platform --token $PSC_VERCEL_TOKEN # ✅ ok
❯ vercel pull --yes --cwd clients/web/apps/platform --environment production --token $PSC_VERCEL_TOKEN # ✅ ok
❯ vercel build --prod --cwd clients/web/apps/platform # ✅ ok
❯ vercel deploy --prebuilt --prod --cwd clients/web/apps/platform --token $PSC_VERCEL_TOKEN # ❌ error
Error: ENOENT: no such file or directory, lstat '/node_modules/styled-jsx/index.js'
❯ vercel -v
Vercel CLI 39.2.4
39.2.4
I was able to deploy by setting rootDirectory in the settings → linking/pulling app #1 in the root directory of the monorepo → building/deploying it → removing .vercel -> linking/pulling app #2 → ...
But this use-case feels totally broken.
I encountered the same issue both locally and in GitHub Actions.
The only workaround that worked for me was downgrading, but that's not an ideal solution.
I might be doing something wrong, but I couldn't get it to work with vercel@latest.
I'm running the Vercel CLI commands inside the project repo ([root]/apps/web).
My monorepo is currently a Turbo starter setup with just a base "Hello World" Next.js app.
Reference: Commit
Edit: My issue was that I was running the commands from the wrong location 😅
For me the following worked:
- Set
rootDirectory: apps/webin Vercel project settings (dashboard) - Run ALL commands from monorepo root (not from
apps/web):
# All commands run from monorepo root
vercel pull --yes --environment=production --token=xyz
vercel build --prod --token=xyz
vercel deploy --prebuilt --prod --token=xyz
@bennobuilder your solution is the only that worked, but also make sure to selet "Next.js" in the framework preset field.
@bennobuilder going to try this solution - I don't understand the point of having cwd as an option if you have to run everything from root in order for things to work