共计 13215 个字符,预计需要花费 34 分钟才能阅读完成。
Gatsby 介绍
什么是 Gatsby
Gatsby 是一个基于 React,用于搭建动态站点的开源框架,用于帮忙 开发者构建运行速度极快的网站。能够说它是一个动态站点生成器,Gatsby 次要的利用的技术是 React 和 GraphQL。
官网:https://www.gatsbyjs.org/
为什么选 Gatsby
Gatsby 能疾速应用 React 生态系统来生成动态网站,它具备更高的性能,而且 Gatsby 的生态也很弱小。
当你想本人入手搭建集体博客时,思考的是 SEO 要好,而且你不必理睬数据库和服务器等简单的部署设置,Gatsby 构建的网站为动态站点,你能够很轻松的将网站部署在很多服务上。Gatsby 不须要期待申请时生成页面,而是事后生成页面,因而网站的速度会很快。
Gatsby 中使用了 React, react-router, Webpack 以及 GraphQL 等新技术,也追随了技术潮流。
GraphQL 介绍
下面咱们说到了 GraphQL,没理解的同学可能不太分明。
GraphQL 是一种用于 API 的查询语言,是 Restful API 的替代品。
至于代替 Restful API 一说,集体感觉当初 Restful API 占据相对的主导地位,以后还是很难被撼动的。因为目前来看,GraphQL 也有它的毛病。
看到这里没学过 GraphQL 也不必怕,因为用到的不多而且 Gatsby 内置一个界面不便咱们操作。GraphQL 目前国外比拟火,它作为一门新技术,即便不深刻咱们也能够理解一下。
这里咱们当然要吹捧它的长处,下面的定义你可能会纳闷,API 不就是后端写好的接口吗,怎么还能查问?
GraphQL 咱们把这个单词拆开的话是:Graph(图形或图表) + QL(Query Language),它是一种图形化的查询语言,形容客户端如何像服务端申请数据的语法标准。听起来隐隐约约,那它绝对 Restful API 又解决了什么痛点呢?
- 申请你所要的数据不多不少
置信少数人必定遇到过的场景,比方我的项目管理系统,进入某页面展现一个列表,列表上只需展现题目,但你申请返回的数据却多了其余信息,比方创建者、创立工夫等。这些信息在这里是多余的,但它可能有它本人存在的理由,或者是其余场景须要返回这些信息,因而该接口就间接蕴含了所有数据。
这一点,GraphQL 能精确获取你想要的数据,不多不少,想要返回指定的什么数据,就返回什么数据。数据由利用来管制,而不是服务器。
- 获取多个资源只须要一个申请
GraphQL 查问不仅可能取得资源的属性,还能沿着资源间援用进一步查问。典型的 REST API 申请多个资源时得载入多个 URL,而 GraphQL 能够通过一次申请就获取你利用所需的所有数据。这样一来,即便是比较慢的挪动网络连接下,应用 GraphQL 的利用也能体现得足够迅速。
- 形容所有的可能类型零碎
GraphQL API 基于类型和字段的形式进行组织,而非入口端点。你能够通过一个繁多入口端点失去你所有的数据能力。GraphQL 应用类型来保障利用只申请可能的数据,还提供了清晰的辅助性错误信息。利用能够应用类型,而防止编写手动解析代码。
Gatsby 应用了 GraphQL,作为在本地治理资源的一种形式。
搭建我的项目
开始
- 装置 Gatsby 脚手架
npm install -g gatsby-cli
- 新建我的项目
gatsby new projectName:依据 starter 创立一个新我的项目
gatsby new gatsby-blog-demo https://github.com/gatsbyjs/gatsby-starter-hello-world
咱们这里应用官网最简略版本的 hello-world 模板进行开发,如果你间接应用
gatsby new gatsby-blog-demo
默认会应用 gatsby-starter-default 来新建我的项目
- 运行我的项目
cd gatsby-blog-demo
gatsby develop
关上 localhost:8000
,就能够看到输入了一句Hello world!
常用命令
这里介绍 Gatsby 的几个常用命令:
- gastby develop:开启热加载开发环境
- gastby build:打包到 public 下,构建生产环境用的优化过的动态网站所需的所有动态资源、动态页面与 js 代码
- gatsby serve:在打包之后,启动一个本地的服务,供你测试方才 ”gatsby build” 生成的动态网页
GraphiQL
关上http://localhost:8000/__graphql
,就会看到 GraphQL 的调试界面,这里能够查看所有的数据、以及调试 query 语句是否返回相应的数据。能够间接在左侧点击选中,就能够主动生成 query 语句。
可能呈现的正告
如果运行后你的控制台呈现:
React-Hot-Loader: react-????-dom patch is not detected. React 16.6+ features may not work.
能够这样解决:
npm install @hot-loader/react-dom
在根目录下新建gatsby-node.js
exports.onCreateWebpackConfig = ({getConfig, stage}) => {const config = getConfig()
if (stage.startsWith('develop') && config.resolve) {
config.resolve.alias = {
...config.resolve.alias,
'react-dom': '@hot-loader/react-dom'
}
}
}
再重新启动我的项目,就能够打消这个正告
我的项目构造
├── .cache
├── public
├── src
| └── pages // 该文件夹下的文件会被映射为路由
| └── index.js
├── static // 动态资源
├── .prettierignore
├── .prettierrc
├── gatsby-config.js // 根本配置文件
├── LICENSE
├── package.json
├── README.md
└── yarn.lock
Gatsby 配置文件
这里最初始的模板只有一个配置文件,个别我的项目中都会有 4 个配置文件
gatsby-config.js
根本配置文件。整个 Gatsby 站点的配置文件。能够在外面配置网站的相干根本信息。
gatsby-node.js
node 相干配置文件。这个文件只会在 build 期间运行一次,比方动态创建一些页面。
gatsby-browser.js
客户端相干配置。一些浏览器相干的 API 通过在这个文件里去实现,比方一些监听路由变动,注册 serviceWorker 等等。
gatsby-ssr.js
服务端渲染相干配置文件。应用 Gatsby 的服务端渲染 API 自定义影响服务端渲染的默认设置。
创立页面
路由页
咱们在 pages
目录下创立一个文件about.js
,则对应的路由门路为/about
import React from 'react'
const About = () => {return <div>about me</div>}
export default About
关上http://localhost:8000/about
,显示的是咱们刚刚创立的页面
404 页面
pages
目录下的文件名即是路由门路,但有一个比拟非凡,当匹配不到门路时,Gatsby 会跳转到 404 页面,如果咱们在 pages 下创立文件名404.js
,会应用咱们自定义的 404 页面。以后咱们轻易输出一个不存在的页面门路:http://localhost:8000/test
,页面就会报错。
咱们新建一个文件 404.js
import React from 'react'
const About = () => {return <div>404 页面不存在 </div>}
export default About
再轻易输出一个门路,显示出该页面:
Gatsby 会确保将 404 页面构建为 404.html,默认状况下会为咱们创立此页面,在该页面也列出了网站上的所有页面路由链接, 咱们能够通过单击 Preview custom 404 page
看咱们方才创立的 404 页面。
那咱们想间接跳转到咱们自定义的 404 页面啊,还要咱们点击才跳转。起因是处于开发环境,即当应用 gatsby develop
时,Gatsby 应用默认的 404 页面笼罩咱们自定义的 404 页面,但实际上是曾经失效了。
咱们能够打包,启动一个本地的服务,模仿处于线上环境来看,这个时候才是间接显示咱们自定义的 404 页面。
gatsby build
gatsby serve
而后关上http://localhost:9000/test
(任意门路),就能跳转到咱们自定义的 404 页面了
创立布局组件
- 创立一个新目录
src/components
。 - 在下面的目录中创立一个布局组件文件 src/components/layout.js:
import React from 'react'
export default ({children}) => (<div style={{ margin: `3rem auto`, maxWidth: 650, padding: `0 1rem`}}>{children}</div>
)
- 在
src/pages/index.js
中,退出 Layout 组件,
import React from 'react'
import Layout from '../components/layout'
export default function Home() {return <Layout>Hello world!</Layout>}
这样就让整体页面居中了,这里都是 React 的基本操作
设置 CSS 款式
Gatsby 中款式能够应用多种形式,一般的 import './xxx.css
咱们就不说了。
应用全局款式
咱们向网站增加全局款式的最间接的办法之一就是应用全局 .css 样式表。
在 src 目录下新建文件夹styles
,增加一个 global.css 文件
html {background-color: #f5f5f5;}
- 在目录下创立 gatsby-browser.js 中,将款式文件导入
import "./src/styles/global.css"
重启本地服务,就发现页面背景变为浅灰色了。
应用 CSS Module 为组件设置款式
CSS Module 能够缩小全局净化、避免命名抵触和款式的笼罩。
CSS Module 实现原理是:将所有模块化的类名,批改为成惟一的名称,即增加一些不反复的前缀或后缀。这样使得我的项目中,不同人员编写的款式不会呈现笼罩和抵触。
- 创立 CSS 文件
src/styles/index.module.css
.title {color: red;}
.text {color: blue;}
用法如下:src/pages/index.js
import React from "react"
import Layout from "../components/layout"
import styles from "../styles/index.module.css"
export default function Home() {console.log(styles)
return (
<Layout>
<h1 className={styles.title}>Hello World</h1>
<div className={styles.text}>Test</div>
</Layout>
)
}
运行后果:
输入 styles
, 能够看到被导入解决的后果:
如果将其与 CSS 文件进行比拟,你会发现每个格局当初都是导入对象中指向长字符串的键(key),例如 title
指向 index-module--title--1i-Wh
。这些款式名称是 CSS 模块生成的。保障它们在你的网站上是惟一的。而且因为必须导入它们能力应用这些类,所以对于在任何中央应用这些 CSS 款式都没问题。
其余解决 CSS 的形式
应用 css 款式就点到为止了,其余的比方 Sass 等;还有 CSS in JS 的形式,比方 Emotion, Styled Component。能够去官网查看相应反对的 Gatsby 插件,就能够应用了。
获取 Gatsby 中的数据
建设网站时,您可能须要重用一些罕用的数据——比方专用的网站题目、作者信息等,咱们不可能在每个页面都加,所以咱们把题目存储在一个地位,而后从其余文件援用该地位就行了,更改的时候也只能更改这一处中央。
这些罕用数据的寄存地位就是 gatsby-config.js
文件中的 siteMetadata
对象。关上这个文件,写入代码:
module.exports = {
/* Your site config here */
siteMetadata: {
title: `Title from siteMetadata`,
author: 'jacky'
},
plugins: [],}
重启服务
应用页面查问
编辑 src/pages/about.js
import React from 'react'
import {graphql} from 'gatsby'
// GraphQL 获取的数据,会当做参数传递到页面组件中
// 数据的模式是 {errors, data},没有谬误则不会有 errors
const About = ({data}) => {console.log(data.site.siteMetadata.title)
return (
<div>
<h1>Title: {data.site.siteMetadata.title}</h1>
<p>author: {data.site.siteMetadata.author}</p>
<div>about me</div>
</div>
)
}
export default About
export const query = graphql`
query {
site {
siteMetadata {
title
author
}
}
}
`
而后就拉出数据了
其中,GraphQL 查问语句是:
{
site {
siteMetadata {
title,
author
}
}
}
你可能会懵逼,site 是哪里来的,这数据格式怎么是这样,这就是 GraphQL 查问语句了,咱们能够关上 Gatsby 内置的 GraphQL 调试界面 http://localhost:8000/__graphql
。
这里的 site
即为咱们 gatsby-config.js
写的站点配置。
顺次点击右边的 site
、siteMetadata
,而后有咱们方才写的title
,author
字段 供咱们抉择,在点击的同时,两头的框会生成查问语句,最初点击运行按钮,会输入查问后果。
当你前面须要获取更多简单嵌套数据的时候,能够间接在这个界面找和点击,主动生成查问语句就行了。
由咱们本人写的查问语句也晓得,下面咱们介绍 GraphQL 的时候说的一个特点,获取数据不多不少,即咱们能够抉择想要的数据,比方我就想获取题目不想获取作者
export const query = graphql`
query {
site {
siteMetadata {title}
}
}
`
应用非页面组件查问(动态查问)
这里留神,咱们须要辨别两种形式的查问,下面的例子的查问形式,只实用于页面查问,即是在 src/pages
下的路由界面,如果在非页面组件下进行 GraphQL 查问,则不能用下面的形式,应该应用 StaticQuery
组件或者 useStaticQuery hook
。
// 页面查问
export const query = graphql`
query{...}
`
比方咱们创立一个组件src/components/header.js
- StaticQuery
import React from 'react'
import {graphql, StaticQuery} from 'gatsby'
const Header = () => (
<StaticQuery
query={graphql`
query {
site {
siteMetadata {author}
}
}
`}
render={data => {
const {site: { siteMetadata},
} = data
return <div> 这是 Header 组件,作者是:{siteMetadata.author}</div>
}}
/>
)
export default Header
或者应用 useStaticQuery 形式
- useStaticQuery
import React from "react"
import {useStaticQuery, graphql} from "gatsby"
const Header = () => {
const data = useStaticQuery(
graphql`
query {
site {
siteMetadata {author}
}
}
`
)
return <div> 这是 Header 组件,作者是:{data.site.siteMetadata.author}</div>
}
export default Header
而后在 src/pages/index.js
中引入 Header 组件
import React from 'react'
import Layout from '../components/layout'
import Header from '../components/header'
import styles from '../styles/index.module.css'
export default function Home() {
return (
<Layout>
<Header />
<h1 className={styles.title}>Hello World</h1>
<div className={styles.text}>Test</div>
</Layout>
)
}
运行后果如下:
插件
gatsby-source-filesystem
这个是 Gatsby 的数据源插件,即通过该插件将各方面的数据转换为本地可能通过 GraphQL 提取的内容,用于设置我的项目的文件系统。
- 装置插件
npm install --save gatsby-source-filesystem
- 在 gatsby-config.js 文件配置
module.exports = {
siteMetadata: {
title: `Title from siteMetadata`,
author: 'jacky',
},
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `src`, // 名称,能够用来过滤
path: `${__dirname}/src/`, // 文件门路
},
},
],
}
重启服务
关上 http://localhost:8000/__graphql
,关注allFile
和file
两个可选项。
咱们点击 allFile
这个可选项,顺次抉择如下图
这里咱们要晓得,咱们要查问的数据根本在 edges.node
下,节点 node
是图(graph)中一个对象的非凡称说,每个 File 节点都蕴含了你要查问的字段。
咱们抉择的 id
,relativePath
,name
字段都对应咱们 src
目录下创立的文件, 还有很多其余字段可抉择,由此可知咱们创立的 7 个文件的各种信息。
既然这里能查问进去,阐明咱们组件外面也能查出来而后应用数据,比方你能够从组件中查问进去做个文件列表。
这个相比传统的 React 我的项目就挺厉害了,不必做什么简单的工作,就能轻松拿下这些数据。Gatsby 比拟弱小的就是它的生态了,很多插件都配好了,更多插件能够看官网的插件库介绍:https://www.gatsbyjs.org/plug…
gatsby-transformer-remark
这个是数据转换插件,咱们用 Gatsby 做集体博客的话,它可必不可少。当初咱们程序员写博客根本是用 markdown 语法了,做一个博客的话,不可短少的就是对 markdown 语法的解析。
- 装置插件
npm install --save gatsby-transformer-remark
- 在 gatsby-config.js 文件配置
module.exports = {
/* Your site config here */
siteMetadata: {
title: `Title from siteMetadata`,
author: 'jacky',
},
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `src`, // 名称,能够用来过滤
path: `${__dirname}/src/`, // 文件门路
},
},
`gatsby-transformer-remark`,
],
}
重启服务
这个插件增加了 allMarkdownRemark 和 markdownRemark 两个数据字段
- 新建 md 文件
在 src
下创立 _posts
目录,增加一个 first-blog.md
文件
---
title: "我的第一篇博客"
date: "2020-06-21"
tags: "React"
categories: "React 系列"
---
## 这是第一篇博客的题目
first blog 的内容 1
如果博客不是本人搭建的,而是间接上某平台写的话,对下面这段语法就可能不太理解,在 md 文件结尾的 ---
包裹的是 frontmatter(前言),而后在外面能够增加文章的各种关键词信息。
而后咱们就能够在 http://localhost:8000/__graphql
查问到咱们写的 md 文件的详情信息了
咱们略微再改变,创立多两个 md 文件
second-blog.md
---
title: "我的第二篇博客"
date: "2020-06-22"
tags: "Vue"
categories: "Vue 系列"
---
## 这是第二篇博客的题目
second blog 的内容 2
third-blog.md
---
title: "我的第三篇博客"
date: "2020-06-23"
tags: "React"
categories: "React 系列"
---
## 这是第三篇博客的题目
third blog 的内容 3
再次查问数据,把咱们刚刚增加的文章数据都拿下来了
既然 GraphQL 能拿到数据,阐明咱们也能把它放到页面展现进去。
新建文件src/pages/blog.js
, 咱们做一个博客目录汇总:
import React from 'react'
import Layout from '../components/layout'
import {graphql} from 'gatsby'
const Blog = ({data}) => {
return (
<Layout>
<h1> 博客目录 </h1>
<div>
{data.allMarkdownRemark.edges.map(({ node}) => {
return (
<div
key={node.id}
style={{
border: '1px solid #000',
margin: '10px',
padding: '10px',
}}
>
<h2>{node.frontmatter.title}</h2>
<div> 分类{node.frontmatter.categories}</div>
<div> 标签:{node.frontmatter.tags}</div>
<div> 公布工夫:{node.frontmatter.date}</div>
</div>
)
})}
</div>
</Layout>
)
}
export default Blog
export const query = graphql`
query {
allMarkdownRemark {
edges {
node {
id
frontmatter {
tags
title
date
categories
}
}
}
}
}
`
关上http://localhost:8000/blog
,博客目录就展现进去了:
但有个问题,每篇博客的信息的确能拿进去,然而咱们要链接啊,即是点击博客题目,进入博客详情页面,即是文章门路,所以接下来咱们将创立页面。
利用数据创立页面
gatsby-node.js
这个时候咱们就要建设 gatsby-node.js
文件了,这个配置文件外面的代码是 node 层相干的。
后面咱们说过 src/pages
目录下的文件会全副渲染成路由,但如果咱们博客文章一篇篇的详情页要咱们本人创立一个 js 文件,这必定不合理了。
咱们会用到两个 API:
onCreateNode
每当创立新节点(或更新)时,Gatsby 都会调用 onCreateNode 函数。
向 gatsby-node.js
写入代码:
exports.onCreateNode = ({node}) => {console.log(node.internal.type)
}
重启服务,查看终端,你会发现打印出很多创立的节点:SitePage
, SitePlugin
, Site
, SiteBuildMetadata
, Directory
, File
, MarkdownRemark
, 咱们关注的只有 MarkdownRemark
,于是批改函数使其仅仅记录 MarkdownRemark 节点;咱们应用每一个 md 文件的名称来作为门路,如要获取文件名称,你须要遍历一遍它的父节点 File
,File
节点蕴含了咱们须要的文件数据。
exports.onCreateNode = ({node, getNode}) => {if (node.internal.type === `MarkdownRemark`) {const fileNode = getNode(node.parent)
console.log(`\n`, fileNode.relativePath)
}
}
重启服务,查看终端,打印如下:
_posts/first-blog.md
_posts/second-blog.md
_posts/third-blog.md
相对路径进去,接下来咱们要创立门路,能够应用 gatsby-source-filesystem
插件带的创立门路的函数
const {createFilePath} = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({node, getNode}) => {if (node.internal.type === `MarkdownRemark`) {console.log(createFilePath({ node, getNode, basePath: `pages`}))
}
}
重启服务,打印后果如下:
/_posts/first-blog/
/_posts/second-blog/
/_posts/third-blog/
接下来,向 API 传递一个函数createNodeField
,该函数容许咱们在其余插件创立的节点里创立其余字段。
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, // 通常用 slug 一词代表门路
})
}
}
重启服务,关上http://localhost:8000/__graphql
,就能查问到门路了
createPages
createPages 这个 API 用于增加页面。在创立页面之前,首先要有页面模板,这样创立页面就能指定所应用的模板了。
新建文件src/templates/blog-post.js
import React from 'react'
import Layout from '../components/layout'
export default () => {
return (
<Layout>
<div>Hello blog post</div>
</Layout>
)
}
而后更改 gatsby-node.js
的 createPages
函数:
const path = require(`path`)
exports.createPages = async ({graphql, 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: {slug: node.fields.slug,},
})
})
}
重启服务,轻易输出一个门路,跳转到默认的 404 页面,就会看到主动生成三篇博客的门路了,点击任一篇,跳转的是咱们刚创立的 blog-post.js
组件。
咱们要的是显示博客内容,所以咱们须要对模板文件再进行革新:
import React from 'react'
import {graphql} from 'gatsby'
import Layout from '../components/layout'
export default ({data}) => {
const post = data.markdownRemark
return (
<Layout>
<div>
<h1>{post.frontmatter.title}</h1>
<div dangerouslySetInnerHTML={{__html: post.html}} />
</div>
</Layout>
)
}
export const query = graphql`
query($slug: String!) {markdownRemark(fields: { slug: { eq: $slug} }) {
html
frontmatter {title}
}
}
`
下面是动静变量查问的写法,GraphQL 的语法,能够看看 (https://graphql.org/learn/que…
实现之后,比方我点击第二篇博客,就能够正确进入页面并显示内容了
为了更欠缺,咱们给 blog 目录页面增加可跳转的链接,退出 slug
查问字段, 减少 Link
跳转,这个用法与 React 路由的 Link
差不多统一,波及不深的状况下暂且当成雷同用法。
src/pages/blog.js
import React from 'react'
import Layout from '../components/layout'
import {graphql, Link} from 'gatsby'
const Blog = ({data}) => {
return (
<Layout>
<h1> 博客目录 </h1>
<div>
{data.allMarkdownRemark.edges.map(({ node}) => {
return (<Link to={node.fields.slug} key={node.id}>
<div
style={{
border: '1px solid #000',
margin: '10px',
padding: '10px',
}}
>
<h2>{node.frontmatter.title}</h2>
<div> 分类{node.frontmatter.categories}</div>
<div> 标签:{node.frontmatter.tags}</div>
<div> 公布工夫:{node.frontmatter.date}</div>
</div>
</Link>
)
})}
</div>
</Layout>
)
}
export default Blog
export const query = graphql`
query {
allMarkdownRemark {
edges {
node {
id
frontmatter {
tags
title
date
categories
}
fields {slug}
}
}
}
}
`
当初点击博客,就能跳转到对应页面了,尽管没做款式页面比拟丑,但只有在 src/_posts
目录新建 md 文件,而后这里就能跟着主动刷新,算是一个超繁难的博客了。
打包上线
进行开发服务,构建生产版本,把动态文件输入到 public 目录中
gatsby build
在本地查看生产环境版本,运行:
gatsby serve
接下来,就能够在 localhost:9000
拜访咱们方才做的网站了
本我的项目的 github 地址
至此,咱们教程就介绍到这里了。
- ps:集体技术博文 Github 仓库,感觉不错的话欢送 star,给我一点激励持续写作吧~