Closed50

GatsbyJSのチュートリアルを読む

shotakahashotakaha

目次

https://www.gatsbyjs.com/docs/tutorial/

  1. Set Up Your Development Environment
  2. Get to Know Gatsby Building Blocks
  3. Introduction to Styling in Gatsby
  4. Creating Nested Layout Components
  5. Data in Gatsby
  6. Source Plugins
  7. Transformer plugins
  8. Programmatically create pages from data
  9. Preparing a Site to Go Live
shotakahashotakaha

https://www.gatsbyjs.com/docs/tutorial/part-zero/

必要な持ち物を確認

  • Homebrewのインストール ✅
  • Xcode Command Line Toolsのインストール ✅
  • Node.jsのインストール ✅
  • Gitのインストール ✅
  • Gatsby CLI(本体)のインストール ✅
  • Visual Studio Code(エディタ)のインストール ✅
  • Prettier VSCode Plugin(コードフォーマッタ)のインストール ✅

全部持ってた😊

$ brew --version
Homebrew 3.0.0

$ node --version
v15.8.0

$ git --version
git version 2.30.0

$ gatsby --version
Gatsby CLI version: 2.19.1

$ code --version
1.52.1
shotakahashotakaha

https://www.gatsbyjs.com/docs/tutorial/part-zero/#create-a-gatsby-site

Gatsby site を作成する

  1. チュートリアル用のディレクトリ(~/sandbox/gatsby-tutorial/)を作成した
Terminal.app
$ mkdir -p ~/sandbox/gatsby-tutorial/
$ cd ~/sandbox/tutorial/
  1. ページに書いてあるコマンドをコピペして実行した
  2. スターターのGitHub URLを指定して、ウェブサイト(hello-world)を新規作成(new)している
Terminal.app
$ gatsby new hello-world https://github.com/gatsbyjs/gatsby-starter-hello-world
gatsby newを実行した結果
info Creating new site from git: https://github.com/gatsbyjs/gatsby-starter-hello-world.git

Cloning into 'hello-world'...
success Created starter directory layout

info Installing packages...
added 1891 packages, and audited 1892 packages in 26s
6 vulnerabilities (1 low, 5 high)

info Initialising git in hello-world
Your new Gatsby site has been successfully bootstrapped. Start developing it by running:

  cd hello-world
  gatsby develop
  1. 出力結果の最後に書いてるとおりにコマンドを実行した
Terminal.app
$ cd hello-world
$ gatsby develop
gatsby developを実行した結果
Terminal.app
$ gatsby develop
success open and validate gatsby-configs - 0.014s
success load plugins - 0.070s
success onPreInit - 0.025s
success initialize cache - 0.009s
success copy gatsby files - 0.073s
success onPreBootstrap - 0.018s
success createSchemaCustomization - 0.003s
success Checking for changed pages - 0.002s
success source and transform nodes - 0.031s
success building schema - 0.169s
info Total nodes: 18, SitePage nodes: 1 (use --verbose for breakdown)
success createPages - 0.004s
success Checking for changed pages - 0.001s
success createPagesStatefully - 0.035s
success update schema - 0.020s
success write out redirect data - 0.002s
success onPostBootstrap - 0.002s
info bootstrap finished - 3.701s
success onPreExtractQueries - 0.003s
success extract queries from components - 0.082s
success write out requires - 0.007s
success run page queries - 0.027s - 2/2 74.16/s
⠀
You can now view gatsby-starter-hello-world 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
⠀
success Building development bundle - 4.794s
  1. ここでも最後に書いてあるとおりhttp://localhost:8000/をブラウザで開いて、表示内容を確認した
  2. シンプルにHello World!と表示された

まとめ

  1. gatsby newで新規にウェブサイトを作成できる
  2. gatsby developでローカルにサーバを立て、内容を確認できる(ホットリロードに対応している)

あっという間にウェブサイトを作成することができた。
ひとつのコマンドを実行したら、次のコマンドを教えてくれるので忘れっぽくても大丈夫。

shotakahashotakaha

npm update

1.6 vulnerabilitiesと表示されるのが気になった
2. 古くなっているパッケージを npm outdatedで確認した
3.npm update(省略形 : npm up)して最新版にしておく(チュートリアルの操作には影響なかった)

npm outdated
$ npm outdated
Package    Current   Wanted  Latest  Location                Depended by
gatsby      2.26.1   2.32.3  2.32.3  node_modules/gatsby     tutorial-part-four
react      16.13.1  16.14.0  17.0.1  node_modules/react      tutorial-part-four
react-dom  16.13.1  16.14.0  17.0.1  node_modules/react-dom  tutorial-part-four
npm update
$ npm up

added 375 packages, removed 240 packages, changed 322 packages, and audited 2027 packages in 37s

149 packages are looking for funding

found 0 vulnerabilities
shotakahashotakaha

https://www.gatsbyjs.com/docs/tutorial/part-one/

  1. src/pages/index.jsを編集してlocalhost:8000/index.htmlを更新できた
  2. JSXというJavaScriptの中にHTMLを記述する(HTML-in-JS)方法で書くことがベースになっている
  3. ブラウザはJSXを直接理解することができない。その辺りをいい感じにやるのがGatsbyのしごと
shotakahashotakaha

https://www.gatsbyjs.com/docs/tutorial/part-two/

スタイルの適用

  1. gatsby-browser.jsを使って全体用CSSを読み込む方法 ← これまでCSSの知識をそのまま使えるので、とっつき始めるには便利
  2. Component-scoped CSSCSS Modules or CSS-in-JS)を使う方法 ← これからGatsbyにハマる人には《推奨》みたい
  3. このチュートリアルではCSS Modulesの使い方の説明
shotakahashotakaha

Globalスタイル

  1. /src/styles/global.cssを作成する(ファイル名は好きなようにする)
  2. /gatsby-browser.jsを作成し、上のglobal.cssimportする
shotakahashotakaha

import or require

Note: Both CommonJS (require) and ES Module (import) syntax work here. If you’re not sure which to choose, import is usually a good default. When working with files that are only run in a Node.js environment however (like gatsby-node.js), require will need to be used.

こういう注釈があるのはありがたい。
基本的にimportを使えばよいことが分かった。

shotakahashotakaha

CSS Modules

  1. /src/components/container.js/src/components/container.module.cssを作成した
  2. Gatsbyでは)CSS Modulesの拡張子は.module.cssにする
  3. container.jsJSXで書く
  4. .module.cssは普通のCSSで書く
  5. container.jsの中でcontainer.module.cssを読み込むことで使えるようになる
  6. JSXが展開されるときにCSS ModulesのファイルパスをベースにCSSのクラス名が自動で生成されるから、クラス名が重複する心配をしなくてよい。(逆に、クラス名を見ればどのファイルを確認すればよいかが分かる)
shotakahashotakaha

デバッグ

import React from "react"
import styles from "./about-css-modules.module.css"
import Container from "../components/container"

console.log(styles)
  1. 新しくモジュールを読み込んだ場合(import styles from "./about-css-modules.module.css"
  2. きちんと読み込めてるかconsole.log(styles)を使って確認すればよい
shotakahashotakaha

https://www.gatsbyjs.com/docs/tutorial/part-three/

レイアウトコンポーネント

  1. 全体的なサイトのデザインには、レイアウトコンポーネントを使う
  2. ナビゲーションやフッタなどの全ページを通して共通なコンポーネントをひとつにまとめることができる
  3. /src/components/layout.js(ファイル名は何でもいいはず)を作成して、ページコンポーネント(/src/pages/*.js)のファイルでimportする
shotakahashotakaha

ここまでのまとめ

  1. ここまで(チュートリアル3)で、いちおうGatsbyの基本的な使い方を俯瞰した
  2. ページを作成する場合はページコンポーネント(/src/pages/*.js)にJSXで書けばよい
  3. 共通部分はコンポーネントとしてまとめればよい(/src/components/*.js
  4. スタイルはCSS Modulesを使えばよい(/src/components/*.module.css
  5. サイト全体の設計はレイアウトコンポーネントを使えばよい(/src/components/layout.js

で、次は

  1. ページを作成する場合に、毎回JSXファイルを作成するのはちょっと手間(JSXを生で書くのは大変)
  2. Markdownで書いたものを読み込むことができるとハッピー😊
shotakahashotakaha

https://www.gatsbyjs.com/docs/tutorial/part-four/

データのクエリ(呼び出し方)

  1. page query : ページコンポーネントの中で使えるGraphQLクエリ
  2. StaticQuery : ページコンポーネント以外で使えるGrraphQLクエリ

他にもnodecreatePagesを使うことでunstructured dataを使ってページを生成することができるらしいけど、これはまた調べる。
GatsbyではGraphQLを仲介することで、元データがどんな形式であってもプラグインで対応できるようになる。

shotakahashotakaha

https://www.gatsbyjs.com/docs/tutorial/part-five/

ソースの指定

  1. gatsby-source-filesystemプラグインをインストールする
  2. gatsby-config.jsにプラグインを追加、データ源のパスを指定する
  3. ローカルのGraphiQLhttp://localhost:8000/___graphql)にアクセスしてクエリを作成する
  4. allFilesとかfilesを選んで、いろいろ欲しい情報をぽちぽち選択すればOK
  5. GraphiQLの使い方は簡単そうなので、使っていたら分かりそう
shotakahashotakaha

gatsby-config.jsを編集したあとはリスタート

warn develop process needs to be restarted to apply the changes to gatsby-config.js
  1. gatsby-config.jsを編集するとgatsby developを実行しているターミナルに上記のwarningが出力される
  2. 書いてある内容に従ってgatsby developをリスタートさせることで、変更した設定が反映される
shotakahashotakaha
  • gatsby-config.jsを編集したあとwarningが出るときと出ないときがある。原因はよく分かってない。
  • リスタートが必要な時は、ブラウザにポップアップがでる。そのポップアップからgatsby-developをリスタートすることもできる(わざわざターミナルに打ち込まなくてもいいので便利)
shotakahashotakaha

https://www.gatsbyjs.com/docs/tutorial/part-six/

Markdownファイルの読み込み

  1. gatsby-transformer-remarkプラグインをインストール
  2. gatsby-config.jsにプラグインを追加
  3. src/pages/*.mdを作成する
  4. GraphiQLallMarkdownRemark / markdownRemark を使ってクエリを作成する
  5. src/pages/index.jsにクエリを埋め込むことでトップページにMarkdownファイルの一覧を表示することができた

  • gatsby-source-filesystemといろいろなtransformerプラグインを使うことで、ありとあらゆるデータをページに変換することができる
shotakahashotakaha

https://www.gatsbyjs.com/docs/tutorial/part-seven/

ページを自動的に生成する方法

  1. ページ(記事ページとか)のpath or slugを作成する(このチュートリアルでは以降slugを使う)
  2. ページを作成する

ページを作成するためのGatsby API

  1. onCreateNode
  2. createPages

編集する設定ファイル

  1. gatsby-node.js
shotakahashotakaha

onCreateNode

  1. 新しいノードが作成されたり、更新されたりしたときにGatsbyがコールするAPI
  2. MarkdownRemarkノードだけにフィルタする
shotakahashotakaha
gatsby-node.js
exports.onCreateNode = ({ node }) => {
  console.log(`Node created of type "${node.internal.type}"`)
}
出力結果
Node created of type "SitePage"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "SitePlugin"
Node created of type "Site"
Node created of type "SiteBuildMetadata"
Node created of type "Directory"
Node created of type "Directory"
Node created of type "Directory"
Node created of type "Directory"
Node created of type "File"
Node created of type "File"
Node created of type "File"
Node created of type "File"
Node created of type "File"
Node created of type "MarkdownRemark"
Node created of type "File"
Node created of type "MarkdownRemark"
Node created of type "File"
shotakahashotakaha
gatsby-node.js
exports.onCreateNode = ({ node, getNode }) => {
  if (node.internal.type === `MarkdownRemark`) {
    console.log(`Node created of type "${node.internal.type}"`)
    const fileNode = getNode(node.parent)
    console.log(`\n`, fileNode.relativePath)
  }
}
  • このままだと何も起きないのでpandas-and-bananas.mdを適当に編集
出力結果
changed file at /Users/shotakaha/repos/sandbox/gatsby-tutorial/tutorial-part-four/src/pages/sweet-pandas-eating-sweets.md
Node created of type "MarkdownRemark"

 pages/sweet-pandas-eating-sweets.md
shotakahashotakaha
gatsby-node.js
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode }) => {
  if (node.internal.type === `MarkdownRemark`) {
    console.log(`node.internal.type: "${node.internal.type}"`)
    const fileNode = getNode(node.parent)
    console.log(`fileNode.relativePath:`, fileNode.relativePath)
    console.log(
      `createFilePath:`,
      createFilePath({ node, getNode, basePath: `pages` })
    )
  }
}
出力結果
node.internal.type: "MarkdownRemark"
fileNode.relativePath: pages/pandas-and-bananas.md
createFilePath: /pandas-and-bananas/

node.internal.type: "MarkdownRemark"
fileNode.relativePath: pages/sweet-pandas-eating-sweets.md
createFilePath: /sweet-pandas-eating-sweets/
  • .mdのファイル名 → スラッグ ができてる
shotakahashotakaha

スラッグの作り方

  1. /src/pages/*.mdのファイル名をスラッグとして使う
  2. 具体的に/src/pages/pandas-and-bananas.md → localhost:8000/pandas-and-bananas/ にする
  3. ファイル名を取得するためにgetNode()を使う

・・・とりあえずコピペして動かしてから、いろいろ考えよ

shotakahashotakaha
gatsby-node.js
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    console.log(`node.internal.type: "${node.internal.type}"`)
    const fileNode = getNode(node.parent)
    console.log(`fileNode.relativePath:`, fileNode.relativePath)
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    console.log(`slug:`, slug)
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}
  • gastsby developをリスタート
  • http://localhost:8000/___graphqlをブラウザで開き、チュートリアルにあるクエリをコピペして実行
出力結果
{
  "data": {
    "allMarkdownRemark": {
      "edges": [
        {
          "node": {
            "fields": {
              "slug": "/sweet-pandas-eating-sweets/"
            }
          }
        },
        {
          "node": {
            "fields": {
              "slug": "/pandas-and-bananas/"
            }
          }
        }
      ]
    }
  },
  "extensions": {}
}
  • slugが追加されていることが確認できた
shotakahashotakaha
  • 別の要素をベースにスラッグを生成したい場合にも使えそう
  • 別の要素:ノードのIDを使う/日付を使う、など
shotakahashotakaha

ここまででできたこと

  1. *.mdのファイル名をベースにスラッグを作成できた
  2. スラッグをGraphQLでクエリできるようになった

まだできていないこと

  1. ページの生成
shotakahashotakaha

ページテンプレートコンポーネントの作成

  1. src/templates/blog-post.jsを作成する
  2. レイアウトコンポーネント(src/component/layout.js)をimportする
  3. 単一の.mdに対してGraphQLクエリを発行する
  4. 戻ってくる値を、表示したい箇所に配置する
shotakahashotakaha

最終的なgatsby-node.js

  • チュートリアルに乗っているものをコピペして、ちゃんと動くことが確認できた
  • 内容についてはそのうちちゃんと読んで理解する
チュートリアルのコピペ
gatsby-node.js
const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const result = await graphql(`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `)

  result.data.allMarkdownRemark.edges.forEach(({ node }) => {
    createPage({
      path: node.fields.slug,
      component: path.resolve(`./src/templates/blog-post.js`),
      context: {
        // Data passed to context is available
        // in page queries as GraphQL variables.
        slug: node.fields.slug,
      },
    })
  })
}
shotakahashotakaha

サブディレクトリもOK

  1. src/pages/2021/pandas-and-bananas.mdを作成(pandas-and-bananas.mdをコピー)
  2. localhost:8000/2021/pandas-and-bananas/に表示できることを確認
  3. gatsyb-config.jsgatsby-node.jsの変更はいらなかった
shotakahashotakaha

トップページを修正

  1. src/pages/index.jsを修正して、各記事へのリンクを追加する
  2. slugGraphQLでコールできるようにしておくと、こういうところでも使える
shotakahashotakaha

ここまでのまとめ

  1. Gatsbyで新規サイトを作成した(gatsby new
  2. ページやコンポーネントを作成した(src/pages/*.js / src/components/js
  3. スタイルコンポーネントを作成した(src/components/*.module.css
  4. sourcetransformerプラグインを追加した(gatsby-config.js
  5. GraphQLクエリを使ってページを作成した(src/pages/*.md
  6. ファイル名を使って自動でページを作成した(gatsby-node.js

これでチュートリアルは(ほぼ)完了🎉

shotakahashotakaha

PWA対策のために追加するとよいプラグイン

  1. gatsby-plugin-manifest
  2. gatsby-plugin-offline
  3. gatsby-plugin-react-helmet, react-helmet
shotakahashotakaha

https://www.gatsbyjs.com/docs/themes/what-are-gatsby-themes/

Gatsby Theme

  1. gatsby-starterを使う方法
  2. gatsby-themesを使う方法
  3. gatsby-themesはnpmパッケージとして提供されている
  4. 1つのウェブサイトで複数のテーマ(npmパッケージ)を導入することができる
  5. テーマによって機能が違うけど、あの機能とこの機能を合わせて使うこともできる
shotakahashotakaha
  • チュートリアルを読んでみて、なんだかできそうな気がしてきた
  • とりあえずよさげなテーマを探してみた
  • これ使ってみようかな

サンプルサイト
https://gatsby-theme-forty.netlify.app/

リポジトリ
https://github.com/codebushi/gatsby-theme-forty

shotakahashotakaha

できた!😊

  1. テーマのリポジトリを指定してgatsby newした
  2. gatsby newすると勝手にGitリポジトリにしてくれる
  3. src/pages/*.jssrc/components/*.jsを直接編集
  4. あれこれ編集し、ひと段落したところで自分のGitLabpushした
  5. 下記のCI設定を.gitlab-ci.ymlにコピペして、GitLab Pagesが自動生成&確認できるようにした

https://gitlab.com/pages/gatsby

このスクラップは2021/02/09にクローズされました