Gatsby 3 Migration

Earlier today I was listening to Tips & Tricks for Supercharging Image Performance, a Gatsby webinar about the new gatsby-plugin-image library. This library, bundled in as part of the new Gatsby v3, aims to simplify the optimization of images that a Gatsby website serves, but it's not the focus of this blog post. Toward the end of the webinar, one of the presenters, Matt Kane (@ascorbic on Twitter), mentioned that Gatsby v2 was scheduled for end of life. Uh oh. I have a handful of sites living out on the internet (including this one) that are on Gatsby v2. Uh oh uh oh uh oh. I did a quick search to see when the EOL date is for Gatsby v2, but couldn't find a hard date. But there's no day like the present, so I decided to go ahead and try to upgrade this site.

It looks like Gatsby is trying to make this an easy transition, though. For one thing, they have this handy Migrating from v2 to v3 guide where they provide instructions to follow for getting started and addressing common issues that are encountered. Cool.

Updating Dependencies

The first step in all of this is running upgrades on your code package dependencies. To give the repo a fresh start, I created a new Git branch within which to tackle all of these changes, then deleted package-lock.json and the entire node_modules directory.

The actual updates start with defining the core version of Gatsby you want to use in package.json to be 3.0.0 or higher. The following command installed and set the proper version for me: npm install --save gatsby@latest.

From there it's a matter of checking which installed NPM packages are outdated. Every site is different and has different plugins and dependencies installed, so there's no catch-all list of versions for these code packages needed. Instead you can check what's installed in your project using the npm outdated command. This gives you a list similar to the following:

Package                          Current   Wanted  Latest  Location                                      Depended by
gatsby-cli                        2.19.2   2.19.2   3.2.0  node_modules/gatsby-cli                       joeyreyes-dev
gatsby-image                      2.11.0   2.11.0   3.2.0  node_modules/gatsby-image                     joeyreyes-dev
gatsby-plugin-manifest            2.12.0   2.12.1   3.2.0  node_modules/gatsby-plugin-manifest           joeyreyes-dev
gatsby-plugin-react-helmet        3.10.0   3.10.0   4.2.0  node_modules/gatsby-plugin-react-helmet       joeyreyes-dev
gatsby-plugin-react-svg            3.0.0    3.0.1   3.0.1  node_modules/gatsby-plugin-react-svg          joeyreyes-dev

This is just a sample. I'm a big fan of the YOLO Update, where you just go through and run updates on everything and see what happens. If something breaks then you start following the error stack, and address the needs specific to certain dependencies. I recently just did this on an old WordPress site that I manage that hadn't had updates run in several years. It's not easy but sometimes it just has to be done.

I just went through the list and installed the latest version of each package. For example I would run npm install --save gatsby-cli@latest. This worked for most of the packages. Some had issues with the dependency tree that NPM v7 did not want to or could not resolve. To address this you can run that same command with the --legacy-peer-deps flag (i.e., npm install --save gatsby-cli@latest --legacy-peer-deps) which tells NPM to ignore peer dependencies and install anyway. If you want to read more about this flag and what's going on when you use it, you can read this Stack Overflow submission. Care should obviously be taken when you're forcing these kinds of updates and installations to make sure nothing is breaking. Fortunately I only had to do this for a couple of my package installations.

Fire That Server Up

With all the code dependencies updated, it was time to see what worked and what didn't. Before anything else I ran gatsby clean to purge any cached old content from previous development builds, then ran gatsby develop. There were a few warnings from Gatsby v3, but the site still fired up on localhost. It even looked like it should.

One of the more persistent warnings was the following: warn [gatsby-transformer-sharp] The "fixed" and "fluid" resolvers are now deprecated. Switch to "gatsby-plugin-image" for better performance and a simpler API. See https://gatsby.dev/migrate-images to learn how. Hey, there's that gatsby-plugin-image thing from the webinar that started all of this. The old gatsby-image package that was used so frequently in Gatsby v2 still worked, but since all of this work was being done to embrace the new and shiny, I thought it'd be a good time to try out this new image package. Luckily, as you can see in that warning message, another migration guide is provided for moving from gatsby-image to gatby-plugin-image. Cool cool.

I only have images on a small number of pages and templates in this blog so I wanted to try it out manually. I followed the guide but couldn't get my picture to show up on the About page. Errors were pretty opaque, and the newness of the package made it hard to figure out what I was doing wrong. But then I saw in the migration guide that there is a codemod to update your image imports automagically. Hey why not. YOLO Update, right? So I ran the following command: npx gatsby-codemods gatsby-plugin-image. No errors, 4 files modified. Cool cool cool. Fired the server back up, and the images are present! Some look a little weird, and I needed to modify the CSS for their parent containers a little bit, but nothing major.

Easy Enough

So that about sums up my experience upgrading from Gatsby v2 to Gatsby v3. I just updated the code dependencies, then ran a little codemod to embrace the gatsby-plugin-image freshness. Gatsby has some great migration docs available for this, but the errors you encounter might not be super well documented. So take all of this with a big grain of salt that experiences may vary depending on how out of date your NPM packages are, how old the versions of Node and Gatsby you're running are, and which/how many plugins, themes, or dependencies you're using. Some of those may not be 100% buttoned up and ready for primetime with the new Gatsby. One thing I'm running into that I cannot resolve is the following warning:

warn Module not found: Error: Can't resolve 'path' in '/joeyreyes-dev/node_modules/minimatch'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
  - add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
  - install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
  resolve.fallback: { "path": false }

From what I can tell, this is an issue where one of the really deep dependencies, minimatch, is not quite compatible with the latest version of webpack that Gatsby v3 uses. I think this is a matter of that package's code maintainer(s) making adjustments. But from what I can tell, the site still runs fine. If you're reading this on the web then that should be the case at least. Enjoy this site on the new Gatsby v3!