Gatsby v2からv3へアップグレードするためにいろいろしたよ！

# はじめに
こんにちは。新しいPCほしいのですが、chromebookで仕事できるのかちょっと検討中です。昔はストレージなかったですが、最近はストレージあるんすねー！vscodeとかも使えるしLinux入れられるのであれば、行けるのか...:thinking:

さて、今回は**Gatsby**のv3が出てたので、アップグレードしました！
ただ、いろいろこねくり回してやっとアップグレードできたので、その軌跡を記事にしようと思います。

これからやるぞという方の参考になれば幸いです！

# 本編
## 1. **gatsby**の最新版をinstallします。

```sh
$ npm install gatsby@latest
```

ここで、npmのバージョンが6のときは、以下のようにオプション付けないとダメでした。

```sh
$ npm install gatsby@latest --legacy-peer-deps
```

## 2. 一旦buildできるか試してみた.

**案の定、すごい怒られる...。**

```sh
$ gatsby develop

ERROR

Unexpected key "pageData" found in preloadedState argument passed to createStore. Expected to find one of the known reducer keys instead: "nodes", "logs", "pages", "redirects",
"schema", "definitions", "staticQueryComponents", "status", "webpack", "webpackCompilationHash", "config", "lastAction", "jobsV2", "pageDataStats", "components", "babelrc", "jobs",
 "nodesByType", "program", "resolvedNodesCache", "nodesTouched", "flattenedPlugins", "pendingPageDataWrites", "schemaCustomization", "inferenceMetadata", "staticQueriesByTemplate",
 "queries", "visitedPages", "html", "functions". Unexpected keys will be ignored.

ERROR #98123  WEBPACK

Generating development JavaScript bundle failed

Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
Error: PostCSS plugin postcss-flexbugs-fixes requires PostCSS 8.
Migration guide for end-users:
https://github.com/postcss/postcss/wiki/PostCSS-8-for-end-users
...(省略)


ERROR #98123  WEBPACK

Generating development JavaScript bundle failed

Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
Error: PostCSS plugin postcss-flexbugs-fixes requires PostCSS 8.
Migration guide for end-users:
https://github.com/postcss/postcss/wiki/PostCSS-8-for-end-users
...(省略)

ERROR #98123  WEBPACK

Generating development JavaScript bundle failed

ESLint is not a constructor

failed Building development bundle - 6.846s
ERROR in ./.cache/blank.css
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
Error: PostCSS plugin postcss-flexbugs-fixes requires PostCSS 8.
Migration guide for end-users:
https://github.com/postcss/postcss/wiki/PostCSS-8-for-end-users
...(省略)

ERROR in ./node_modules/prismjs/themes/prism.css
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
Error: PostCSS plugin postcss-flexbugs-fixes requires PostCSS 8.
Migration guide for end-users:
https://github.com/postcss/postcss/wiki/PostCSS-8-for-end-users
...(省略)

```

## 3. 古いnode modulesを確認してみた.

```sh
$ npm outdated

Package                          Current   Wanted  Latest  Location
@emotion/core                     10.1.1   10.1.1  11.0.0  node_modules/@emotion/core
@emotion/styled                  10.0.27  10.0.27  11.3.0  node_modules/@emotion/styled
chalk                              3.0.0    3.0.0   4.1.1  node_modules/chalk
contentful-import                 7.9.42   7.9.42  8.1.13  node_modules/contentful-import
eslint                             6.8.0    6.8.0  7.27.0  node_modules/eslint
eslint-config-gatsby-standard      2.2.0    2.2.0   3.0.2  node_modules/eslint-config-gatsby-standard
gatsby-image                      2.11.0   2.11.0   3.6.0  node_modules/gatsby-image
gatsby-plugin-catch-links         2.10.0   2.10.0   3.6.0  node_modules/gatsby-plugin-catch-links
gatsby-plugin-emotion              4.5.0    4.5.0   6.6.0  node_modules/gatsby-plugin-emotion
gatsby-plugin-google-analytics    2.11.0   2.11.0   3.6.0  node_modules/gatsby-plugin-google-analytics
gatsby-plugin-instagram-embed      2.1.0    2.1.0   3.0.0  node_modules/gatsby-plugin-instagram-embed
gatsby-plugin-manifest            2.12.1   2.12.1   3.6.0  node_modules/gatsby-plugin-manifest
gatsby-plugin-netlify             2.11.1   2.11.1   3.6.1  node_modules/gatsby-plugin-netlify
gatsby-plugin-offline             3.10.2   3.10.2   4.6.0  node_modules/gatsby-plugin-offline
gatsby-plugin-react-helmet        3.10.0   3.10.0   4.6.0  node_modules/gatsby-plugin-react-helmet
gatsby-plugin-schema-snapshot      1.7.0    1.7.0   2.6.0  node_modules/gatsby-plugin-schema-snapshot
gatsby-plugin-sitemap             2.12.0   2.12.0   4.2.0  node_modules/gatsby-plugin-sitemap
gatsby-plugin-theme-ui             0.3.5    0.3.5   0.9.1  node_modules/gatsby-plugin-theme-ui
gatsby-remark-autolink-headers    2.11.0   2.11.0   4.3.0  node_modules/gatsby-remark-autolink-headers
gatsby-remark-images-contentful   2.10.0   2.10.0   4.3.0  node_modules/gatsby-remark-images-contentful
gatsby-remark-prismjs             3.13.0   3.13.0   5.3.0  node_modules/gatsby-remark-prismjs
gatsby-source-contentful          2.3.56   2.3.56   5.6.1  node_modules/gatsby-source-contentful
gatsby-transformer-remark         2.16.1   2.16.1   4.3.0  node_modules/gatsby-transformer-remark
inquirer                           7.3.3    7.3.3   8.1.0  node_modules/inquirer
prettier                          1.19.1   1.19.1   2.3.0  node_modules/prettier
react                            16.14.0  16.14.0  17.0.2  node_modules/react
react-dom                        16.14.0  16.14.0  17.0.2  node_modules/react-dom
react-helmet                       5.2.1    5.2.1   6.1.0  node_modules/react-helmet
stylelint-config-standard         19.0.0   19.0.0  22.0.0  node_modules/stylelint-config-standard
theme-ui                           0.3.5    0.3.5   0.9.1  node_modules/theme-ui
```

おいおい、結構あるな:thinking:

## 4. 古いnode modulesを最新にしてみた.
上で確認した古いnode modulesをすべて最新バージョンに上げます.

```sh
$ npm install @emotion/styled@latest --legacy-peer-deps
$ npm install chalk@latest --legacy-peer-deps
$ npm install contentful-import@latest --legacy-peer-deps
$ npm install eslint@latest --legacy-peer-deps
$ npm install eslint-config-gatsby-standard@latest --legacy-peer-deps
$ npm install gatsby-image@latest --legacy-peer-deps
$ npm install gatsby-plugin-catch-links@latest --legacy-peer-deps
$ npm install gatsby-plugin-emotion@latest --legacy-peer-deps
$ npm install gatsby-plugin-google-analytics@latest --legacy-peer-deps
$ npm install gatsby-plugin-instagram-embed@latest --legacy-peer-deps
$ npm install gatsby-plugin-manifest@latest --legacy-peer-deps
$ npm install gatsby-plugin-netlify@latest --legacy-peer-deps
$ npm install gatsby-plugin-offline@latest --legacy-peer-deps
$ npm install gatsby-plugin-react-helmet@latest --legacy-peer-deps
$ npm install gatsby-plugin-schema-snapshot@latest --legacy-peer-deps
$ npm install gatsby-plugin-sitemap@latest --legacy-peer-deps
$ npm install gatsby-plugin-theme-ui@latest --legacy-peer-deps
$ npm install gatsby-remark-autolink-headers@latest --legacy-peer-deps
$ npm install gatsby-remark-images-contentful@latest --legacy-peer-deps
$ npm install gatsby-remark-prismjs@latest --legacy-peer-deps
$ npm install gatsby-source-contentful@latest --legacy-peer-deps
$ npm install gatsby-transformer-remark@latest --legacy-peer-deps
$ npm install inquirer@latest --legacy-peer-deps
$ npm install prettier@latest --legacy-peer-deps
$ npm install react@latest --legacy-peer-deps
$ npm install react-dom@latest --legacy-peer-deps
$ npm install react-helmet@latest --legacy-peer-deps
$ npm install stylelint-config-standard@latest --legacy-peer-deps
$ npm install theme-ui@latest --legacy-peer-deps
```

## 5. 一旦buildできるか試してみた.

**案の定、怒られる...。**

```sh
$ gatsby develop

success open and validate gatsby-configs - 0.077s
warn Plugin gatsby-remark-images-anywhere is not compatible with your gatsby version 3.6.2 - It requires gatsby@^2.12.0

 ERROR #11331  PLUGIN

Invalid plugin options for "gatsby-plugin-google-analytics":

- "trackingId" is required

not finished load plugins - 2.132s
```

あれ、**gatsby-plugin-google-analytics**の**trackingId**は、本番環境でしか環境変数を流し込んでないから開発で怒られている模様。いままではそれでもビルドできたのに、バージョン上がって必須になったのかな:thinking:


# 6. 開発の環境変数にtrackingIdを追加して開発ビルド時に参照できるようにする.

プロジェクトルートに、.envファイル作成.

```.env.development
GOOGLE_ANALYTICS=UA-000000000-0
```

gatsby-config.jsで.envを読み込む.

```js:gatsby-config.js
require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`,
})

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-google-analytics`,
      options: {
        trackingId: process.env.GOOGLE_ANALYTICS,
      },
    },
  ]
}
```

## 7. 一旦buildできるか試してみた.

**案の定、怒られる...。**

```sh
$ gatsby develop

 ERROR #11321  PLUGIN

"gatsby-node.js" threw an error while running the createPages lifecycle:

Interface field ContentfulReference.contentful_id expects type String! but ContentfulAsset.contentful_id is type String.

Interface field ContentfulReference.contentful_id expects type String! but ContentfulTag.contentful_id is type String.

Interface field ContentfulEntry.contentful_id expects type String! but ContentfulTag.contentful_id is type String.

Interface field ContentfulEntry.node_locale expects type String! but ContentfulTag.node_locale is type String.

Interface field ContentfulReference.contentful_id expects type String! but ContentfulPost.contentful_id is type String.

Interface field ContentfulEntry.contentful_id expects type String! but ContentfulPost.contentful_id is type String.

Interface field ContentfulEntry.node_locale expects type String! but ContentfulPost.node_locale is type String.

Interface field ContentfulReference.contentful_id expects type String! but ContentfulPage.contentful_id is type String.

Interface field ContentfulEntry.contentful_id expects type String! but ContentfulPage.contentful_id is type String.

Interface field ContentfulEntry.node_locale expects type String! but ContentfulPage.node_locale is type String.
```

ん？:thiking: 型のタイプヒンティングが違うのか？null許容してほしいのかな。

## 8. 上記で言われたタイプヒンティングでnullを許容する.

この辺の子たちだね。
`contentful_id: String` => `contentful_id: String!` にする。

**変更前**

```gql:root/src/gatsby/schema/schema.gql
type ContentfulTag implements Node @derivedTypes @dontInfer {
  title: String
  slug: String
  post: [ContentfulPost] @link(by: "id", from: "post___NODE")
  spaceId: String
  contentful_id: String
  createdAt: Date @dateformat
  updatedAt: Date @dateformat
  sys: ContentfulTagSys
  node_locale: String
}
```

**変更後**

```gql:root/src/gatsby/schema/schema.gql
type ContentfulTag implements Node @derivedTypes @dontInfer {
  title: String
  slug: String
  post: [ContentfulPost] @link(by: "id", from: "post___NODE")
  spaceId: String
  contentful_id: String!
  createdAt: Date @dateformat
  updatedAt: Date @dateformat
  sys: ContentfulTagSys
  node_locale: String
}
```

## 9. 一旦buildできるか試してみた.

**案の定、怒られる...。**

```sh
$ gatsby develop

 ERROR #11321  PLUGIN

"gatsby-node.js" threw an error while running the createPages lifecycle:

Interface field ContentfulEntry.node_locale expects type String! but ContentfulTag.node_locale is type String.

Interface field ContentfulEntry.node_locale expects type String! but ContentfulPost.node_locale is type String.

Interface field ContentfulEntry.node_locale expects type String! but ContentfulPage.node_locale is type String.
```

あ、さっきと同じ感じで型のタイプヒンティングが違いそう。

## 10. 上記で言われたタイプヒンティングでnullを許容する.

この辺の子たちだね。
`node_locale: String` => `node_locale: String!` にする。

**変更前**

```gql:root/src/gatsby/schema/schema.gql
type ContentfulTag implements Node @derivedTypes @dontInfer {
  title: String
  slug: String
  post: [ContentfulPost] @link(by: "id", from: "post___NODE")
  spaceId: String
  contentful_id: String!
  createdAt: Date @dateformat
  updatedAt: Date @dateformat
  sys: ContentfulTagSys
  node_locale: String
}
```

**変更後**

```gql:root/src/gatsby/schema/schema.gql
type ContentfulTag implements Node @derivedTypes @dontInfer {
  title: String
  slug: String
  post: [ContentfulPost] @link(by: "id", from: "post___NODE")
  spaceId: String
  contentful_id: String!
  createdAt: Date @dateformat
  updatedAt: Date @dateformat
  sys: ContentfulTagSys
  node_locale: String
}
```

## 11. 一旦buildできるか試してみた.

**案の定、怒られる...。**

```sh
$ gatsby develop

ERROR #85923  GRAPHQL

There was an error in your GraphQL query:

Cannot query field "fluid" on type "ContentfulAsset".

If you don't expect "fluid" to exist on the type "ContentfulAsset" it is most likely a typo.
However, if you expect "fluid" to exist there are a couple of solutions to common problems:

- If you added a new data source and/or changed something inside gatsby-node.js/gatsby-config.js, please try a restart of your development server
- The field might be accessible in another subfield, please try your query in GraphiQL and use the GraphiQL explorer to see which fields you can query and what shape they have
- You want to optionally use your field "fluid" and right now it is not used anywhere. Therefore Gatsby can't infer the type and add it to the GraphQL schema. A quick fix is to add
 at least one entry with that field ("dummy content")

It is recommended to explicitly type your GraphQL schema if you want to use optional fields. This way you don't have to add the mentioned "dummy content". Visit our docs to learn
how you can define the schema for "ContentfulAsset":
https://www.gatsbyjs.com/docs/reference/graphql-data-layer/schema-customization#creating-type-definitions

```

typoしてるだと？そんなはず、だってこれで動いていたんだよ:thinking:

## 12. あ、**gatsby-image**じゃなくて**gatsby-plugin-image**になったんですかい！

こいつだ！！

https://www.gatsbyjs.com/plugins/gatsby-source-contentful/#using-the-new-gatsby-image-plugin

そんなわけで、**gatsby-plugin-image**をインストールします。

```sh
$ npm install gatsby-plugin-image
```

## 13. 一旦buildできるか試してみた.

**動いたー！！！**

```sh
$ gatsby develop

success run page queries - 52.992s - 3/3 0.06/s
⠀
You can now view gatsby-starter-gcn in the browser.
⠀
  http://localhost:8000/
⠀
View GraphiQL, an in-browser IDE, to explore your site's data and schema
⠀
  http://localhost:8000/___graphql
⠀
Note that the development build is not optimized.
To create a production build, use gatsby build
```

# 14. バージョン確認

```sh
$ gatsby -v
Gatsby CLI version: 3.6.0
Gatsby version: 3.6.2
```

おお！v3に上がってますー！サイトも動いてますー！素敵:smile:

# おわりに
1つずつエラーを眺めながらポチポチしてバージョン対応しました。
詳細は時間があるときにはちゃんと調べようと思います。
取り急ぎ、対応しないとで困っている方の参考になれば幸いです。
それでは！