Heygrady

Upgrading Gatsby to 1.0

July 06, 2017

The latest version of Gatsby was somewhat different from the pre-1.0 release. I upgraded my blog manually from the old version to the new one.

In a previous post I installed Gatsby 0.12.48 as an upgrade to my blog. Now it’s already time to upgrade Gatsby. Version 1.0 of Gatsby has been released. There are already docs available for upgrading to the new version. Here we’re going to upgrade this blog to Gatsby 1.0.

Big changes

Gatsby has changed in some significant, disorienting ways since the pre-1.0 days. The big upgrade is that there’s a new application framework designed around GraphQL. This new app-centric structure is more like what you’d find in a traditional react starter-kit, like the react-redux-starter-kit, except Gatsby has a focus on pages instead of routes. Gatsby is still just a static site generator — but it’s getting dressed up to work with data.

The 1.0 version of Gatsby includes an upgrade to their blog starter.We’re trying to make our old site (based on the old blog starter) work with the new version of Gatsby.

Let’s install a new blog as an example of what we needs to change. This will give us a local example of an already-upgraded Gatsby site to work from.

Make a fresh Gatsby blog

Install a fresh blog in a new directory. I installed it in the directory next to my existing blog. This will make it easy to copy files over when it’s time for that.

# upgrade to the latest gatsby cli
npm install -g gatsby

# install the fresh blog next to your blog
cd blog
cd ..
gatsby new upgrade-test gatsbyjs/gatsby-starter-blog

Moving over posts

The old blog was a vanilla clone of the Gatsby starter. It should be possible to move the posts from the pages folder of the old site to the src/pages folder of the new site. For now it’s best to only move the blog posts themselves. Gatsby is pretty much the same with regards to posts themselves, many of the other boilerplate files have changed.

  • Copy just the posts from your existing blog to the fresh blog
  • Delete the example posts
  • Start the fresh blog to see if it works
cd upgrade-test
yarn dev

Once you’re happy that the new site can load your posts, it’s time to systematically migrate over the new files into your existing blog.

Because our blog is so vanilla we should be able to do an in-place upgrade, copying over only the files we need.

Make an upgrade branch

This will be a big change to the site. We’re going to be following a feature-branch workflow.

cd blog
git branch gatsby-upgrade && \
git checkout gatsby-upgrade

Add the src folder

The most obvious change in Gatsby is the addition of a src folder. This is a common convention in babel-based projects and it’s great that Gatsby is embracing it.

mkdir src && \
mv components ./src/ && \
mv css ./src/ && \
mv pages ./src/ && \
mv utils ./src/ && \
mv wrappers ./src/ && \
mv html.js ./src/

Out with the old, in with the new

The new Gatsby works differently enough that we want to blow away our old blog and copy the new blog on top of it. We’re going to do this somewhat surgically. Luckily there’s a first step that’s pretty easy. We should be able to rename our newly created src folder and replace it with the source folder from the fresh new blog we created at the beginning of this post.

Note: If you haven’t created that fresh copy (see above), do so now. We’re going to be grabbing a bunch of files from it.

# stash old files and copy over the new ones
echo old-src >> .gitignore
mv src old-src
cp ../upgrade-test/src ./

Now we need to reconcile the two src folders.

  • If you haven’t already, move all of your posts from old-src to src — and make sure to remove the example posts.
  • Make sure to replace your profile pic in the src/components folder.
  • Note that the new blog doesn’t have a ReadNext component anymore. You can choose to get the old one working. I’m choosing to follow along and drop the read next feature.

Add src/config.js

The new Gatsby relies on GraphQL to manage the config but this idea hasn’t been fully ported over to the blog example. Whatever the reason, the new blog is using hard-coded values in src/components/Bio.js and src/layouts/index.js. As a temporary fix we’re going to add a src/config.js file with the values we need.

Eventually this should be replaced by GraphQL lookups. If you were trying to get ReadNext working this might be a good place to start. We’re going to use the config to remove the hard-coded values. Eventually we should replace the config with GraphQL lookups but that can wait for another time.

You should port over all of the values from your config.toml because we’ll be deleting that in a later step.

export default {
  blogTitle: 'Heygrady',
  author: 'Grady Kuhnline',
  twitterHandle: 'heygrady'
}

Fix src/layouts/index.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Link from 'gatsby-link'
import { Container } from 'react-responsive-grid'
import { rhythm, scale } from '../utils/typography'
import config from '../config'

import 'prismjs/themes/prism-solarizedlight.css'
import '../css/prism.css'

// ... Replace the hard-coded blog title with a config variable

Template.propTypes = {
  children: PropTypes.func,
  location: PropTypes.object
}

export default Template

Fix src/components/Bio.js

  • Import the temporary config
  • Replace instances of Kyle Mathews with {config.author}
  • Add back your customized bio
  • Fix PropTypes warnings
  • Fix ESLint errors

Fix src/pages/index.js

Fix src/templates/blog-post.js

  • Fix PropTypes warnings
  • Fix ESLint errors

Merge package.json

  • Update name, description, etc to match your blog.
  • Copy the dependencies from the new blog
  • Keep the devDependencies from the old blog (see previous post on eslint)
  • Grab the fix-semi script from the new blog
  • Update build:prod to use --prefix-paths instead of --prefix-links

Copy over other important files

We need to drop our config.toml and grab the bootstrap config files from the new blog.

rm config.toml && \
rm .gitignore && \
cp ../upgrade-test/.gitignore ./ && \
cp ../upgrade-test/.babelrc ./ && \
cp ../upgrade-test/gatsby-config.js ./ && \
cp ../upgrade-test/gatsby-node.js ./

Update gatsby-config.js

Gatsby uses a new path-prefix functionality. We need to add this to the gatsby-config.js. We also need to add our siteMetadata to match what we added in src/config.js.

  • Add a pathPrefix
  • Update the siteMetadata
module.exports = {
  pathPrefix: '/',
  siteMetadata: {
    title: 'Heygrady',
    author: 'Grady Kuhnline',
    twitterHandle:'heygrady'
  },
  // ...
}

Reinstall everything

The new version of Gatsby has totally different dependencies. We need to blow away the public and node_modules folders and reinstall all of our packages. This will remove any files related to the old version of Gatsby.

rm -drf public && \
rm -drf node_modules && \
yarn install

Test it Out

If everything is working, we should be able to boot up the test site using yarn dev.

# see if the site works on http://localhost:8000
yarn dev

Load the site in your browser and see if everything looks correct.

You also need to test the production build. Because we’re building static files, we can easily test the build using http-server. This allows us to server the public folder locally to ensure the site is building correctly.

yarn global add http-server

yarn build:prod && \
cd public && \
http-server -c-1

Wrapping up

If you customized your old blog more heavily than I did, you may need to fix up a few more things. In cases where the new graphql functionality isn’t obvious, fall back on the src/config.js file and leave yourself a TODO. At the time of this writing the graphql documentation is incomplete (latest) and upgrading may be non-trivial.

Deploying

Once you are happy with your upgrade, commit it to the gatsby-upgrade branch and push it to github.

git add . && \
git commit -m "Upgrading to Gatsby 1.0" && \
git push origin gatsby-upgrade

On Github you will want to merge your feature branch using a pull request. This should trigger the travis deploy. Be sure to check every link on your site before doing the final merge.


Grady KuhnlineWritten by Grady Kuhnline. @heygrady | Github