Upgrading from NextJS v12 to v13
I’ve been running Next 12.1.7-canary.38 for a while and recently my IDE started giving me warnings that this package contained vulnerabilities.
So I decided to make the leap and upgrade to NextJS v13.
Initially things went smooth.
I upgraded locally and had a handful of warnings and errors that needed to be addressed by:
-
Removing the layout prop from
Image
component since that was removed in v13.1 -
Running the suggested Next codemod to deal with other changes to the
Image
components between v12 and v13 -
Removing the
prefetch
attribute on a number of components to clear some warnings.
Everything was running great locally with next dev
. No errors, no warnings.
But after pushing to Vercel, I got a new error I’d never seen before. The UI showed:
Application error: a client-side exception has occurred (see the browser console for more information).
on an otherwise blank screen.
In the console, the first error message was:
index.js:271 TypeError: Cannot call a class as a function at jsbi-umd.js:1:491 at a (jsbi-umd.js:1:491) at a.<anonymous> (jsbi-umd.js:1:2649) at new a (jsbi-umd.js:1:4473) at Function.value (jsbi-umd.js:1:17240) at Function.value (jsbi-umd.js:1:8031) at 4567 (index.esm.js:1:3777) at __webpack_require__ (bootstrap:21:1) at 9997 (TableFooter.tsx:69:1) at __webpack_require__ (bootstrap:21:1)
I hadn’t seen anything like that before and I couldn’t tell where it was coming from. I searched for solutions but nothing seemed to come close to my situation. I couldn’t find any places where I was calling a class as a function.
Again the problem was only happening in production, locally everything was fine.
I spent a considerable amount of experimenting with possible solutions, then deploying to Vercel, waiting 2 minutes only the find the error was still there.
One good thing that came out of this was I finally figured out that running
vercel build
is a much faster way to test a production vercel build locally
in a case like this. I’ll definitely be making use of that in the future.
With that shorter build-test cycle time I was able to narrow down the source
of the error. This requires an install of [Vercel CLI](https://vercel
.com/docs/cli).
If you are using Vercel CLI, do you install it globally like
the docs suggest, or do you install on a per project basis? I went with the
global install, but then realized it’s not in my environment PATH
variable.
So instead of messing with that, I just called it with ~blentz/.yarn/bin/vercel build
Back to the original error. I had been using the Temporal
package to
calculate things like the current day of the year (aka the ordinal):
<TableFooter total={Temporal.Now.plainDateISO().dayOfYear} habit="days" goal={Temporal.Now.plainDateISO().daysInYear} totalPercentage={Math.floor((15 / 365) * 100)} topLabel={"Day #"} bottomLabel={"of"} />
Temporal is not yet approved for production use but at the time I thought what the hell, what could go wrong?
Well, it turns out it was causing the mysterious:
index.js:271 TypeError: Cannot call a class as a function
error.
I figured this out by commenting out chunks of code and seeing somewhat helpful changes to the stacktrace in the original error message. They were kind of pointing me in the right direction.
Looking into other date/time libraries led me to the Moment library. Since that is not being actively developed, I went with their recommendation and used Luxon. Its easy to use and well documented. Here’s what it looks like in use:
<TableFooter total={DateTime.now().ordinal} habit="days" goal={DateTime.local(2024).daysInYear} totalPercentage={Math.floor((15 / 365) * 100)} topLabel={"Day #"} bottomLabel={"of"} />
Issue solved ✅
Better library for date/time ✅
No more 2 minute wait times when troubleshooting a Vercel build ✅
I’m glad I made the switch to v13.
Hopefully this might help someone else out who also thought it would be a great idea to use the Temporal library before it’s been officially approved.