快速掌握《了解了盖茨比》的教程
我试过用 Gatsby,但只用教程只能解决一些问题,最后还是不得不阅读大量文档。整理了文档链接后,我写了一个还不错的教程,所以发了出来(虽然有些地方还是有点不完整的)。
(追加说明)当实际创建博客时,您可能会参考这里的内容。
安装
npm install -g gatsby-cli
gatsby new [rootPath] [starter] Create new Gatsby project.
您可以指定一个“starter”来启动。默认情况下,将选择默认的启动器。
由于这是一个入门教程,只需要选择一个Hello-World。
gatsby new my-blog https://github.com/gatsbyjs/gatsby-starter-hello-world
gatsby develop
总算也写在了npm脚本中。
npm run develop
"scripts": {
"develop": "gatsby develop"
}
当需要启动多个项目时,可以使用-p选项来指定不同的端口。
gatsby develop -p 3000
CLI的文档都被详细地提供了。
默认情况下,您可以通过http://localhost:8000/访问页面,并且可以通过http://localhost:8000/___graphql访问GrqphiQL。
初级初学者
页面 (yè mian)
在目录的结构中有规则,pages/会自动成为页面。
例如,创建pages/about.js,就会在/about上显示(生成页面并设置路由)。
import React from 'react'
export default <div> index page </div>
import React from 'react'
export default <div> hello page </div>
您可以在components/中创建共享组件,然后像开发普通的React应用程序那样进行开发。
在 src/pages/*.js 中定义的任何 React 组件都将自动成为一个页面。
使用页面组件
还可以创建模板文件并动态地生成页面。可以自动创建页面。
GraphQL (only need one option):
GraphQL是一种查询语言
gatsby 的方便之处在于可以通过 Graphql 在项目内获取数据。
您可以通过以下查询获取项目的设置信息。
将config文件如下进行更改。
module.exports = {
siteMetadata: {
title: `Title from siteMetadata`,
}
}
query {
site {
siteMetadata {
title
}
}
}
示威活动
通过查询获取项目信息,创建一个显示这些信息的React组件,并且基于它生成页面的流程是gatsby的。
使用一个页面查询
我认为对于这个GraphQL,最好将其分为两个步骤来理解,一个是添加数据的步骤,另一个是获取数据的步骤。
首先我们来看一下添加数据的工作。
通过安装后述的插件,你就可以自由获取项目内的信息。
将数据添加到GraphQL
通过插件添加数据
在文件中,将数据添加操作描述为“基于插件驱动”,实际上只需要安装插件即可。
寻找数据
《了不起的盖茨比》源文件系统
通过使用gatsby-source-filesystem,可以从源中获取数据。
npm install --save gatsby-source-filesystem
module.exports = {
siteMetadata: {
title: `Pandas Eating Lots`,
},
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `src`,
path: `${__dirname}/src/`,
},
}
]
}
打开GraphiQL后,将会新增allFile和file选项,并可以通过以下查询获取文件信息。
query {
allFile {
edges {
node {
relativePath
prettySize
extension
birthTime(fromNow: true)
}
}
}
}
在教程中,我们获取并展示了项目的JS文件。
gatsby-transformer-remark: 贾比转换器
这个插件不仅仅是用来添加数据的,所以用这种方式写可能有点微妙,但这个插件最容易理解的功能是将Markdown转换为HTML。可以将md文件的信息转换并提取为html,也可以提取frontmatter等元信息。
添加了allMarkdownRemark。
自己添加数据
可以使用createNodeAPI来自己传输数据。后面会提及,插件是使用这个API来传输数据的。
尝试手动输入数据
const pokemons = [
{ name: “Pikachu”, type: “electric” },
{ name: “Squirtle”, type: “water” },
]
pokemons.forEach(pokemon => {
const node = {
名称:pokemon.name,
类型:pokemon.type,
编号:createNodeId(`Pokemon-${pokemon.name}`),
内部:{
类型:”宠物”,
内容摘要:createContentDigest(pokemon),
},
}
actions.createNode(node)
})
}
通过以下查询,您将能够获取 。
query MyPokemonQuery {
allPokemon {
nodes {
name
type
id
}
}
}
可以传送外部获取的数据。
试试把从 API 获取的数据流过去。
const fetch = require(“node-fetch”)
const fetchItems = () =>
fetch(“https://qiita.com/api/v2/items”).then(res => res.json())
exports.sourceNodes = async ({
actions,
createNodeId,
createContentDigest,
}) => {
const items = await fetchItems()
items.forEach(item => {
const node = {
id: item.id,
title: item.title,
user: {
name: item.user.name,
},
internal: {
type: “Item”,
contentDigest: createContentDigest(item),
},
}
actions.createNode(node)
})
}
查询ItemQuery {
allItem {
nodes {
title
user {
name
}
}
}
}
{
“data”: {
“allItem”: {
“nodes”: [
{
“title”: “关于blob和createObjectURL的问题”,
“user”: {
“name”: “Yu Watanabe”
}
},
]
}
}
}
通过从Qiita的API获取的信息流,现在可以通过查询进行获取。
我认为您可以通过使用createNode函数获取并导入了本地文件列表,就像之前提到的gatsby-source-filesystem所做的一样。
由于有一个插件,它可以在传输文件信息或从WordPress获取并传输文章,所以我们只需将路径或URL放入配置文件中,就可以通过查询来获取数据。
Pixabay源插件教程
只需要在页面上显示通过查询获取的结果即可。
添加节点
你可以在节点中添加字段
生成页面的短标识符
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,
})
}
}
已新增了一个slug,可以获取它。
query {
allMarkdownRemark {
edges {
node {
id
fields {
slug
}
}
}
}
}
查询
有些人可能是第一次接触GraphQL,但如果只是创建网站,我认为参考文档的内容就足够了。而且在GraphQL中,只需随意点击左边的选项就会自动帮你生成查询,所以我认为没有什么特别困扰的事情。
别名
在中国的本地化,只需要一种选择:
allMarkdownRemark的结果是data.allMarkdownRemark本身,但是您可以在开头加上任意的alias。
它将返回为data.latestPost,data.relatedPost这样的形式。
query {
latestPost: allMarkdownRemark(limit: 5) { }
relatedPost: allMarkdownRemark(limit: 5) { }
}
前言
在Markdown文件的开头,定义信息如下。
---
title: my first post
date: 2019-12-7
---
通过使用先前提到的gatsby-transformer-remark,您可以使用以下查询来获取数据。
frontmatter {
title:
date:
}
参数
主要是关于Markdown-Remark的讨论。
- limit
allMarkdownRemark(limit: 5) { }
- format
date(formatString: "YYYY月MM月DD日")
- filter
filter: { tags: { in: ["post", "page"] }, draft: { eq: false } }
获取最近的5个帖子的查询
query {
allMarkdownRemark(
limit: 5,
sort: {order: DESC, fields: frontmatter___create_at}
) {
edges {
node {
id
frontmatter {
title
}
}
}
}
}
动态生成页面。
从页面中获取所需的数据
我们将实际从GraphQL中获取数据并在页面上显示。
import React from "react"
import { graphql } from "gatsby"
export const query = graphql`
query TitleQuery {
site {
siteMetadata {
title
}
}
}
`
export default ({ data }) => (
<div>
<h1>{data.site.siteMetadata.title}</h1>
</div>
)
页面查询
-
- 1つのファイルにつき1つのqueryを宣言できる。この時変数は関係ない。
- queryの結果がpropsのdataオブジェクトに入ってくる。
在教程中没有写明,但上述规则是存在的。
我尝试在一个文件中声明了两个查询,结果被怒斥了。
export const query1 = graphql`
query HomePageQuery {
site {
siteMetadata {
description
}
}
}
`
export const query2 = graphql`
query HomePageQuery {
site {
siteMetadata {
description
}
}
}
`
Multiple "root" queries found in file
当初看到这个时,为什么查询的结果会传递到props的data里呢?一开始我有点困惑,不知道什么时候执行查询,但现在我使用的是静态网站生成器,根据规范我应该在文件中定义查询,然后它会根据这个查询来生成页面,我忘记了这一点。
https://www.gatsbyjs.org/docs/recipes/#使用页面查询从数据中查询数据
https://www.gatsbyjs.org/docs/page-query/#添加GraphQL查询
动态生成页面
使用createPage API从模板动态生成页面。
我认为在教程的第七部分会变成这样的感觉。
const path = require(`path`)
exports.createPages = async ({ actions, graphql }) => {
const result = await graphql(`
{
allMarkdownRemark {
edges {
node {
frontmatter {
path
}
}
}
}
}
`)
if (result.errors) { console.error(result.errors) }
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
actions.createPage({
path: node.frontmatter.path,
component: path.resolve(`src/templates/post.js`),
})
})
}
import React from "react"
import { graphql } from "gatsby"
export const pageQuery = graphql`
query($path: String!) {
markdownRemark(frontmatter: { path: { eq: $path } }) {
html
frontmatter {
date(formatString: "MMMM DD, YYYY")
path
title
}
}
}
`
const Template = ({ data }) => {
const { markdownRemark } = dat
const { frontmatter, html } = markdownRemark
return (
<div className="blog-post">
<h1>{frontmatter.title}</h1>
<h2>{frontmatter.date}</h2>
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
)
}
export default Template;
首先,我们来查看模板文件。模板文件会使用path参数来嵌入查询的结果。
在gatsby-node.js文件中,根据所有md文件的查询结果调用createPage方法。
该方法指定了上面的模板文件,并动态生成页面。
重要但未在教程中提到的一点是,上下文参数可以作为模板的props和模板文件查询的参数传递。
https://www.gatsbyjs.org/docs/recipes/#通过GraphQL为博客帖子和页面获取Markdown数据
https://www.gatsbyjs.org/docs/using-gatsby-without-graphql/
创建页面
所有上下文值都可以作为以$为前缀的参数,在模板的GraphQL查询中使用。
创建页面
将这些作为属性传递给组件的this.props.pageContext,同时也作为graphql参数传递给graphql查询。
寻找来源花了我一些时间。
概念性的
开胃菜
-
- gatsby-starter-default
gatsby-starter-blog
gatsby-starter-hello-world
实际上,公式的起始者只有前面提到的三个。
Gatsby.js 初始模板列表
https://www.gatsbyjs.org/starters/?v=2
gatsby new gatsby-starter-hero-blog https://github.com/greglobinski/gatsby-starter-hero-blog
这件事有点笨重。
插件
npm install --save gatsby-transformer-json
module.exports = {
plugins: [`gatsby-transformer-json`],
}
插件可以指定任意的选项。
plugins: [
// Shortcut for adding plugins without options.
"gatsby-plugin-react-helmet",
{
// Standard plugin with options example
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/src/data/`,
name: "data",
},
}
]
使用StyledComponents和axios等npx package需要
也可以指定本地路径来安装插件。
配置
gatsby-config.js -> Gatsby配置.js
盖茨比-Node.js
在构建时只被调用一次,可以动态生成页面或添加GraphQL节点。
实践部分
gatsby new blog https://github.com/gatsbyjs/gatsby-starter-hello-world
使用styled-components
安装模块和插件。
npm install --save gatsby-plugin-styled-components styled-components babel-plugin-styled-components
module.exports = {
plugins: [`gatsby-plugin-styled-components`],
}
使用TypeScript
我不确定它是否会有多大参考价值,但您需要安装插件。
npm install gatsby-plugin-typescript
{
"include": ["./src/**/*"],
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"lib": ["dom", "es2017"],
"jsx": "react",
"strict": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"noEmit": true,
"skipLibCheck": true
}
}
使用TypeScript的优点有多大,根据官方正在努力使用PropsTypes的情况来看,我认为加入TypeScript是可以的。
语法高亮
只要依赖于Gatsby的插件,就能轻松地安装插件。
npm i -S gatsby-remark-prismjs
我会将其添加到gatsby-transformer-remark插件中。
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-prismjs`,
]
}
}
]
可以获取到带有class的HTML的查询,然后您可以自行指定样式,或者只需加载预设的主题即可。
gatsby-browser.js的意思是gatsby框架的浏览器端配置文件。
require("prismjs/themes/prism-solarizedlight.css")
把标签进行分类分配
搜索引擎优化
文档中包含了SEO组件。
部署(GitHub页面)
只需安装插件并进行推送即可。
插件
如果使用编辑器的插件,可能会在graphql输入中实现插值功能。
对此的想法
因为听说很简单,所以我以为可以在看Qiita的教程的同时大概30分钟就可以搞定,但结果我还是不得不阅读很多文档,花了相当长的时间。
仅仅依靠教程可能会让你产生“为什么啊?”的疑问,所以如果有余力的话,我建议你看一下recipes和content-and-data,这样可以加快理解速度。如果对按照规范写作没有困难的话,我认为这相当简单。
虽然我说了这么多,但我认为从自己喜欢的起步项目开始,稍作改动是最划算的选择。