Skip to content
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

Breaking: Upgrade Gatsby to latest version 5. #186

Merged
merged 5 commits into from
Aug 15, 2024

Conversation

maanasb01
Copy link
Collaborator

@maanasb01 maanasb01 commented Aug 14, 2024

Upgradation to Version 5 Notes

Table of Contents

Breaking Changes

  • Minimal requirement of Node.js version 18.
  • Minimal requirement of the React version is 18.
  • GraphQL schema changes (Discussed Later). The internal graphql dependency was updated to v16.
  • Changes in MDX syntax after upgrading gatsby-plugin-mdx which uses MDX v2.

Upgrading Gatsby, React & other dependencies

Ref: https://www.gatsbyjs.com/docs/reference/release-notes/migrating-from-v4-to-v5/#updating-your-dependencies

  • Using --legacy-peer-deps with npm: Since npm 7+ enforces stricter peer dependency rules, Gatsby recommended using the --legacy-peer-deps option during installation. This approach was taken to prevent dependency resolution errors that could arise from incompatible plugin versions.

  • Updating Gatsby Plugins: All Gatsby-related plugins (those prefixed with gatsby-*) were updated to their latest versions to ensure compatibility with v5.

  • Community Plugins: Some third-party plugins did not immediately support Gatsby v5. In these cases, Gatsby recommends using --legacy-peer-deps. This is because the plugin needs to update its peerDependencies to include the new version of Gatsby.

"While this might indicate that the plugin has incompatibilities, in most cases they should continue to work."
Gatsby Documentation

GraphQL Changes

Sort and Aggregation

  • As per the RFC: Change to sort and aggregation fields API, the sort argument and aggregation’s field argument were changed from enums to nested input objects.

  • Gatsby provides a codemod for changing the graphql queries where the sort or aggregation is used.

  • NOTE: The npx gatsby-codemods@latest sort-and-aggr-graphql <filepath> which is written in the migration guide did not work for this project. So instead, I installed the gatsby-codemod and JSCodeshift and then ran command jscodeshift -t node_modules/gatsby-codemods/transforms/sort-and-aggr-graphql.js . like an example provided in gatsby-codemod docs.

  • The following examples are taken from the Gatsby migration guide:

    Sort:

    • Before:
      {
        allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
          nodes {
            ...fields
          }
        }
      }
    • After:
      {
        allMarkdownRemark(sort: { frontmatter: { date: DESC } }) {
          nodes {
            ...fields
          }
        }
      }

    Aggregation:

    • Before:
      {
        allMarkdownRemark {
          distinct(field: frontmatter___category)
        }
      }
    • After:
      {
        allMarkdownRemark {
          distinct(field: { frontmatter: { category: SELECT } })
        }
      }

Extending the GraphQL MDX nodes

The fields property

  • Earlier, the additional fields which were being extended to the mdx nodes were directly accessible in the GraphQl query. But now, they will be accessible through the fields property.
  • In this project, the slug field is being extended to all the mdx nodes with the help of onCreateNode. This is still the same.
  • Reference for the below code: https://github.com/tattle-made/website/blob/master/gatsby-node.js
exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions
  if (node.internal.type === `Mdx`) {
    // if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}
  • The above code remains the same but the way to access the slug property in the GraphQl query will now be through the fields property instead of directly accessing it like before.
    • Before

      const result = await graphql(`
      query {
      allMdx {
        nodes {
          id
          slug
          frontmatter {
            name
          }
        }
      }
      }
      `)
    • After

      const result = await graphql(`
      query {
        allMdx {
          nodes {
            id
            fields {
              slug
            }
            frontmatter {
              name
            }
          }
        }
      }
      `)

The fileAbsolutePath is deprecated

  • The fileAbsolutePath field inside the mdx nodes is deprecated. Instead, we are required to use contentFilePath inside the internal property ( internal.contentFilePath ).
  • Before
    const result = await graphql(`
    query {
    allMdx {
      nodes {
        id
        fileAbsolutePath
        frontmatter {
          name
        }
      }
    }
    }
    `)
  • After
     const result = await graphql(`
     query {
       allMdx {
         nodes {
           id
           internal {
              contentFilePath
           }
           frontmatter {
             name
           }
         }
       }
     }
     `)

Changes in childImageSharp

  • This is related to the migration from gatsby-image to gatsby-plugin-image, as gatsby-image plugin is deprecated.
  • More details are discussed in the Handling Images section.
  • All the GraphQL changes in the details can be found here.
  • There are no more fragments to use (like fluid, fixed). Instead, things like layout and format are passed as arguments to the gatsbyImageData resolver.
  • The fluid image type is deprecated in favour of two alternatives: fullWidth and constrained
    • Before
        query {
         file(relativePath: { eq: "landing-page-wide.png" }) {
           childImageSharp {
             fluid {
               src
             }
           }
         }
       }
    • After
        query {
         file(relativePath: { eq: "landing-page-wide.png" }) {
           childImageSharp {
             gatsbyImageData(
               layout: FULL_WIDTH
               placeholder: BLURRED
             )
           }
         }
       }

Changes related to MDX files

The gatsby-plugin-mdx latest version

  • We now use the latest version of gatsby-plugin-mdx plugin.
  • All the changes related to the GraphQL queries are discussed in the GraphQL Changes section.
  • References:
  • After installing this plugin, when I was trying to run the code in developer mode, I kept getting an error related to es-lint. To resolve this I had to install eslint and eslint-webpack-plugin packages as dev dependencies. This could be because of the requirements of the plugin after the update. Note that I had to downgrade the eslint dependency from version 9 to version 7.3 to make it work.
  • In the latest upgrade, the GitHub Flavored Markdown (GFM) support was removed from MDX v2. I had to re-enable it with mdxOptions (after installing the remark-gfm package).
    • Note: There was some issue with the remark-gfm package (possibly while rendering the tables). So, I had to downgrade this package by a version. I referred to this issue and many answers suggested doing that.

MDX Syntax

  • This was a major change which affected all the Mdx files.
  • Relevant section in migration guide: https://www.gatsbyjs.com/plugins/gatsby-plugin-mdx/#updating-mdx-content
  • After the upgrade, the plugin uses MDX v2. Some of the changes include:
    • HTML syntax won't work from now, only JSX syntax would work ex: <img> won't work now, it has to be the <img /> tag.
    • Comments should be done as they are done in JSX (with {/* */}.
    • Unescaped left angle bracket / less than (<) and left curly brace ({) have to be escaped: \< or\{(or use expressions: {'<'}, {'{'}) - From plugin migration guide
  • All other changes can be viewed here in the mdx-js official documentation.
  • I have also noticed in several mdx files of blogs and other places as well that styling of the components was being done with the string ex- <div style="width:16em;">. Instead, the objects should be used to do the same: <div style={{width: "16em}}>. The previous way would throw an error during the build time.
  • I recommend using an extension to get the IntelliSense of the latest MDX version syntax. I have used this extension in VS code and it worked pretty well in identifying all the syntax issues.
  • In this PR, I have identified the issues in all the mdx files in the project everywhere and rectified them.

Layout issue in MDX files inside the pages directory.

  • The latest update in the mdx plugin deprecated the defaultLayout option. So all the mdx files (only inside the pages directory) need to export a default Layout component (or wrap the whole file's content in the layout component), according to the mdx v2 syntax. A good reference for all the options in place of defaultLayout: https://stackoverflow.com/a/73584154. We can explore other ways too later.
  • For this, I have created a script "addMdxLayout.js" in the root directory. For every mdx file in the pages directory, it checks if the default layout is already there or not, if it's not, then it adds the export default Layout statement at the top of the file.
  • From now on, if there is a need to create an mdx file inside the pages directory (so that it has its own route like /contact), please take a look at any of the previously presented files in the pages directory and just copy the lines related to exporting the layout. These are the lines which are added to all the mdx files in the pages directory:
import DefaultLayoutNarrow from "@/components/default-layout-narrow";

export default function Layout({ children }) {
  return <DefaultLayoutNarrow>{children}</DefaultLayoutNarrow>;
}

Handling Images

  • This section might be related to issue Standardize how images are to be used in the website. #177.
  • The gatsby-image plugin has been deprecated. Instead, it is recommended to use the gatsby-plugin-image only.
  • Migration guide: https://www.gatsbyjs.com/docs/reference/release-notes/image-migration-guide/#graphql-changes
  • I have implemented all the GraphQL related changes as described in the GraphQL Changes section.
  • The migration guide also suggests using the GatsbyImage component from the gatsby-plugin-image package instead of using the Image component from the old gatsby-image package. In this project, we never used the Image component from the old gatsby-image package, but used the Image component from the grommet. I tried using the suggested components in the https://www.gatsbyjs.com/plugins/gatsby-plugin-image/#gatsby-plugin-image documentation (the GatsbyImage component and the StaticImage component), but they did not work out quite well. The StaticImage component was not rendering and the GatsbyImage component was rendering low-quality images.
  • I tried to resolve the issues by implementing several suggestions from the discussions like changing the default quality from 50 to a higher number, but it did not work out. So I switched back to using the component from grommet. We can explore this later.

Added a new gatsby-plugin-alias-imports plugin

  • Added gatsby-plugin-alias-imports plugins to have alias imports, now src can be accessed with "@". This was done specifically to make importing layout in mdx files inside the pages directory easy. But we can add other aliases too and use them throughout the project.

Removal of useNavigate hook

Copy link

netlify bot commented Aug 14, 2024

Deploy Preview for tattle-website-preview failed. Why did it fail? →

Name Link
🔨 Latest commit ca83abc
🔍 Latest deploy log https://app.netlify.com/sites/tattle-website-preview/deploys/66bcea0f44499900089f6cb4

@dennyabrain
Copy link
Contributor

@maanasb01 the netlify build seems to be failing because it was using older version of node to build the site. I have upgraded node version on netlify. You might need to push again to trigger a build. Since its a major commit, I'd like to make sure the preview build on netlify is passing so i can test all important pages.

@maanasb01
Copy link
Collaborator Author

@dennyabrain Done!

@maanasb01
Copy link
Collaborator Author

@dennyabrain It appears that the version which is being used is still 16.20.2

Netlify Build logs:
image

@dennyabrain
Copy link
Contributor

dennyabrain commented Aug 14, 2024

Yeah, not sure why. I have configured netlify to use the latest stable node version.
Screenshot 2024-08-14 at 22-20-17 Build   deploy Site configuration tattle-website-preview Netlify

Lets take a look tomorrow.

@maanasb01
Copy link
Collaborator Author

maanasb01 commented Aug 14, 2024

@dennyabrain Yeah sure! Can it depend on deploy-production.yml file? In that file, the mentioned node version is still 16. In this PR I have changed it to 18.

@dennyabrain
Copy link
Contributor

Hmmm, I don't think so. But regardless I have updated the version in the workflow file as well and merged in main.

@maanasb01
Copy link
Collaborator Author

@dennyabrain Yeah you were right, it did not work. I pushed a new commit and it failed again with the same error (the version compatibility one).

@dennyabrain
Copy link
Contributor

I have pulled the PR locally and built it and checked it. I am merging it to check the possiblity that maybe netlify is failing because of some old data/caching issue. Will watch out for next PR

@dennyabrain dennyabrain merged commit d5af483 into tattle-made:master Aug 15, 2024
1 of 5 checks passed
@dennyabrain dennyabrain linked an issue Aug 15, 2024 that may be closed by this pull request
@maanasb01
Copy link
Collaborator Author

Great! Glad it worked out!

@maanasb01 maanasb01 changed the title Feat: first iteration of upgrading Gatsby to latest version 5. Breaking: Upgrade Gatsby to latest version 5. Aug 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Upgrade project's core dependencies to latest version
2 participants