Gatsby is introduced
What is Gatsby
Gatsby is an open source framework for static sites based on React that helps developers build extremely fast websites. It can be said that it is a static site generator. The main application technologies of Gatsby are React and GraphQL.
Liverpoolfc.tv: Gatsby
Why Gatsby
Gatsby can quickly use the React ecosystem to generate static websites with higher performance, and The Gatsby ecosystem is also powerful.
When you want to build a personal blog by yourself, you should consider SEO, and you do not need to pay attention to the complex deployment Settings such as database and server. The website Gatsby built is a static site, so you can easily deploy the website on many services. Gatsby doesn’t need to wait for requests to generate pages. Instead, it generates pages in advance, so the website is fast.
Gatsby adopted React, React-Router, Webpack, GraphQL and other new technologies, which also followed the technological trend.
GraphQL introduction
We talked about GraphQL, if you’re not familiar with it.
❝
GraphQL is a query language for apis and an alternative to Restful apis.
❞
As for the replacement of Restful apis, I personally feel that Restful apis now occupy an absolutely dominant position, and it is still difficult to be shaken at present. For now, GraphQL has its drawbacks.
Don’t be afraid to see that you haven’t learned GraphQL, because you don’t use it much and Gatsby has a built-in interface for us to operate. GraphQL is very popular in foreign countries. As a new technology, we can have a look at it without going into depth.
Here, of course, we have to extol its advantages, the above definition you may wonder, isn’t the API written back end interface, how can still query?
GraphQL is a graphical Query Language that describes the syntax of how a client requests data from a server. That sounds vague, but what pain points does its relatively Restful API address?
- Ask for the data you want no more, no less
I’m sure most of you have encountered a scenario, such as a project management system, where you go to a page and show a list, and the list only shows the title, but you ask for more data, such as who created it, when it was created, etc. This information is redundant here, but it may have its own raison d ‘etre, or other scenarios need to return it, so the interface contains all the data directly.
At this point, GraphQL gets exactly what you want, no more, no less, and returns whatever data you want. The data is controlled by the application, not the server.
- Obtaining multiple resources requires only one request
GraphQL queries can not only retrieve the attributes of a resource, but also further query along inter-resource references. While typical REST apis load multiple urls to request multiple resources, GraphQL can get all the data you need for your application in a single request. As a result, applications using GraphQL are fast enough to perform even over slow mobile connections.
- Describes all possible type systems
The GraphQL API is organized based on types and fields, not entry endpoints. You can get all your data capabilities from a single entry point. GraphQL uses types to ensure that applications only request possible data, and also provides clear auxiliary error messages. Applications can use types instead of writing manual parsing code.
Gatsby used GraphQL as a way to manage resources locally.
Set up the project
start
- Installation of Gatsby Scaffolding
npm install -g gatsby-cli
Copy the code
- New project
❝
Gatsby New [projectName][Starter] : Creates a new project based on the starter
❞
gatsby new gatsby-blog-demo https://github.com/gatsbyjs/gatsby-starter-hello-world
Copy the code
We use the official hello-world template for development, if you use it directly
gatsby new gatsby-blog-demo
Copy the code
By default, the gatsby-starter-default is used to create a new project
- Run the project
cd gatsby-blog-demo
gatsby develop
Copy the code
Open localhost:8000 and you’ll see Hello world!
Common commands
Here are some of the commands Gatsby used:
- Gastby Develop: Start the hot loading development environment
- Gastby Build: Package in public all the static resources, static pages, and JS code needed to build an optimized static site for production
- Gatsby Serve: After you pack, start a local service where you can test the static web pages just generated by the “Gatsby Build”
GraphiQL
Open http://localhost:8000/__graphql and you’ll see the GraphQL debug interface, where you can view all the data and see if the debug Query statement returns the corresponding data. Query statements can be generated automatically by clicking on the left.
Possible warnings
If your console appears after running:
React-Hot-Loader: react-hot-dom patch is not detected. React 16.6+ features may not work.
Copy the code
It can be solved like this:
npm install @hot-loader/react-dom
Copy the code
Create a new gatsby-node.js file in the root directory
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' } } } Copy the code
Restarting the project eliminates this warning
The project structure
├ ─ ─ the cache├ ─ ─ the public├ ─ ─ the SRC| └ ─ ─ pages / / files under this folder will be mapped to routing| └ ─ ─ index. Js├─ Static // Static Resources├ ─ ─ prettierignore├ ─ ─ prettierrc├─ Gatsby -config.js // Basic Configuration file├ ─ ─ LICENSE├ ─ ─ package. Json├ ─ ─ the README, md└ ─ ─ yarn. The lockCopy the code
Gatsby Configuration file
The initial template here has only one configuration file, whereas a typical project has four
gatsby-config.js
Basic configuration files. The entire Gatsby site configuration file. You can configure the basic information of the website in it.
gatsby-node.js
Node configuration files. This file is only run once during builds, such as dynamically creating some pages.
gatsby-browser.js
Client configuration. Some browser-specific apis are implemented in this file, such as listening for route changes, registering serviceworkers, and so on.
gatsby-ssr.js
The server renders the configuration file. Use Gatsby’s server rendering API to customize the default Settings that affect server rendering.
Create the page
Routing page
We create a file about. Js in the pages directory, and the route path is /about
import React from 'react'
const About = (a)= > {
return <div>about me</div>
}
export default About Copy the code
Open the http://localhost:8000/about, shows the page we just created
404 pages
The file name in the Pages directory is the routing path, but there is a special one. When the path cannot be matched, Gatsby will jump to the 404 page. If we create the file name 404.js under pages, our self-defined 404 page will be used. Current we just input a nonexistent page path: http://localhost:8000/test, would be an error page.
Let’s create a new file called 404.js
import React from 'react'
const About = (a)= > {
return <div>404 page does not exist</div>
}
export default About Copy the code
Enter another path to display the page:
Gatsby makes sure the 404 page is built as 404.html, which is created for us by default. It also lists all the page routing links on the site. We can see the 404 page we just created by clicking on the Preview Custom 404 Page.
So we want to go directly to our custom 404 page, which requires us to click to jump to. The reason is that in the development environment, when Using Gatsby Develop, Gatsby overwrites our custom 404 pages with the default 404 page, which is actually already in effect.
We can package, start a local service, simulate an online environment, and then directly display our custom 404 page.
gatsby build
gatsby serve
Copy the code
Then open the http://localhost:9000/test (arbitrary path), will be able to jump to a custom 404 page for us
Creating layout components
-
Create a new directory SRC/Components.
-
Create a layout component file SRC/Components /layout.js in the directory above:
import React from 'react'
export default ({ children }) => (
<div style={{ margin: `3rem auto`, maxWidth: 650.padding: `0 1rem` }}>{children}</div>
)
Copy the code
- in
src/pages/index.js
Add the Layout component to the
import React from 'react'
import Layout from '.. /components/layout'
export default function Home() {
return <Layout>Hello world!</Layout>
} Copy the code
This keeps the entire screen centered, and the basic actions of React are here
Setting CSS Styles
Styles in Gatsby can take many forms, but we won’t mention the common import ‘./xxx. CSS.
Use global styles
One of the most straightforward ways to add global styles to a website is to use global.css stylesheets.
Create folder styles under SRC and add a global.css file
html {
background-color: #f5f5f5;
}
Copy the code
- In the create Gatsby -browser.js directory, import the style file
import "./src/styles/global.css"
Copy the code
Restart the local service and notice that the background of the page has changed to light gray.
Use CSS Modules to style components
CSS Modules reduce global contamination and prevent naming conflicts and style overwriting.
❝
The CSS Module is implemented by changing the names of all modular classes to unique names, that is, adding some unique prefixes or suffixes. This prevents overwriting and conflicting styles written by different people in a project.
❞
- Creating a CSS File
src/styles/index.module.css
.title {
color: red;
}
.text {
color: blue;
} Copy the code
Usage: 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> ) } Copy the code
Running results:
Print styles to see the result of the imported processing:
If you compare this to a CSS file, you’ll see that each format is now a key that points to a long string in the import object, for exampletitle
Point to theindex-module--title--1i-Wh
. These style names are generated by the CSS module. Make sure they are unique on your site. And because you have to import them to use these classes, it’s fine to use these CSS styles anywhere.
Other ways of dealing with CSS
CSS styles are enough, others like Sass, etc. There are also STYLES of CSS in JS, such as Emotion, Styled Component. You can go to the official website to check the supported Gatsby plug-in, then you can use it.
Get the data in Gatsby
When building a website, you may need to reuse some common data – such as common site titles, author information, etc. We can’t add it on every page, so we store the title in one location and reference that location from other files, and only change it in one place.
The location of this common data is the siteMetadata object in the Gatsby -config.js file. Open this file and write the code:
module.exports = {
/* Your site config here */
siteMetadata: {
title: `Title from siteMetadata`,
author: 'jacky'
}, plugins: [], } Copy the code
Restart the service
Using page query
Edit the SRC/pages/about. Js
import React from 'react'
import { graphql } from 'gatsby'
// The data obtained by GraphQL is passed to the page component as parameters
// Data is of the form {errors, data}, without errors there would be no 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 } } } ` Copy the code
And then you pull out the data
Where the GraphQL query statement is:
{
site {
siteMetadata {
title,
author
} } } Copy the code
This is the GraphQL query statement. You can open the built-in GraphQL debugging interface of Gatsby http://localhost:8000/__graphql.
The site here is the configuration of the site written by our gatsby-config.js.
Click site and siteMetadata on the left successively, and then there are title and author fields we wrote just now for us to choose. At the same time, the middle box will generate query statement, and finally click the run button to output the query result.
When you need to get more complex nested data later, you can directly find and click in this interface, automatically generate query statements on the line.
You can get as much data as you want. For example, I want to get the title and not the author
export const query = graphql`
query {
site {
siteMetadata {
title
} } } ` Copy the code
Queries using non-page components (static queries)
Note here that we need to distinguish between the two query methods. The query method in the above example is only applicable to page query, that is, routing interface under SRC/Pages. If GraphQL query is performed under non-page components, the above method cannot be used. The StaticQuery component or useStaticQuery hook should be used.
// page queryexport const query = graphql`
query{ ... }
`
Copy the code
For example, we create a component SRC/Components /header.js
- StaticQuery
import React from 'react'
import { graphql, StaticQuery } from 'gatsby'
const Header = (a)= > (
<StaticQuery query={graphql` query { site { siteMetadata { author } } } `} render={data= > { const { site: { siteMetadata }, } = data return <div>This is the Header component and the author is: {siteMetadata. Author}</div> }} /> ) export default Header Copy the code
Or use the useStaticQuery method
- useStaticQuery
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
const Header = () => {
const data = useStaticQuery(
graphql` query { site { siteMetadata { author } } } ` ) returnThe < div > this is the Header component, the author is: {data. Site. SiteMetadata. Author} < / div >} export default Header Copy the code
Then import the Header component in SRC /pages/index.js
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> ) } Copy the code
The running results are as follows:
The plug-in
gatsby-source-filesystem
This is the Data source plug-in of Gatsby, which converts all aspects of data into content that can be extracted locally through GraphQL for setting the file system of the project.
- Installing a plug-in
npm install --save gatsby-source-filesystem
Copy the code
- Configure in the gatsby-config.js file
module.exports = {
siteMetadata: {
title: `Title from siteMetadata`. author: 'jacky'. },
plugins: [ { resolve: `gatsby-source-filesystem`. options: { name: `src`.// The name can be used to filter path: `${__dirname}/src/`.// File path }, }, ].} Copy the code
Restart the service
Go to http://localhost:8000/__graphql and look at allFile and File options.
Let’s click on the optional “allFile” and select the ones shown below
Note that the data you are querying is basically under edges. Node. Node is a special name for an object in the graph, and each File node contains the field you are querying.
The ID,name, and relativePath fields we selected correspond to the files we created in our SRC directory, and there are many other fields to choose from, giving you a variety of information about the seven files we created.
If you can query it here, it means you can query it in the component and then use the data, so you can query it in the component and make a list of files.
Compared to the traditional React project, the React project can easily capture the data without doing any complicated work. Gatsby more powerful is its ecological, many plug-ins are match well, more can see the website of the plugin library is introduced: https://www.gatsbyjs.org/plugins/
gatsby-transformer-remark
This is the data conversion plugin, which is essential if we use Gatsby as our personal blog. We programmers use Markdown syntax to write blogs now, and parsing markdown syntax is a must for a blog.
- Installing a plug-in
npm install --save gatsby-transformer-remark
Copy the code
- Configure in the gatsby-config.js file
module.exports = {
/* Your site config here */
siteMetadata: {
title: `Title from siteMetadata`. author: 'jacky'. }, plugins: [ { resolve: `gatsby-source-filesystem`. options: { name: `src`.// The name can be used to filter path: `${__dirname}/src/`.// File path }, }, `gatsby-transformer-remark`.].} Copy the code
Restart the service
The plug-in adds two data fields, allMarkdownRemark and markdownRemark
- Creating an MD File
Create the _posts directory under SRC and add a first-blog.md file
---
title: "My first blog."
date: "2020-06-21"
tags: "React"
categories: "The React series"
--- ## This is the title of the first blog post Content of First Blog 1Copy the code
If the blog is not built by yourself, but directly on a platform to write, you may not understand the above syntax, at the beginning of the MD file – wrapped in frontMatter (preface), and then can add a variety of keywords in the article information.
We can then query the details of the MD file we wrote at http://localhost:8000/__graphql
Let’s change it a little bit and create two more MD files
second-blog.md
---
title: "My second blog post."
date: "2020-06-22"
tags: "Vue"
categories: "Vue series"
--- ## This is the title of the second blog post Second Blog content 2Copy the code
third-blog.md
---
title: "My third blog post."
date: "2020-06-23"
tags: "React"
categories: "The React series"
--- ## This is the title of the third blog post Third Blog content 3Copy the code
Query the data again and remove all the article data we just added
Since GraphQL can get the data, we can display it on a page.
Create a new file SRC /pages/blog.js and make a summary of the blog directory:
import React from 'react'
import Layout from '.. /components/layout'
import { graphql } from 'gatsby'
const Blog = ({ data }) = > {
return ( <Layout> <h1>Blog directory</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>Classification of {node. The frontmatter. Categories}</div> <div>Tags: {node. The 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 } } } } } ` Copy the code
Open the http://localhost:8000/blog, a blog directory is displayed:
The problem is, we can actually get the information for each blog post, but we have to link, which means click on the blog title, go to the blog details page, which is the post path, so we’re going to create the page.
Create pages using data
gatsby-node.js
This is the time to create the Gatsby -node.js file. The code in this configuration file is node layer specific.
Previously we said that all files in the SRC/Pages directory are rendered as routes, but it would not make sense if the detail pages of our blog posts required us to create our own JS file.
We will use two apis:
onCreateNode
Gatsby calls the onCreateNode function every time a new node (or update) is created.
Write the code to gatsby-node.js:
exports.onCreateNode = ({ node }) = > {
console.log(node.internal.type)
}
Copy the code
Restart the service, look at the terminal, and you’ll see a number of created nodes printed: SitePage, SitePlugin, Site, SiteBuildMetadata, Directory, File, MarkdownRemark, all we care about is MarkdownRemark, Modify the function so that it only records MarkdownRemark nodes; We use the name of each MD File as the path. To get the File name, you need to walk through its parent File, which contains the File data we need.
exports.onCreateNode = ({ node, getNode }) = > {
if (node.internal.type === `MarkdownRemark`) {
const fileNode = getNode(node.parent)
console.log(`\n`, fileNode.relativePath)
}
} Copy the code
Restart the service and view the terminal. The following output is displayed:
_posts/first-blog.md
_posts/second-blog.md
_posts/third-blog.md
Copy the code
To create a path, use the function attached with the Gatsby – source-Filesystem to create a path
const { createFilePath } = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({ node, getNode }) = > {
if (node.internal.type === `MarkdownRemark`) {
console.log(createFilePath({ node, getNode, basePath: `pages` }))
} } Copy the code
Restart the service. The following information is displayed:
/_posts/first-blog/
/_posts/second-blog/
/_posts/third-blog/
Copy the code
Next, we pass a function to the API, createNodeField, which allows us to create additional fields in nodes created by other plug-ins.
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, // The word slug is usually used to represent a path }) } } Copy the code
Restart the service, open http://localhost:8000/__graphql, you can query the path
createPages
CreatePages this API is used to add pages. Before you create a page, you need to have a page template so that you can specify which template to use when creating the page.
Create a new file SRC /templates/blog-post.js
import React from 'react'
import Layout from '.. /components/layout'
export default() = > { return (
<Layout> <div>Hello blog post</div> </Layout> ) } Copy the code
Then change the Gatsby – Node. js createPages function:
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, }, }) }) } Copy the code
Restart the service, enter a path to the default 404 page, and you’ll see the path to three automatically generated blogs. If you click on any of these, you’ll see the path to the blog-post.js component we just created.
We want to display blog content, so we need to modify the template file again:
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 } } } ` Copy the code
The above is a dynamic variable query method and GraphQL syntax, can look at (https://graphql.org/learn/queries/#variables)
When I’m done, say I click on the second blog post, I’ll be right on the page and displaying the content
To make things better, we added reachable links to the blog directory page, added slug query fields, and added Link redirect. This usage is almost the same as Link in the React route.
src/pages/blog.js
import React from 'react'
import Layout from '.. /components/layout'
import { graphql, Link } from 'gatsby'
const Blog = ({ data }) = > {
return ( <Layout> <h1>Blog directory</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>Classification of {node. The frontmatter. Categories}</div> <div>Tags: {node. The 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 } } } } } ` Copy the code
Now click on the blog, you can jump to the corresponding page, although the style page is not ugly, but just create a new MD file in the SRC /_posts directory, and then it will automatically refresh, which is a super easy blog.
Package online
Stop developing the service, build the production version, and export the static files to the public directory
gatsby build
Copy the code
To view the production environment version locally, run:
gatsby serve
Copy the code
Next, you can access the site we just made at localhost:9000
Github address of this project
That’s it for the tutorial.
- Ps: Personal technical blog Github warehouse, if you feel good welcome star, give me a little encouragement to continue writing ~