nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
22.72k stars 2.27k forks source link

Next js: Easily deploy to Zeit vercel #3051

Closed asherccohen closed 3 years ago

asherccohen commented 4 years ago

Expected Behavior

Deploy to Zeit Vercel with a simple command.

Current Behavior

Current 'build' structure works for platforms like Heroku but not on Zeit Vercel, as we can't push the .next folder. Like this we miss all the cool features this hosting platform gives like static hosting to CDN!

Failure Information (for bugs)

Zeit Vercel is very strict on how to deploy a next js project since it needs to accomodate for many factors (paths/api routes/deps/env variables etcs), therefore prefers building on their hosting provider. It also ignores .next folders (there's a trick to push this by using a .vercelignore file, but doesn't help anyway)

The current implementation of next js plugin for nx dev is great, it can easily create a .next folder and copy assets to dist/myApp, it also generates a basic package.json (to which we have to manually add deps).

This structure is ready for platforms like Heroku, where we can push over the .next folder (build artifacts which include shared libs and typescript related compilation), have heroku install node_modules then run the project.

The only solution I have found is to avoid building altogether. What I do:

Steps to Reproduce

Please provide detailed steps for reproducing the issue.

  1. generate a next app
  2. add some dependencies (like date-fns or some other library) and use it in the app.
  3. import and use a shared lib
  4. nx build myNextJSApp
  5. Try to deploy to Zeit Vercel (REMEMBER that .next folder will not be pushed to Vercel)
rarmatei commented 4 years ago

Thank you for submitting this!

So just to summarise the problem here:

Ideally:

This is also why deploying to platforms like Heroku works great - because they allow you to next build locally, and then next start on their platform.

Getting around this problem would involve creating a "simplified monorepo", which contains just the libs and dependencies in package.json that your next.js app needs, and putting that into dist so it can be sent to Vercel. This is a complex process, a bit counter-intuitive (in the sense that we're putting source files in dist, where you'd expect a deployable artifact), and will only exist to work around a limitation of the Vercel platform.

Vercel knows about this, so I'd say to wait on them for a bit. As monorepos become more and more popular this will be a more and more requested feature.

asherccohen commented 4 years ago

Great stuff and well explained. Let's keep this for reference...it might help people stuck on this case.

benediktvaldez commented 4 years ago

As far as I can tell there are no plans of supporting pre-built next.js apps, this comment is 8 days old in response to another nx user trying to do this.

At the moment, we don't plan to support "pre-built" Next.js apps since we do need to control the generated output and underlying routing. So no, it is not possible, and we don't envision a future where this would be implemented. source

Couldn't this be resolved by a vercel specific deploy script within @nrwl/next? These two are so tightly coupled due to being developed by the same company. I agree it sounds a little weird copying source files to the dist folder, but it could be done similarly to storybook, creating something like dist/vercel/appname. My reasoning is mostly that this is what I (and others that want to deploy next apps to vercel) will end up having to do this anyway, unless there's a better way to achieve this right now?

rarmatei commented 4 years ago

As far as I can tell there are no plans of supporting pre-built next.js apps, this comment is 8 days old in response to another nx user trying to do this.

At the moment, we don't plan to support "pre-built" Next.js apps since we do need to control the generated output and underlying routing. So no, it is not possible, and we don't envision a future where this would be implemented. source

Couldn't this be resolved by a vercel specific deploy script within @nrwl/next? These two are so tightly coupled due to being developed by the same company. I agree it sounds a little weird copying source files to the dist folder, but it could be done similarly to storybook, creating something like dist/vercel/appname. My reasoning is mostly that this is what I (and others that want to deploy next apps to vercel) will end up having to do this anyway, unless there's a better way to achieve this right now?

I agree, if this becomes the only option, it will definitely be something we'll look at. Vercel are working on monorepo support though, and they'll launch something soon hopefully (based on the comment you linked to as well), so let's wait and see how that will work, as it might help with this story.

benediktvaldez commented 4 years ago

I agree, if this becomes the only option, it will definitely be something we'll look at. Vercel are working on monorepo support though, and they'll launch something soon hopefully (based on the comment you linked to as well), so let's wait and see how that will work, as it might help with this story.

That's fair enough. My understanding was that their monorepo support was mainly about being able to support multiple apps being deployed to the same app, or connecting multiple apps to the same repo. That said, they probably have some plans to have some support for configuring the repo.

I guess we'll wait and see 😊

asherccohen commented 4 years ago

Correct, they're concept of monorepo is what they call multizones:

https://nextjs.org/docs/advanced-features/multi-zones

I'm still not totally sold to the concept, I'm trying to understand how this would impact things like SEO.

Nevertheless I don't see how this feature would be helping with our problem, if anything making it even harder.

Let's give it some time and come back to it when they expose their full plan.

Thanks everyone!

flybayer commented 4 years ago

Hey y'all, I have a nx Next.js app deploying to Vercel just fine.

First a few clarifications:

Vercel will automatically configure all of those items if you have a plain Next.js repo. But with NX, you need to configure all of them yourself.

Working Setup

I have a Next.js app configured as the web app in my nx repo at apps/web/

package.json

  "scripts": {
    "build:web": "nx build web",

apps/web/next.config.js

module.exports = {
  target: 'experimental-serverless-trace',
}

.vercelignore

apps/otherapp1
apps/otherapp2
dist
tmp

Project settings in Vercel image

Multiple apps

Vercel doesn't yet support deploying multiple different apps from the same project. This is their "monorepo" support that is currently in development.

rarmatei commented 4 years ago

@flybayer This looks super interesting. Thanks for sharing your setup.

I should have never used the word "magic", I'm sorry for that - what I was referring to was how "Vercel" needs to build your next.js app, instead of letting you build it locally, because it needs to perform some extra setup. Even though you can specify what build command to run, like you said, running next build locally and only uploading the output will not have the same effect (it will not work) as letting Vercel run it for you.

Even though we can ignore other apps in .vercelignore, we do not know which libs/ to ignore - you could have 30 libs, but only 3 of them used by the app you're trying to deploy. I'd like to avoid recommending people push their whole "libs" folder on each deployment of a single app, as it's not very scalable (but you can definitely do it if it works for your repo). This problem would be easily solved if we could build locally, as the generated bundle only contains the code that app needs - nothing extra, regardless of how many libraries we have. And it's not just libs/ that introduce this complexity: in your root package.json you might have dozens of dependencies, but only a subset of them needed by your app. Building locally would again only pull what's needed by your app.

Nx currently doesn't allow you to easily copy only the source code needed by a specific app into dist, and I believe this would be the only use-case for such a feature. Which is why I was suggesting we wait to see what is announced for Vercel's monorepo support, in case it changes our outlook on this. It's not such a trivial thing to implement and brings along some complexity.

Please point out if you think I got any of the above wrong. If you have an example repo where you've managed to deploy only a specific app, the libs that it needs (and maybe only its specific package.json) dependencies, I'd be super interested to look at it, as I definitely might have missed something when I was initially testing this.

bluebeel commented 3 years ago

Hey y'all, I have a nx Next.js app deploying to Vercel just fine.

First a few clarifications:

  • Vercel does not use a custom magic build command. It uses whatever you define
  • Vercel only requires four configuration items for a Next.js deployment:

    1. Project framework set to "Next.js"
    2. The command to build your Next app
    3. The path to your .next build folder
    4. Next build target set to "serverless" or "experimental-serverless-trace"

Vercel will automatically configure all of those items if you have a plain Next.js repo. But with NX, you need to configure all of them yourself.

Working Setup

I have a Next.js app configured as the web app in my nx repo at apps/web/

package.json

  "scripts": {
    "build:web": "nx build web",

apps/web/next.config.js

module.exports = {
  target: 'experimental-serverless-trace',
}

.vercelignore

apps/otherapp1
apps/otherapp2
dist
tmp

Project settings in Vercel image

Multiple apps

Vercel doesn't yet support deploying multiple different apps from the same project. This is their "monorepo" support that is currently in development.

How do you manage the files in the public folder @flybayer ? I currently have the same configuration as you but none of my public files are available.

bluebeel commented 3 years ago

After much trial and error. I finally found my solution. With @flybayer's solution, if you have files in the public folder, they are not deployed on vercel because Vercel expects the public folder to be at the root where the deployment is done. In an nx folder it should be at the same level as the workspace.json file. The temporary solution I found is to set the root directory to apps/<app> on vercel and copy the package.json in this folder, the build command simply next build

flybayer commented 3 years ago

@rarmatei ah yeah we only have one main app in our repo at the moment, so the libs folder is not a problem.

@bluebeel I'm not using the public directory currently, but that's a good point. Probably will at some point.

flybayer commented 3 years ago

Here's a discussion I had with Vercel:

image

bluebeel commented 3 years ago

As a general solution, wouldn't it be possible to copy the public folder to root when nx/next has finished building? @rarmatei By doing this, Vercel sees the public folder at root when it deploys and we maintains the configuration of the ouput directory @flybayer did

flybayer commented 3 years ago

Yes that would work. Also Vercel is looking into the public folder and nx.

itstheandre commented 3 years ago

EDIT - For now, with just one website, i figured it out by following @flybayer setup. It works, and thats what matters. Multiple websites thats going to be a different ball game that i guess they dont have it yet. :)

Okay, as a super new user of the monorepos, let alone nx, how would this work?

If I have a lib folder with multiple components and varibales, how would you deploy something to vercel? Be it git initiated or cli based (i like the idea of cli based better, but its okay) I am completely lost on how to even send the components and variables that needs to get sent to vercel. Is it a metter of adding some scripts? I dont get it

Any help would be super welcome Thanks

benatkin commented 3 years ago

I got it working w/ @flybayer's setup. The first time I skipped over the next.config.js part but I needed that to get it to work. I will also note that I get this message:

17:53:12.934 | >  NX   WARNING  Nx Cloud Problems
-- | --
17:53:12.934 | - Cannot connect to remote cache (scope: api, code: ECONNABORTED).
17:53:12.940 | Done in 44.49s.

Apparently vercel blocks outgoing http requests including to nx-cloud, limiting its usefulness. Thankfully, it doesn't slow down the build noticeably. In the future I would probably want to configure it not to run on Vercel. It would be nice if it could run on Vercel though, if I could allow specific hosts.

dbrrt commented 3 years ago

I managed to deploy a nextJS (SSG) application from a nx monorepo context.

Capture d’écran 2020-10-28 à 21 50 37
"app:build": "nx run app:build && nx run app:export && yarn app:postbuild",
"app:postbuild": "mv dist/apps/app/exported apps/app/dist",

Selecting the other config did the trick. Using nextJS plugin failed because the route-manifest.json was never found.

bryandowning commented 3 years ago

Just in case anyone else comes across this thread and doesn't read #4032 (like me). I was able to get this working by adjusting the outputPath that nx builds next into.

I had followed what @flybayer did, and was able to confirm that files weren't serving from the public directory. Simply adjusting the outputPath, and removing the Output Directory override in the Vercel setting fixed it for me.

Note: My build command is simply: "build": "nx build",. So yarn nx build <app> --outputPath . is equivalent.

Screen Shot 2020-11-25 at 12 32 00 PM
JamesHenry commented 3 years ago

UPDATE

We have made a lot of progress on both the Vercel and Nrwl sides since I shared this solution, please see this comment for up to date guidance: https://github.com/nrwl/nx/issues/3051#issuecomment-757451051

I'm pleased to say that the advice below this line is now outdated!


Hi Folks,

Employee number 5 of Nrwl and long time Nx contributor (as well as long time Zeit/Vercel) user here 👋

Some of the suggestions on this thread so far are really not ideal in my opinion. They are giving up certain features of the Vercel + Next.js integration in some cases - sometimes subtly. Believe me I've banged my head against this problem a lot.

I hope sharing what I've learned will be useful to you!

This is the best possible setup I have managed to figure out with Nx + Next.js + Vercel, and I am currently running it in production across multiple projects. It is not perfect, but I believe it is the closest we can get with the current constraints on Vercel, and I have provided them with the product feedback on how to make this work perfectly with Nx. Read on to find out what I mean.

Let's say we have a Next.js app, generated by standard Nx schematics, called website (and it therefore lives in apps/website).

We want to create a project on Vercel by importing our Nx monorepo, and then calling the project website as well (NOT the name of the monorepo itself, which is what Vercel will pick by default).

Choice of framework preset on Vercel

What's important here is that we want to pick the Next.js preset (NOT Other or anything else)

You'll know you'll have done that bit right if your settings page for your website project on Vercel looks like this:

image

Choice of root directory on Vercel

We want to set the Root Directory to the apps/website directory. That's right, NOT to the root of the monorepo.

You'll know you'll have done that bit right if your settings page for your website project on Vercel looks like this:

image

Notice that checked box? That's also really important, but it's the default behaviour these days so you don't need to worry about it during initial setup.

Build & Development Settings

We have already picked one of these above, the Next.js preset. Now we need to override the build command as well.

Custom build command

Remember, our root directory is apps/website, so this is the starting context for our build.

I personally have created a reusable shell script that handles traversing up from my app's directory to the root and then doing the necessary Nx install and build. It looks like this:

tools/utils/build-nextjs-app-on-vercel.sh

# THIS SCRIPT IS INTENDED TO BE INVOKED FROM WITHIN THE ROOT OF THE PROJEECT BEING BUILT
# E.g. From within apps/foo -> ../../tools/utils/build-nextjs-app-on-vercel.sh foo apps/foo

if [ "$1" = "" ]
then
  echo "\nError: Missing required projectName as first argument"
  echo "\n       Example usage: $0 <projectName>"
  exit
fi

if [ "$2" = "" ]
then
  echo "\nError: Missing required outputPath as second argument"
  echo "\n       Example usage: $0 <projectName> <outputPath>"
  exit
fi

# Clean up the node_modules we had to install just to keep Vercel happy within the project root.
# If we don't remove them they will cause issues with the build from the root.
rm -rf node_modules

# Change to root (dynamically determined based on where we are executing the script from
# because there could be nesting within the apps/ directory)
SCRIPT_LOCATION=$0
DOT_DOT_SLASH=../

s=${SCRIPT_LOCATION//"$DOT_DOT_SLASH"}
NUMBER_OF_DOT_DOT_SLASHES="$(((${#SCRIPT_LOCATION} - ${#s}) / ${#DOT_DOT_SLASH}))"

for i in $(seq 1 $NUMBER_OF_DOT_DOT_SLASHES)
do
  cd ../
done

# Install full monorepo dependencies
yarn install

NODE_ENV=production npx nx build $1 --prod --outputPath=$2

(If you use this, or any other, shell script don't forget to make it executable in the usual way, e.g. chmod +x tools/utils/build-nextjs-app-on-vercel.sh)

NOTE: Vercel expects our Next.js build output to be in the Vercel Root Directory we chose (i.e. apps/website) so that is why we set the outputPath option to our Nx builder to be just that. This means we don't need to update our Nx workspace.json and we can serve and build the app locally how we always have. Zero config changes FTW!

The usage for our apps/website project therefore looks like this:

../../tools/utils/build-nextjs-app-on-vercel.sh website apps/website

And that's exactly what we override our build command on Vercel to be!

You'll know you'll have done that bit right if your settings page for your website project on Vercel looks like this:

image

What about a custom install command?

Now because we are handling the monorepo install in our custom build command (which is kind of the only place we can handle it), we don't want Vercel to waste time running an install in the nested location in apps/website.

Unfortunately, however, we do not seem to be able to skip the install command. If we override the install command to be empty - as is suggested - it will throw an error.

You'll know you'll have done that bit right if your settings page for your website project on Vercel looks like this:

image

SUPER DUPER IMPORTANT NOTE and the only real caveat of this setup...

Vercel will look for a package.json in your Vercel Root Directory, so for us that is apps/website.

This needs to exist, and it needs to be valid JSON otherwise the Vercel build silently fails. Unfortunately it does also need to contain a dependency on Next.js as well, which was briefly not the case on Vercel, but they seem to have added an explicit check for it now.

Remember above when I said this:

It is not perfect, but I believe it is the closest we can get with the current constraints on Vercel, and I have provided them with the product feedback on how to make this work perfectly with Nx

This is what I was referring to! I have passed on this exact feedback to Vercel. If they could make it so that this package.json check does not happen, the setup would be pretty great and all OOTB Nx!

So, all we need to do to work around this check and complete our setup is add a basic package.json file in the right location. I personally went for this:

apps/website/package.json

{
  "private": true,
  "description": "This file (and next dep) has to be here to get the Vercel build to run at all",
  "dependencies": {
    "next": "9.5.2"
  }
}

The next version here doesn't matter at all, it is never going to be used (and our custom build script above cleaned it up post-install anyway).

And that's it!

We only needed to add one file (and change ZERO config) for our OOTB Nx Next.js app to work and all the most killer automatic optimizations of Vercel + Next.js are fully available to us, such as Incremental Static Generation 🎉


Tangentially related for anyone that is interested:

The other big win that Vercel could make available to us Nx users would be to open up their Skip Build feature to the Nx dependency graph. Right now the Skip Build piece only does a very shallow checkout, so it is not possible to let Nx figure out what is affected for a particular commit.

Thanks to any Vercel folks who read this and let me know if I can help provide further feedback to make the Nx + Vercel story the best it can be 🙏

dbrrt commented 3 years ago

@JamesHenry Any idea why the route-manifest.json isn't found with nextJS plugin?

JamesHenry commented 3 years ago

@dbrrt If you are still approaching it based on the config in your comment above: https://github.com/nrwl/nx/issues/3051#issuecomment-718202172

...then that is the reason why.

My explanation covers that you should not choose Other, you should configure it using the Next.js Framework Preset, and follow all the other steps I outline.

All the steps I outline work together to create the final effect, including the Root Directory, Framework Preset, Custom Build Command etc

PS. Hopefully you are not changing anything about your next.config.js to try and "fix" the Vercel issues? Again the steps I outline above are how to make it work. If you are doing anything differently/in addition, then you risk it not working as expected. Hope that helps!

dbrrt commented 3 years ago

@JamesHenry Thanks for your tips, that'll be helpful, my approach worked somehow but would've preferred having the nextJS preset working indeed.

sskhokhar commented 3 years ago

@JamesHenry I tried the above provided solution. But it says access denied on build-nextjs-app-on-vercel.sh file. What could be the possible solution?

JamesHenry commented 3 years ago

@sskhokhar Perhaps you forgot to make the shell script executable after creating it?

chmod +x tools/utils/build-nextjs-app-on-vercel.sh

I'll add that as a note in my description to remind folks

dbrrt commented 3 years ago

Thanks @JamesHenry

leo commented 3 years ago

Hey, everyone!

Leo from Vercel here.

I'm scheduling a call with @JamesHenry to gain more insight into how we can make deploying NX to Vercel ideal. Afterwards, we'll get back to you here with an improved system!

Thank you for your patience!

westmark commented 3 years ago

@leo @JamesHenry Been using NX for a while and started looking into Next.js + Vercel + NX only yesterday, so imagine how thrilled I was reading the above! NX is awesome, everything should work with NX.

JamesHenry commented 3 years ago

We had a great call with @leo and have learned about some new improvements that have gone into Vercel that will allow us to simplify the recommendations.

I will be updating the Next.js guide on nx.dev to reflect this, and we can close this issue once that update goes live!

andreasasprou commented 3 years ago

Anyone know why I might be getting the following:

image

The configuration has been checked over multiple times by multiple people to ensure it matches the above.

itstheandre commented 3 years ago

Hey @JamesHenry . I saw on Nx's version 11 blog that they mention the contact with Vercel.

Do you know when said conversation / writings will be added? Or if they already are added to nx's website - the guides I mean?

Thanks! Happy holidays 🎉

JamesHenry commented 3 years ago

Hi folks 👋

We have worked together with Vercel to improve the configuration required to deploy Next.js apps on Vercel from Nx workspaces. Additional/custom scripts are no longer required.

Please see the updated guidance here https://github.com/nrwl/nx/pull/4483, it is available for you to implement immediately.

Once the PR is merged, the updated guidance will also be available on https://nx.dev/latest/react/guides/nextjs

Thanks!

asherccohen commented 3 years ago

Hey @JamesHenry, great job and thanks for finally getting to the bottom of this issue. I've been long waiting for something as simple as this solution.

I've added two tiny suggestions on your commit, based on my experiments with it, I hope they help.

JamesHenry commented 3 years ago

@asherccohen Thanks! It genuinely required some updates that were made on the Vercel side behind the scenes so it has been a great collaboration and I think things will only get better from here! Nx + Next.js + Vercel is some of my very favourite tech out there right now ❤️

asherccohen commented 3 years ago

Both companies have done an amazing job in simplifying dev experience!

I would keep an eye on how to filter by git branch in the case of git integration, as now I feel that every push to my branch will trigger (potentially) many projects to rebuild. When I started digging into this matter my config was using CI to test+build+deploy to Vercel, still curious to fully understand this.

vsavkin commented 3 years ago

This PR by @JamesHenry covers the setup in the docs https://github.com/nrwl/nx/pull/4483

We will deploy the new version of nx.dev with the changes from the PR later this week.

carlosfaria94 commented 3 years ago

npx nx build tuskdesk --prod --outputPath=. works to build a specific app in Vercel. However, when I try to run next export, i.e. in Nx I think is something like: npx nx export tuskdesk --outputPath=. I get the following error:

Error: A "routes-manifest.json" couldn't be found. This is normally caused by a misconfiguration in your project.

Please check the following, and reach out to support if you cannot resolve the problem:
1. If present, be sure your `build` script in "package.json" calls `next build`. 
2. Navigate to your project's settings in the Vercel dashboard, and verify that the "Build Command" is not overridden, or that it calls `next build`. 
3. Navigate to your project's settings in the Vercel dashboard, and verify that the "Output Directory" is not overridden. Note that `next export` does **not** require you change this setting, even if you customize the `next export` output directory.
4. Learn More: https://err.sh/vercel/vercel/now-next-routes-manifest

I have not changed the Output Directory.

https://github.com/vercel/vercel/blob/master/errors/now-next-routes-manifest.md

carlosfaria94 commented 3 years ago

By updating Nx dependencies with the following build settings, we managed to deploy it successfully:

image

dbrrt commented 3 years ago

@carlosfaria94 but apparently it's bad not using the nextJS preset for a nextJS application on vercel :) I've had as well this routes-manifest.json not being found as well using the nextJS plugin

Hopefully we'll have a neat solution working out-of-the-box with a fresh nextJS within a nx monorepo.

JamesHenry commented 3 years ago

@carlosfaria94 I am honestly surprised there is a need for running next export when deploying to Vercel given they already do Automatic Static Optimization for you, and you retain much greater flexibility to add dynamic behaviour in the future if you want to...

It's for that reason I have never used next export and so would need to defer to somebody who has and/or Vercel themselves to understand what the best approach is.

@leo Apologies for the direct ping, but is it possible that some of the Nx-relevant optimizations/fixes the team made recently were not applicable to next export?

dbrrt commented 3 years ago

@JamesHenry Are we talking of a static deployment or a serverless target deployment? I assumed both should be working with the recently applied fix, despite I was already able to deploy nextJS with nx with the nextJS plugin in vercel, via the serverless target.

https://nextjs.org/docs/advanced-features/static-html-export#how-to-use-it next build && next export is the recommended way to build a nextJS app following the official documentation.

Thanks again for sharing thoughts and experience.

carlosfaria94 commented 3 years ago

Yes, we had to ignore NextJs preset, and it's not clear what are the implications. At this stage, we are basically pushing static content to a CDN (Vercel).

However, I have the same question, what's best option for Vercel with Nextjs: next build or next export ?

btw. We are now trying to deploy only Nx affected applications on Vercel using GitHub Action + Vercel CLI

That's a good reference: https://www.netlify.com/blog/2020/04/21/deploying-nx-monorepos-to-netlify/

Thank you

cyrus-za commented 3 years ago

Nx + Next.js + Vercel is some of my very favourite tech out there right now ❤️ I agree. Love the stack and glad to see people working together. Now if we can just get Prisma to play nice with these we'll have a proper full stack combo.

@carlosfaria94 Things are working for me with latest nx and the changes documented here as @JamesHenry mentioned. No need to run next export. In fact, if you run next export you are basically creating a static CSR app as opposed to dynamically rendering pages on server and having api endpoints in pages/api running serverless functions. It's a fallback for those who do not deploy to vercel and do not have a serverless environment.

btw. We are now trying to deploy only Nx affected applications on Vercel using GitHub Action + Vercel CLI

Yep, we've been struggling with that too. Vercel clones with depth=1 so no reference to changes other than HEAD. If there's more than one commit in a PR, you can only check the last commit's changes and no reference to master in the ignore-build script. You can check here and here

dbrrt commented 3 years ago

@cyrus-za So does that mean it's not recommended to deploy CSR applications to vercel? I still see significant pros deploying a nextJS application this way (static), so it's a bit of a shame not to support that, if that's the case.

cyrus-za commented 3 years ago

@dbrrt its not that it wont work. It's just sad to not have the option to switch some page to ISR or SSR.

What happens when data changes in your db or cms? Do you need to deploy again?

dbrrt commented 3 years ago

@cyrus-za Agreed that an hybrid deployment for next applications could be useful. Regarding the data being changed in the database or cms, if it's managed through serverless functions within the nextJS project, in most cases you would have to redeploy, otherwise, nextJS can be seen as a front-end consuming other services, which can be notified in real-time of such changes via websocket or a polling mechanism. I don't think it's in the scope of nx on vercel since you'll have the same issue with other hosting providers.

cyrus-za commented 3 years ago

I think you are misunderstanding me @dbrrt. For my project, it works fine. Nextjs revalidates and rebuilds the static pages on each request (within a throttle I set on a page by page basis). This is built into nextjs but requires a platform such as vercel to handle that. If you use export you are opting out of it.

JamesHenry commented 3 years ago

I'm going to close this one for now as the original topic of the issue has been fully resolved and we have dedicated guidance on https://nx.dev for deploying Next.js to Vercel from Nx workspaces: https://nx.dev/latest/react/guides/nextjs#deploying-to-vercel

If folks want to continue the discussion around Vercel deployments, we have now enabled the Discussions tab on the repo so you can start a Discussion there: https://github.com/nrwl/nx/discussions

Additionally, if any new issues are discovered with the support for Next.js or anything else they can be reported as fresh issues with necessary context etc.

Thanks all!

marlomgirardi commented 3 years ago

Hey @JamesHenry! Just have one suggestion/question regarding this topic.

The only scenario that is not contemplated in here, is when using --with-deps.

Maybe instead of using --outputPath=. we just update the options inside workspace.json that way it will work with or without dependencies.

It might be another issue but the behaviour of --outputPath when combined with --with-deps seems to not work because it applies --outputPath for each project in that build pipeline (main project and libs).

Do we have an alternative by just changing the build command on vercel or the only option is to update the workspace.json?

Rafcin commented 2 years ago

Thank you for submitting this!

So just to summarise the problem here:

  • Vercel expects a source next.js directory - this is so it can do smart things around creating serverless functions for each one of your SSRd routes. Important here is that when you push your sources, it doesn't just do next build, it does its own custom build command
  • The above works fine when you have an isolated next.js app where ALL of your source files are needed to build and serve the app
  • It breaks down however, when you have a monorepo - with a lot of apps and libs, most of which will not be needed at all to serve and build your specific next.js app: you can't push your whole monorepo everytime you want to deploy just your next.js app, it's not scaleable

Ideally:

  • We'd build the next.js app locally - we have all the monorepo source code locally and we can traverse the dependency graph and grab what's necesary, be it a lib or an npm dependency. This all bundled into dist
  • We'd deploy the dist to Vercel, it would skip the build step, and serve it directly (this is not possible at the moment, you need to let Vercel build your app with a special command, that it doesn't expose publicly - hence why it requires your source files).

This is also why deploying to platforms like Heroku works great - because they allow you to next build locally, and then next start on their platform.

Getting around this problem would involve creating a "simplified monorepo", which contains just the libs and dependencies in package.json that your next.js app needs, and putting that into dist so it can be sent to Vercel. This is a complex process, a bit counter-intuitive (in the sense that we're putting source files in dist, where you'd expect a deployable artifact), and will only exist to work around a limitation of the Vercel platform.

Vercel knows about this, so I'd say to wait on them for a bit. As monorepos become more and more popular this will be a more and more requested feature.

This is also a really big pain point with AWS Amplify deployments. You can't stop the build process either.

asherccohen commented 2 years ago

Would a flow like this work?

Counter intuitive, sure, but better than weird setups.

Get Outlook for Androidhttps://aka.ms/AAb9ysg


From: Raf @.> Sent: Tuesday, November 30, 2021 9:59:19 PM To: nrwl/nx @.> Cc: Asher Cohen @.>; Mention @.> Subject: Re: [nrwl/nx] Next js: Easily deploy to Zeit vercel (#3051)

Thank you for submitting this!

So just to summarise the problem here:

Ideally:

This is also why deploying to platforms like Heroku works great - because they allow you to next build locally, and then next start on their platform.

Getting around this problem would involve creating a "simplified monorepo", which contains just the libs and dependencies in package.json that your next.js app needs, and putting that into dist so it can be sent to Vercel. This is a complex process, a bit counter-intuitive (in the sense that we're putting source files in dist, where you'd expect a deployable artifact), and will only exist to work around a limitation of the Vercel platform.

Vercel knows about this, so I'd say to wait on them for a bit. As monorepos become more and more popular this will be a more and more requested feature.

This is also a really big pain point with AWS Amplify deployments. You can't stop the build process either.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnrwl%2Fnx%2Fissues%2F3051%23issuecomment-983015052&data=04%7C01%7C%7C03737550562e48a4a95b08d9b4444770%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637739027624819702%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=Es0Q9wjyWoTox9%2FIkuSiY7opBekP3K35j5VGTZ0htiw%3D&reserved=0, or unsubscribehttps://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAIIV4EO26K7SCZJQRLQDSWLUOU3KPANCNFSM4NHTVNCA&data=04%7C01%7C%7C03737550562e48a4a95b08d9b4444770%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637739027624829659%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=HNqRO1jJw%2BwWV7qmlUMcrCDvDs6VHMaAut6ZwDa7CCQ%3D&reserved=0.