說來巧得不行,前兩天正好買了本《唐詩三百首》附贈了一個電子書《了不得的蓋茨比》,我心想如今淘寶賣書的都開始送編程書了咋呢?😄,結果人家是本小說,雖然我沒讀過,可是好像還頗有名。不過不要緊,做爲一名前端 Coder,沒讀過《了不得的蓋茨比》沒關係,可是 《靜態站領域 NB 的 Gatsby》仍是應該瞭解一下的。css
首先,我得認可有點標題黨了,由於這個博客並不能算是炫酷屌炸天,可是確實是花了不少心思,從配色到佈局到動畫效果到適配,都還挺用心的;html
其次,若是又以爲不錯的,我也開源出來了,博客架子源碼地址:Gatsby-Animate-Blog;前端
最後,我想說一下爲啥選擇 Gatsby,有兩點緣由。第一,邊寫邊學系列,我確實沒用過 Gatsby,可是做爲一個 Reacter,它的大名仍是如雷貫耳的,我的比較擅長使用 Next.js,其實博客徹底可使用 Next.js 搭建,不過 React.js 官網推薦靜態站的開發使用 Gatsby,必定有它的道理,所以,做爲開發者的門面 —— 我的博客,我決定嘗試使用 Gatsby 來進行開發。由於是邊寫邊學,因此,裏面會盡量多的使用 Gatsby 特性來進行編寫。node
博客效果圖:react
博客地址git
本來是打算放在本身域名上的,結果備案沒經過,我也很無奈😭,暫時先用 now 提供的域名吧。github
就像上面說的,初識 Gatsby 我就是從 React 官網瞭解到的:web
官方正式介紹的三個快速搭建 React.js 的開源框架/腳手架:第一個,大名鼎鼎的 CRA(create-react-app);第二個,最流行的 React SSR 框架 —— Next.js;第三個,就是今天的主角,React Static Websites 的王者 —— Gatsby。npm
術業有專攻,既然官方一直標榜它轉爲靜態展開發而生,那麼今天就一塊兒來看看它在靜態站領域到底有多牛X~編程
npm install -g gatsby-cli
複製代碼
// 構建項目
# gatsby new gatsby-first-project
// 啓動
# cd gatsby-first-project && yarn develop
複製代碼
而後瀏覽器訪問http://localhost:8000
就能夠看到項目啓動,而 Gatsby 還爲咱們額外提供了一個http://localhost:8000/__graphql
查詢界面。
------
| -- .cache
| -- public
| -- src
| -- gatsby-browser.js // 客戶端相關配置
| -- gatsby-config.js // 基本配置文件
| -- gatsby-node.js // node 相關配置文件
| -- gatsby-ssr.js // 服務端渲染相關配置文件
| ... // 其餘文件
複製代碼
除了基本的目錄,就是路由頁約定和四個配置文件比較有意義,其中,gatsby-config 基本每一個項目都有的,而其餘三個若是沒有使用到就能夠刪除,文章最後會單獨介紹這幾個重要的配置文件。
這個概念跟 Next.js 基本如出一轍,Gatsby 不須要咱們配置路由相關內容,而是將pages
文件夾下的 js 文件名稱映射爲路由。
好比pages
目錄內容以下:
// pages
------
| -- index.js // 對應路徑 /
| -- about.js // 對應路徑 /about
| -- pageA.js // 對應路徑 /pageA
...
複製代碼
而後,Gatsby 還有一些默認的設置,好比一個404.js
對應着 404 Not Found 頁面。
// 啥都別說,先執行一下這行命令再說
cp .cache/default-html.js src/html.js
複製代碼
這個文件是用來幹啥的,Gatsby 的 html 結構就是經過這個 js 模板文件進行渲染的,好比咱們想要配置一些東西,或者提早加載一些腳本文件,就能夠重寫它。
咱們在文件裏新增一行<meta name="author" content="luffyZh" />
,查看一下:
能夠看到,重寫的內容生效了,就這麼簡單,其餘的就看你們本身項目需求了~
Gatsby 官方推薦使用 GraphQL 進行查詢,而且也配套了不少對應的插件~而且還提供了可視化查詢頁面。咱們運行項目後,web 端運行在8000端口的同時,http://localhost:8000/___graphql
地址運行着 GraphiQL 服務,具體的我懂的也不是特別多,你們能夠自行觀看~
好比,咱們看看 gatsby-config.js 裏面的內容:
module.exports = {
siteMetadata: {
title: `Gatsby Default Starter`,
description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
author: `@gatsbyjs`,
},
plugins: [
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `data`,
path: `${__dirname}/src/data`,
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-starter-default`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
display: `minimal-ui`,
icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
},
},
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// `gatsby-plugin-offline`,
],
}
複製代碼
其中配置了站點數據,以及各類插件的配置,而後咱們在 GraphiQL 服務裏進行查詢:
能夠看到,結果出來了,而且這仍是動態更新的,好比咱們新添加一個 learnerData,再進行查詢:
能夠看到,也能查出來,固然,左側列表中全部的內容都是能夠進行查詢的,裏面包括整個項目各類資源配置詳細信息,具體的你們能夠去看官方文檔說明,這裏就很少贅述了,只講一點,在這裏查出來或者數據放在這裏確定是要用的,那麼應該怎麼用呢?下面就來介紹,如何在組件裏獲取對應數據。
咱們使用以下方式在頁面進行數據的獲取,使用內置的 graphql 查詢 API,在頁面組件定義查詢,以後查詢結果會經過屬性data
傳遞給組件,在組件就可使用該值,具體以下:
import React from 'react';
import { graphql } from 'gatsby'; // 這個是數據獲取的核心
export const query = graphql`
query PageData {
site {
siteMetadata {
title
description
author
}
}
}
`;
const QueryPage = ({ data }) => {
const { site: { siteMetadata, learnerData } } = data;
return <div>
<h1>siteMetaData:</h1>
<p>title: {siteMetadata.title}</p>
<p>description: {siteMetadata.description}</p>
<p>author: {siteMetadata.author}</p>
</div>
};
export default QueryPage;
複製代碼
注意,這種方式查詢的 data,只有在組件內部才能進行對象取值操做,而在外部就是一個對應 id。
與上面不一樣,上面是將查詢語句與組件分離的形式進行操做,而 StaticQuery 是 Gatsby 爲咱們封裝的組件,集數據查詢與獲取,使用以下:
import React from 'react';
import { StaticQuery, graphql } from 'gatsby';
const StaticQueryPage = () => (
<StaticQuery
query={graphql`
query StaticQueryPageData {
site {
siteMetadata {
title
description
author
}
}
}
`}
render={
data => {
const { site: { siteMetadata, learnerData } } = data;
return <div>
<h1>StaticQueryData</h1>
<h2>siteMetaData:</h2>
<p>title: {siteMetadata.title}</p>
<p>description: {siteMetadata.description}</p>
<p>author: {siteMetadata.author}</p>
</div>
}
}
/>
);
export default StaticQueryPage;
複製代碼
React 自從出了 Hooks 之後,不少人趨之若鶩,都慢慢的喜歡上了,不少插件也都配套出了 useXXX hook 的 API,這裏也是同樣,除了上面兩種方法,在頁面裏你還可使用useStaticQuery
來進行查詢,使用方式以下:
import React from "react";
import { useStaticQuery, graphql } from "gatsby";
export default () => {
const data = useStaticQuery(graphql`
query UseStaticQueryData {
site {
siteMetadata {
title,
description,
author
}
}
}
`);
const { site: { siteMetadata, learnerData } } = data;
return (
<div>
<h1>UseStaticQueryData</h1>
<h2>siteMetaData:</h2>
<p>title: {siteMetadata.title}</p>
<p>description: {siteMetadata.description}</p>
<p>author: {siteMetadata.author}</p>
</div>
)
}
複製代碼
這裏就只介紹上面幾個頁面組件級別的,若是是純前端基本夠用了,不過 Gatsby 還有更多高級用法,好比 node 端配置頁面等等。關於更多內容或者 Gatsby GraphQL 相關,Gatsby 專門有一個章節,叫作 why-gatsby-uses-graphql,你們能夠閱讀一下。
簡單使用下來發現,Gatsby 所謂的便捷即便由於他將本來手動作的或者本身組裝的各類需求輪子都在本身的社區搞成了插件,龐大的插件系統,即插即用是它便捷的緣由,所以,就來了解一下它的一些 API 以及幾個重要的插件。
第一個,基本全部框架都必備的,路由部分。Gatsby 的 Link 跟通常的前端路由基本一致,沒有太大區別,由於它只是對reach/router進行了包裝。。
<Link to='/pageA'>Link to pageA</Link> // 前端路由
<a href='/pageA'>A tag to pageA</a> // a 標籤跳轉
複製代碼
固然,既然作了封裝,Gatsby 的 Link 組件必定有它的獨到之處,好比:activeClassName
和activeStyle
,顧名思義,就是選中時的狀態,若是是通常框架,這個選中狀態可能須要咱們用額外的代碼去控制,在 Gatsby 使用這兩個類就能夠了。咱們用下段代碼看看效果:
// layout.css
.active {
color: red
}
// nav.js
<Link
to="/"
style={{ color: '#fff' }}
activeClassName="active"
>
Home
</Link>
/
<Link
to="/about/"
style={{ color: '#fff' }}
activeStyle={{ color: "#000", background: '#fff' }}
>
About
</Link>
複製代碼
哎呀,發現activeClassName
並無論用,爲啥呢?仔細看了一下,原來 Link 組件使用了 style 約定了 color 樣式,style 優先級要高,那麼有沒有其餘辦法呢?有,咱們看下段代碼:
<Link
to="/"
getProps={({ isCurrent }) => {
// the object returned here is passed to the
// anchor element's props
return {
style: {
color: isCurrent ? "red" : "#fff"
}
};
}}
>
Home
</Link>
複製代碼
嗯,關於 Link 還有更多好用的功能,就不一一介紹了,能夠去官方文檔去看 -> Gatsby Link
這個插件是 gatsby 被引用最多的插件,通常與其餘插件配合使用,好比 GraphQL 和 gatsby-node,用於設置項目的文件系統,而且還能夠設置多個。
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `data`,
path: `${__dirname}/src/data`,
},
},
}
複製代碼
好比,上面的代碼,我設置了兩個靜態文件系統,一個是 images,一個是 data,咱們能夠經過 GraphiQL 來進行查詢:
既然均可以查詢出來了,也就表示咱們能夠在代碼裏使用他們。下面就簡單的寫個頁面列出來全部的文系統靜態資源文件。
import React, { Fragment } from 'react';
import { graphql, useStaticQuery } from 'gatsby';
const List = () => {
const data = useStaticQuery(
graphql`
query ListQuery {
allFile {
edges {
node {
id
name
relativePath
publicURL
dir
}
}
}
}
`
);
const { allFile: { edges } } = data;
return (
<table border='1'>
<thead>
<tr>
<th>文件名</th>
<th>所屬目錄</th>
<th>預覽地址</th>
</tr>
</thead>
<tbody>
渲染文件列表
</tbody>
</table>
)
}
export default List;
複製代碼
能夠看到,確實很方便,正常來講這都是須要後臺進行大量的代碼工做的,而 Gatsby 只用一個簡易的插件配置再搭配上 GraphQL 語法查詢就能夠了,真香~其餘關於插件更多能夠去官網插件庫查看,該插件還有其餘高級功能,而且該插件也是不少插件的依賴~
Gatsby 支持咱們設置靜態文件引入,新建static
文件夾,裏面的文件會對應/filename
獲取,該文件夾在編譯時會拷貝一份到public
文件夾裏,同時看到上面代碼的應該也發現了,gatsby-source-filesystem
這個插件也會將文件夾下面的文件存放一份到/static
文件夾裏咱們能夠經過publicURL
字段使用 GraphQL 進行查詢。
import React from 'react';
const Image = () => (
<div>
<img alt='image' src='/gatsby-astronaut.png' />
</div>
);
export default Image;
複製代碼
Gatsby 官方本身說的:Gatsby 網站之因此快的部分緣由,很大程度上在於圖像的處理方法。
Gatsby 利用的是插件gatsby-plugin-sharp
和 GraphQL 配合的模式來完成圖像的加載。
官方特地強調了,
gatsby-image
並不能代替<img/>
標籤,具體使用仍是得看場合。
Gatsby-Image 須要幾個官方插件一塊兒使用,而本地圖片的加載依靠的就是上面介紹的gatsby-source-filesystem
。
yarn add gatsby-image gatsby-plugin-sharp gatsby-transformer-sharp gatsby-source-filesystem
複製代碼
接下來就看看相關優化的插件要怎麼用:
// gatsby-config.js
module.exports = {
plugins: [
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: 'images',
path: `${__dirname}/src/images/`,
},
},
],
}
複製代碼
gatsby-image
解決了大型網站構建時的以下問題:
1. 將大圖像調整爲設計所需的大小
2. 生成多個較小的圖像,以便智能手機和平板電腦不會下載桌面尺寸的圖像
3. 剝離全部沒必要要的元數據並優化 JPEG 和 PNG 壓縮
4. 高效延遲加載圖像以加快初始頁面加載速度並節省帶寬
5. 使用「模糊處理」技術或「跟蹤的佔位符」 SVG 在加載圖像時顯示圖像預覽
6. 保持圖片位置,以便在加載圖片時您的頁面不會錯亂
複製代碼
這兩個插件都是 gatsby 基於 sharp 圖像處理工具進行擴展的。具體使用就是簡單的在加載圖片的時候進行寬高以及質量進行設置。
上面都稀裏糊塗的安裝完了,咱們來看看這些插件都作了什麼:
事先聲明一下,由於 Gatsby 的內置約束插件系統太多了,因此文章可能充斥着不少說明性圖片,沒辦法,我本身並不能用語言解釋清楚,只能圖片來講了。
能夠看到,左側查詢列表裏出現了兩個帶有 imageSharp 關鍵字的字段,他們就是上面兩個 sharp 插件幫咱們作的一些關於圖片的一些優化。 好比咱們查詢一下全部的本地優化圖片:
嗯,這裏有兩個關鍵點。
gatsby-source-filesystem
配置的文件夾裏面的全部圖片,注意,只有配置了才能夠。/static
文件夾下面有三個圖片,配置的/src/images
文件夾下有兩個圖片,能查到的只有images
文件夾下的兩張圖片。
xxx-sharp
插件處理過的圖片是經過 GraphQL 方法建立的, 可用的圖像優化有兩種類型,固定圖像 - fixed 和流體圖像 - fluid。那麼這兩種類型圖片有什麼區別呢?簡單點,fixed 返回的是固定尺寸的圖片,而 fluid 返回的是流式圖片,它會根據容器寬度進行自適應。我以爲仍是直接來代碼實踐吧:
// /page/image.js
import React from 'react';
import { useStaticQuery, graphql } from "gatsby";
import iconImage from '../images/gatsby-icon.png';
import Img from 'gatsby-image';
const Image = () => {
const data = useStaticQuery(graphql`
query {
fixedIconImage: file(relativePath: { eq: "gatsby-icon.png" }) {
childImageSharp {
fixed(width: 200) {
...GatsbyImageSharpFixed
}
}
}
fluidIconImage: file(relativePath: { eq: "gatsby-icon.png" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
`)
return (
<div>
<h1>靜態引入文件</h1>
<img alt='static-image' src='/gatsby-icon.png' />
<h1>import 引入文件</h1>
<img alt='import-image' src={iconImage} />
<h1>fixed 文件</h1>
<Img alt='fixed-image' fixed={data.fixedIconImage.childImageSharp.fixed} />
<h1>fluid 文件</h1>
<Img alt='fluid-image' fluid={data.fluidIconImage.childImageSharp.fluid} />
</div>
);
}
export default Image;
複製代碼
最高級的功能,先來看看如何使用,須要經過引入gatsby-image
插件,而且參數和正常的<img />
標籤也不同,它不接收 src 屬性,而是接收對應的 fixed 或 fluid 屬性,該屬性就是經過 GraphQL 查詢出來的:
嗯,看到了吧,fluid 類型的文件會撐滿容器寬度。簡要的關鍵點說完了,接下來得了解一下 Gatsby-Image 吹了這麼半天,到底作了哪些優化,仍是用兩張圖片來講明一下:
第一張圖片,以 fluid 爲例,查詢圖片的 src,第二張圖片是編譯過的項目會將配置事後的圖片資源生成多種分辨率不一樣形式(src/base64...),而且在實際運行中按需加載最優的方案。固然,這個最優是 Gatsby 幫咱們判斷的。
上面這張圖說得很清楚了也頗有說服力,gatsby-image
經過<picture>
標籤來加載圖片,裏面有<source>
標籤,裏面放置的是連接地址也就是上面咱們截圖的內容。而下方用來顯示圖片的就是<img>
標籤,它會根據不一樣設備不一樣分辨率進行圖片的優化加載,而且圖片的加載方式是懶加載loading='lazy'
。
上面幾個基本是 Gatsby 必用插件,講完也就差很少了,這裏由於是要搭建博客站,所以額外再介紹一個插件,由於下面也會用到,怕你們不知道就在這裏介紹了。這個插件很簡單,就是解析項目裏的.md
文件,而後咱們就能夠經過 graphql 進行查詢了,這樣也便於進行文章內容的動態配置生成。
// In your gatsby-config.js
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
// CommonMark mode (default: true)
commonmark: true,
// Footnotes mode (default: true)
footnotes: true,
// Pedantic mode (default: true)
pedantic: true,
// GitHub Flavored Markdown mode (default: true)
gfm: true,
// Plugins configs
plugins: [],
},
},
],
複製代碼
使用方式就是配置進去就行,而後咱們就會發現,Graphiql 多了兩個字段:
上面咱們項目裏新增了/posts
文件夾,裏面存放了兩個.md
文件,正好被查詢出來了。除此以外,還能夠爲 Markdown 文件配置相關頭部內容供使用,具體約定的格式以下:
// posts/first.md
---
title: "第一篇文章"
author: "luffyZh"
tag: "React,HTML"
date: "2020-01-12"
---
## 我是第一篇文章
> 第一篇文章
複製代碼
經過插件,就會解析頭部內容爲frontmatter
字段,裏面是咱們配置好的字段屬性。
這個文件很好說了,任何框架任何項目都有本身的配置文件,而gatsby-config.js
就是整個 Gatsby 站點的配置文件。咱們能夠在裏面配置網站的相關基本信息:
module.exports = {
siteMetadata: {
title: `Gatsby`,
siteUrl: `https://www.gatsbyjs.org`,
description: `Blazing fast modern site generator for React`,
},
}
複製代碼
module.exports = {
plugins: [
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `docs`,
path: `${__dirname}/../docs/`,
},
},
],
}
複製代碼
module.exports = {
pathPrefix: `/blog`,
}
複製代碼
這個配置場景也頗有用,那就是 Github Pages 部署項目的時候的路徑問題,更多詳細能夠去看文檔。
polyfill (boolean) - polyfill 相關
mapping (object) - 比較高級,不知道怎麼用。。。😄
proxy (object) - 代理
module.exports = {
proxy: [
{
prefix: "/api",
url: "http://dev-mysite.com",
},
{
prefix: "/api2",
url: "http://dev2-mysite.com",
},
],
}
複製代碼
更多查看文檔。
一些瀏覽器相關的 API 經過在這個文件裏去實現,好比一些監聽路由變化,註冊 serviceWorker 等等。
// 監聽路由變化
exports.onRouteUpdate = ({ location, prevLocation }) => {
console.log('new pathname', location.pathname)
console.log('old pathname', prevLocation ? prevLocation.pathname : null)
};
複製代碼
// 由於是 Node.js,所以引入方式不是 import
const React = require("react");
const Layout = require("./src/components/layout").default;
exports.wrapPageElement = ({ element, props }) => {
// props provide same data to Layout as Page element will get
// including location, data, etc - you don't need to pass it return <Layout {...props}>{element}</Layout> } 複製代碼
能夠看到,已經將咱們全部頁面都使用 Layout 組件包裹上了。裏面出現重複是由於我沒有把原來代碼裏的 Layout 刪除掉,由於只是使用方法,這麼看更直觀。
這個跟上面組件是同樣的場景,只不過是用來包裝根組件的,好比 redux 的 Provider,好比 ant-design 的國際化等。
// 引入 redux
const React = require("react")
const { Provider } = require("react-redux")
const createStore = require("./src/state/createStore")
const store = createStore()
exports.wrapRootElement = ({ element }) => {
return (
<Provider store={store}>
{element}
</Provider>
)
}
複製代碼
具體更多的詳見browser-api。
這個配置文件裏面的代碼顧名思義是 node 層相關的,所以它只會在 build 期間運行一次,好比動態建立一些頁面。這裏有個場景能夠想一下,通常 Gatsby 用來作靜態站,咱們熟知的也就是我的博客,那麼龐大的文章列表難道要手動維護?確定不合理,所以就適合在 node 層動態生成文章列表文章內容頁等等。
前面說過了,Gatsby會把src/pages
目錄下的文件所有渲染成路由,這是一個約定,可是不免會這麼一種場景,就是頁面是帶參數動態生成的,這種時候pages
的定義方式就捉襟見肘了,此時就須要利用gatsby-node.js
來進行配置了。先來簡單寫一個後端建立頁面的示例:
// gatsby-node.js
const path = require('path');
exports.createPages = ({ actions }) => {
const { createPage } = actions;
const staticTemplate = path.resolve(`src/templates/static.js`)
// Query for markdown nodes to use in creating pages.
// You can query for whatever data you want to create pages for e.g.
// products, portfolio items, landing pages, etc.
// Variables can be added as the second function parameter
createPage({
// Path for this page — required
path: `node-static`,
component: staticTemplate,
context: {
title: '我是靜態頁面',
content: '靜態頁內容'
},
});
};
複製代碼
上面代碼在 gatsby-node.js 的 createPages API 建立一個路由,模板是/src/templates/static.js
,對應路徑是/node-static
,而建立頁面以及傳遞屬性使用的是actions.createPage
,它的context
屬性能夠配置一些屬性做爲 props 傳遞給組件,而在組件內部咱們能夠經過幾種方式來獲取:
// 第一種 - 經過 pageContext 獲取 context
import React from 'react';
export default (props) => {
const { pageContext: { title, content } } = props;
return (
<>
<h1>{title}</h1>
<p>{content}</p>
</>
)
};
// 第二種 - 經過 GraphQL 獲取
export const data = graphql`
query {
sitePage(path: {eq: "/node-static"}) {
id
context {
title
content
}
}
}
`;
const { sitePage: { context: { title, content } } } = data;
複製代碼
上面只是一個簡單的演示 node 層如何建立頁面,不過呢,若是是這種頁面,確定是放在src/pages
目錄下更合理,經過 node 建立的頁面必定是更復雜的頁面。我說過了想使用 Gatsby 搭建一個我的博客,所以就使用 gatsby-node.js 來動態建立博客文章頁吧。
上圖,我新建了一個 posts 文件夾,裏面存放博客文章(.md 文件)。在 gatsby-node.js 編寫代碼動態生成每一個文章的頁面。
// gatsby-node.js
exports.createPages = ({ actions, graphql }) => {
const { createPage } = actions;
...
/* 建立一個複雜的動態頁面 */
const blogPostTemplate = path.resolve(`src/templates/blog-post.js`)
return graphql(`
query {
allMarkdownRemark {
edges {
node {
id,
html
}
}
}
}
`).then(result => {
if (result.errors) {
throw result.errors
}
// Create blog post pages.
result.data.allMarkdownRemark.edges.forEach(edge => {
createPage({
// Path for this page — required
path: `posts/${edge.node.id}`,
component: blogPostTemplate,
context: {
html: edge.node.html
},
})
})
});
...
}
複製代碼
這裏是用了 graphql 查詢,注意這個graphql
來自 createPages 的 API,咱們查詢到全部的 markdown 文章內容,而後逐個遍歷生成路由頁面,定義是 posts/${articleId}
,重啓服務訪問一下:
能夠看到,兩篇文章在 graphql 是能夠查詢到的,而且咱們前端組件也正常渲染了對應文章頁面。這只是牛刀小試,還有不少更方便的功能,具體更多的詳見browser-api。
這個文件,看名字意思是服務端渲染相關處理,給的示例是這樣的,你能夠將服務端渲染的 HTML 代碼在此文件裏進行二次加工處理。
// gatsby-ssr.js
const React = require("react")
// 給 body 標籤添加一個類名字爲 my-body-class
exports.onRenderBody = ({ setBodyAttributes }, pluginOptions) => {
setBodyAttributes({
className: "my-body-class",
})
};
複製代碼
可是這裏須要注意一點,wrapPageElement
和wrapRootElement
這兩個 API 是 gatsby-browser.js 和 gatsby-ssr.js 共享的。最好保證只在其中一個文件使用它們,否則可能會出現渲染不一致的場景。
其他還有不少 API,不過 gatsby-ssr.js 更多的是與/src/html.js
文件一塊兒討論,它修改的內容會覆蓋html.js
的內容。
具體更多的詳見browser-api。
關於部署,由於我是 Next.js 愛好者,所以這裏選擇使用 now 來進行部署,固然也有其餘的方式,好比 surge。
now
複製代碼
嗯,完事了,固然,前提是你安裝了now-cli
,具體的能夠去 now 官網去安裝,反正安裝完你直接運行命令 now 就完事了~
咱們來看看部署後的網站:
一篇文章想把 Gatsby 全部內容儘量的講到確實太難了,文章架構組織了很久,最後決定是上面那樣,可能不能算完美,可是我以爲已是新手可以接受的按部就班了。由於 Gatsby 技術耦合很嚴重,你若是想使用它,就必須前置掌握太多的東西了(node/react/graphql...)。
上面基本把我用到的學到的經過本身的理解都解釋給你們了,Gatsby 使用下來發現本身真的挺無力,哈哈,爲啥呢?由於你能作的只是寫頁面代碼,其餘的就是按照 Gatsby 的約束安裝插件直接使用就行,怎麼說呢?寫下來毫無成就感~固然了也側面印證了 Gatsby 確實適合快速建站,啥都不須要你管你就能夠有一個各方面都比較完美的靜態站,由於他將不少性能優化點都集成在了項目以及插件系統,咱們拿來主義直接使用就 OK 了。