Gatsby初試啼聲


Gatsby初試啼聲

文章目錄

  1. Gatsby初試啼聲
  2. 利用react-bootstrap打造React風格頁面
  3. 了解Gatsby中GraphQL如何運作
  4. Gatsby GraphQL讀取JSON
  5. 在Gatsby GraphQL中組合出完美資料
  6. Gatsby程序化產生頁面
  7. 上線個人頁面到Netlify+啟動Netlify CMS

在開始之前:
本篇文章已預設讀者已經對React有基本的了解,如果對React還不熟悉的朋友,可以先參考Reactjs官網文檔以及新手教學了解React之後再回來使用Gatsby更加得心應手。

什麼是Gatsby?為什麼要使用Gatsby?

Gatsby是一個建構在React上的靜態網站生成器。他原本標榜他是一個建構在React上的靜態網站生成器,但是現在經過幾年的發展,他也形成了自己的生態圈,加入了graphql、也有各式各樣的套件。
那為什麼要使用Gatsby?還是回到會使用靜態網站產生器的理由一個字:「快」。如果我們考慮靜態網站生成器的好處,不管使用哪種語言都是一樣的-靜態網站生成器可以快速幫助我們產生一個基本的框架,省去我們建置的一些麻煩。我們之後在這個基礎的框架上進行修改就可以了,這也是我們這一系列文章要做的事情。其實靜態網站產生器很多(比較知名的例如:JekyllHugoHexo),想要用哪一套其實就看個人偏好,不過我們這裡就專注在React上。

安裝Gatsby

Gatsby建立一個模板很快,如果不想要搞得太複雜,幾行指令就可以建立起一個簡單的模板。

安裝Gatsby CLI

npm install -g gatsby-cli

建立新網站

gatsby new gatsby-site

執行開發用伺服器

cd gatsby-site
gatsby develop

執行完這一步就可以看到我們的模板已經在運行了。


不過在這個系列文章裡面我們會使用另外一個進階的模板gatsby-personal-starter-blog,裡面包含有一個主頁面跟一個部落格。這裡提一下這個模板自帶typographyjs跟netlifyCMS,我個人不是特別喜歡typographyjs,所以後續會使用最普遍的bootstrap React版進行樣式調整。而netlifyCMS則是賦予Gatsby部落格功能的套件,後續的文章也會提到。

使用模板建立網站

gatsby new my-blog-starter https://github.com/thomaswang/gatsby-personal-starter-blog
cd my-blog-starter
gatsby develop
個人頁面
個人部落格

事實上如果沒有想要做什麼修改的話,這樣的網站已經可以上線了!我們可以透過以下的指令產生production build:

gatsby build

另外也可以在本地測試production的效果

gatsby serve

觀察模板結構

src/page/index.js

import React from "react"
import { Link } from "gatsby"

import Layout from "../components/layout"
import SEO from "../components/seo"
import Button from "../components/button"

class IndexPage extends React.Component {
  render() {
    const siteTitle = "Gatsby Starter Personal Website"

    return (
      <Layout location={this.props.location} title={siteTitle}>
        <SEO
          title="Home"
          keywords={[`blog`, `gatsby`, `javascript`, `react`]}
        />
        <img style={{ margin: 0 }} src="./GatsbyScene.svg" alt="Gatsby Scene" />
        <h1>
          Hey people{" "}
          <span role="img" aria-label="wave emoji">
            👋
          </span>
        </h1>
        <p>Welcome to your new Gatsby website. You are on your home page.</p>
        <p>
          This starter comes out of the box with styled components and Gatsby's
          default starter blog running on Netlify CMS.
        </p>
        <p>Now go build something great!</p>
        <Link to="/blog/">
          <Button marginTop="35px">Go to Blog</Button>
        </Link>
      </Layout>
    )
  }
}

export default IndexPage

這裡對於React而言很簡單,就是一個普通的Component。值得一提的是超連結是使用Gatsby裡面自帶的套件,而不是常見的react router。據官方文件說,這個套件已經對跳轉頁面進行了優化,但是只能使用於內部的連結。

src/page/blog.js

import React from "react"
import { Link, graphql } from "gatsby"

import Bio from "../components/bio"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { rhythm } from "../utils/typography"
import Button from "../components/button"

class Blog extends React.Component {
  render() {
    const { data } = this.props
    const siteTitle = data.site.siteMetadata.title
    const posts = data.allMdx.edges

    return (
      <Layout location={this.props.location} title={siteTitle}>
        <SEO title="All posts" />
        <Bio />
        <div style={{ margin: "20px 0 40px" }}>
          {posts.map(({ node }) => {
            const title = node.frontmatter.title || node.fields.slug
            return (
              <div key={node.fields.slug}>
                <h3
                  style={{
                    marginBottom: rhythm(1 / 4),
                  }}
                >
                  <Link
                    style={{ boxShadow: `none` }}
                    to={`blog${node.fields.slug}`}
                  >
                    {title}
                  </Link>
                </h3>
                <small>{node.frontmatter.date}</small>
                <p
                  dangerouslySetInnerHTML={{
                    __html: node.frontmatter.description || node.excerpt,
                  }}
                />
              </div>
            )
          })}
        </div>
        <Link to="/">
          <Button marginTop="85px">Go Home</Button>
        </Link>
      </Layout>
    )
  }
}

export default Blog

export const pageQuery = graphql`
  query {
    site {
      siteMetadata {
        title
      }
    }
    allMdx(sort: { fields: [frontmatter___date], order: DESC }) {
      edges {
        node {
          excerpt
          fields {
            slug
          }
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            title
            description
          }
        }
      }
    }
  }
`

另外一個主要頁面就是部落格了。這裡稍微開始有點不一樣,除了上面提到原本自帶的使用的樣式系統typographyjs,為了讀取以makrdown撰寫的部落格文章,還有加入graphql讀取資料。有兩種讀取資料的叫法,page query以及StaticQuery,後面提到graphql時會再更深入。

gatsby-config.js

module.exports = {
  siteMetadata: {
    // edit below
    title: `Gatsby Starter Personal Blog`,
    author: `Kyle Matthews`,
    description: `A starter personal blog with styled components, dark mode, and Netlify CMS.`,
    siteUrl: `https://gatsby-starter-blog-demo.netlify.com/`,
    social: {
      twitter: `kylemathews`,
    },
  },
  plugins: [
    `gatsby-plugin-netlify-cms`,
    `gatsby-plugin-styled-components`,
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    `gatsby-plugin-offline`,
    `gatsby-plugin-react-helmet`,
    `gatsby-plugin-feed-mdx`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `${__dirname}/content/blog`,
        name: `blog`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `${__dirname}/content/assets`,
        name: `assets`,
      },
    },
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        extensions: [".mdx", ".md"],
        gatsbyRemarkPlugins: [
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 590,
            },
          },
          {
            resolve: `gatsby-remark-responsive-iframe`,
            options: {
              wrapperStyle: `margin-bottom: 1.0725rem`,
            },
          },
          {
            resolve: `gatsby-remark-vscode`,
          },
          {
            resolve: `gatsby-remark-copy-linked-files`,
          },
          {
            resolve: `gatsby-remark-smartypants`,
          },
        ],
      },
    },
    {
      resolve: `gatsby-plugin-google-analytics`,
      options: {
        // edit below
        // trackingId: `ADD YOUR TRACKING ID HERE`,
      },
    },
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `Gatsby Starter Blog`,
        short_name: `GatsbyJS`,
        start_url: `/`,
        background_color: `#ffffff`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        // edit below
        icon: `content/assets/gatsby-icon.png`,
      },
    },
    {
      resolve: `gatsby-plugin-typography`,
      options: {
        pathToConfigModule: `src/utils/typography`,
      },
    },
  ],
}

在這裡可以加上我們自己想要讓graphql讀取的資料,所以才有siteMetadata的區域。除了讀取資料外已經安裝許多plugin,像是讀取部落格用的資料就是透過gatsby-source-filesystem來讀取並匯入至graphql中,而gatsby-plugin-mdx則是轉化markdown檔案為部落格文章的html。

其他部份比較值得一提有gatsby-node.js,裡面的onCreateNodecreatePages是動態產生部落格文章的關鍵,但是因為我們這次的焦點在於更改為個人頁面,所以就不會去更改他了。

後續規劃

更動項目

在系列文章裡面,我會做一個比較傳統形式的個人頁面,也就是除了主頁面外,還會有作品集、關於我&聯絡方式的頁面。預計會做以下幾件事情:

  1. 調整Layout
  2. 加上作品集、關於我頁面
  3. 調整樣式為bootstrap風格

上線說明

最後,一個階段大致完成後,我會使用netlify將頁面上線,並且設定netlifyCMS,這樣就可以使用CMS來寫部落格了。

本篇文章的程式碼的實作可以在github repo1-installing-gatsby-starter找到

參考資源

#React #gatsby





現在很多網站都不需要複雜的結構,使用靜態網站呈現就可以了。可以產生靜態網站的框架有很多,這次介紹使用React系列的Gatsby來快速製作一個個人頁面。

留言討論