-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
[next] Fix nextjs routes in vercel dev
#4510
Conversation
I have tried this change locally and deployed on vercel using a staging deployment of our production application. I was unable to detect any adverse effect as both worked fine. The unit tests ran fine
As far as I could tell, before my change,
Since my change hopefully I missed something |
now dev
vercel dev
vercel dev
vercel dev
Hi, can you provide a link to an example project this is trying to fix? This legacy routes generation should no longer be relied on since it conflicts with the new rewrites/redirects support in Next.js. I think the correct way to handle this would be to make sure we proxy all request to |
Hi @ijjk I have quickly configured an example in https://github.com/jeantil/next-9-ts-aliases-workspaces/tree/vercel/dynamic-paths-failure which demonstrates the issue:
run vercel dev
I get a 404 on the last one in dev and with @styfle's guidance, I tracked it down to this modification. Using a builder with this modification in both deployed and dev work fine.
I try to follow the changes in both vercel and next but I was unaware of this feature. |
f124515
to
2a730bc
Compare
Hello @styfle @ijjk , have you had time to review this issue further ? we are not feeling very safe diverging from vercel published builders for too long, maintaining our own fork is quite time consuming but dynamic next routes are broken in our project (and probably a few others) without this fix.
and now repeating the same command
fails right at the start, I'm not sure what's wrong and I'm quite lost in the repo setup, some guidance would be most welcome. |
This PR fixes a longstanding issue introduced in #3673 that prevents routing properties from applying to the framework's upstream dev server. This mimic's the older proxy logic used in build matches here: https://github.com/vercel/vercel/blob/5035fa537f82181649d42778c60145d8890f3291/packages/now-cli/src/util/dev/server.ts#L1535-L1539 - Related to #3777 - Related to #4510
@styfle I have looked at #4644 and installed 19.1.1 locally to see if it made this PR obsolete. Unfortunately #4644 does not fix the nextjs dynamic routing in Is there any concern regarding this PR that I need to address to help it move forward, it makes our DX really bad. We use a custom build of @vercel/next in dev to get the fix from this PR, but it's quite a costly process so getting this in would free up a lot of effort for us |
Hi @jeantil Thanks for the PR! The only thing missing is a test fixture. You can add one to ./packages/now-cli/test/dev/fixtures, perhaps just your example repo you linked to earlier. You can run locally by setting your |
Actually, let's put the new test in ./packages/now-cli/test/dev/fixtures since this is a I updated my comment above. |
packages/now-next/src/index.ts
Outdated
urls[entrypoint], | ||
meta.isDev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
urls[entrypoint], | |
meta.isDev | |
urls[entrypoint] |
This method is only used in dev mode so we don't need to pass whether we're in dev mode or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ijjk I think its better to be explicit, someone might move this getRoutes() to a different place where it might get used in production.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm i reverted this to resolve this comment but I can re-revert :)
@@ -490,7 +495,7 @@ export async function getDynamicRoutes( | |||
routes.push({ | |||
src: pageMatcher.matcher.source, | |||
dest, | |||
check: true, | |||
check: !isDev, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change needed? Seems like it shouldn't affect the routes in dev mode 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually that change is the fix, all the rest was just propagating the value of isDev
though the function calls because I failed to notice that getRoutes was always only called in dev mode.
I initially added tons of traces in the route matching code and ended up with traces like
dev router trying to match undefined /blog/top-10-des-incontournables-destination-du-perou
dev router trying to match GET /www/blog/top-10-des-incontournables-destination-du-perou to {"src":"^/www/(blog/([^/]+?)(?:/)?)$","dest":"http://localhost:44659/$1","check":true}
===============
hasDestFile false pathname /blog/top-10-des-incontournables-destination-du-perou destPath http://localhost:44659/blog/top-10-des-incontournables-destination-du-perou phase null routeConfig {"src":"^/www/(blog/([^/]+?)(?:/)?)$","dest":"http://localhost:44659/$1","check":true}
===============
After a bit of back and forth testing a few vercel.json configurations @styfle wrote:
Oh so the route `
{"src":"^/www/(blog/([^/]+?)(?:/)?)$","dest":"http://localhost:43097/$1","check":true}
is from @vercel/next which seems wrong. I dont think it should have check:true
I traced it back to this line and indeed changing it to false resolved the issue. I must confess that I have absolutely no idea what check: true
orcheck: false
does. since I needed is to be false in dev to get the behaviour I wanted, I made the safest possible change I could by making sure this only affected dev mode.
on a side note, since the value of the isDev
parameter was not provided to getDynamicRoutes
before this change isDev
was always undefined, thus !isDev
was always true, thus the code at https://github.com/vercel/vercel/pull/4510/files#diff-f5c41b908e3f767349246f7dfb3714e1L484 was always going through path.join('/', entryDirectory, pageMatcher.pageName)
but I was unable to detect an impact after changing it. It is worth noting that just fixing the isDev
value without setting check
to false was not enough to fix the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ijjk The problem is that check: true
is similar to continue: true
when the resource is not found. See the routing logic here:
if (routeConfig.check && devServer && phase !== 'hit') { |
In particular, this is where it continues:
continue; |
packages/now-cli/test/dev/fixtures/monorepo-dynamic-paths/blog/next.config.js
Outdated
Show resolved
Hide resolved
I have added the integration test in @styfle suggested I use |
be12483
to
e61f8a7
Compare
packages/now-cli/test/dev/fixtures/monorepo-dynamic-paths/blog/package.json
Outdated
Show resolved
Hide resolved
a28fccc
to
a750c4a
Compare
This change fixes vercel#4239 where using `now dev` to work on monorepos where the next.js app is not in the topmost directory fails to correctly route to dynamic pages. After investigating the devServer router, @styfle prompted me to investigate the @vercel/next builder. He also suggested restricting `check` to be false only when running in `now dev`. This led me to realize that isDev was either false or undefined in getDynamicRoutes. Fixing that didn't lead to any observable adverse effect on my repository either running `yarn test-unit`, during `vercel dev` or while deploying on vercel...
I managed to make the integration test work by deploying a custom build of now-next with the patch (next-2.6.8-canary.0.tgz) and forcing the integration test to use that. I then reverted In the process of making the integration test work I discovered further breakage in the routing in prod mode:
Here is a table of observed results for the above routes, for
Interestingly
--edit-- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for all the work you put into this, great job! 🎉
I ran all the tests locally and found one that needed to be updated so I pushed a change.
I think we can merge this and address the other bugs in another PR 👍
thank you ! |
@morgs32 it would be worth investigating this table further since I wasn't aware of fallback pages at the time and it may explain some of the issue but I don't have time to do this for the moment |
I understand @jeantil. How did you go about testing |
I suggest building the full checkout once, then in if you suspect your modifications are not picked up, you can I built the above table by experimenting with the testcase I added for this PR in good hunting ! |
Well I created an issue with vercel's website since I can't do it through GitHub. Here's a PR that got dynamic routes to work in my own deployment. Not sure it's a safe fix - but thought I'd share! |
This change fixes #4239 where using
now dev
to work on monorepos havinga next.js app which is not in the topmost directory fails to correctly route
to dynamic pages.