gatsby_如何利用静态站点生成器Gatsby.js来利用您的React技能

谢夜洛
2023-12-01

gatsby

Sometimes a dynamic single-page app is overkill. You just need to get some attractive information on the internet. Welcome back to static sites. With the Gatsby.js framework, you don’t have to leave your React skills behind in the pursuit of faster, better, weaker.

有时,动态单页应用程序会显得过大。 您只需要在互联网上获取一些有吸引力的信息。 欢迎回到静态站点。 使用Gatsby.js框架,您不必为了追求更快,更好,更弱而放弃React技能。

什么是静态网站,为什么要一个? (What is a static site and why do you want one?)

A static site, as opposed to a dynamic site, is one that a) does not interact with a database, and b) looks the same for everyone. Each page of a static site exists as a separate file.

相对于动态站点,静态站点是a)不与数据库交互,b)每个人看起来都一样的站点。 静态站点的每个页面都作为单独的文件存在。

If you’ve worked with React or most other front-end frameworks, you’ll recognize that this is different than our current favorite model of a “single page site” — you may click links, but you always stay “on the same page”. Every React site on the internet is rendered almost completely within the app div of a very basic HTML page. Everything inside of the div is generated dynamically. Often very specifically for the user in front of the computer.

如果您使用过React或大多数其他前端框架,那么您会发现这与我们当前最喜欢的“单页面站点”模型不同–您可以单击链接,但始终保持在同一页面上”。 互联网上的每个React网站几乎都完全在一个非常基本HTML页面的app div中呈现。 div内部的所有内容都是动态生成的。 通常非常适合计算机前的用户。

It may be further helpful to understand some of the things a static site cannot do:

了解静态站点无法执行的某些操作可能会进一步有所帮助:

  • Render pages dynamically based on database information (displaying user information at /user/<user-id>, for instance)

    根据数据库信息动态呈现页面(例如,在/user/<user- id>上显示用户信息)

  • Generate and use logins / user authentication

    生成并使用登录名/用户身份验证
  • Be assured of any persistence of data (you can use cookies, of course, but your users are always free to trash them)

    确保数据的持久性(当然,您可以使用cookie,但是您的用户始终可以随意丢弃它们)

优点 (Advantages)

Static sites are fast, as they don’t need to talk to any database to get their information. They are also already rendered and built when the user requests the page from their browser, so it is available instantaneously (image loading notwithstanding, of course). All the code needed to run your website is provided to the browser and it runs locally.

静态站点速度很快 ,因为它们无需与任何数据库进行对话即可获取其信息。 当用户从浏览器请求页面时,它们也已经被渲染和构建,因此该页面是即时可用的(尽管加载了图像)。 运行您的网站所需的所有代码都提供给浏览器,并且在本地运行。

Static sites can be hosted simply. No Heroku falling asleep, no whirring up servers. It goes without saying that this is the cheapest way to get your content into the world. Most will be satisfied with the free options for simple sites.

静态站点可以简单地托管 。 没有Heroku入睡,没有唤醒服务器。 不用说,这是将您的内容发布到世界上的最便宜的方法。 大多数人会对简单网站的免费选项感到满意。

Static sites are stable. The only barrier to more and more users loading your site is the hosting server where you have your files. No worries about database loads or processing. It’s just sending over HTML, CSS and Javascript files, and it can do it as quickly as your host allows.

静态站点是稳定的 。 越来越多的用户加载您的站点的唯一障碍是托管服务器,您可以在其中托管文件。 不用担心数据库加载或处理。 它只是通过HTML,CSS和Javascript文件发送,并且可以在主机允许的范围内尽快完成发送。

缺点 (Disadvantages)

All the major disadvantages are baked into the very concept of a static site: difficulty in updating content and lack of response to users. If your project requires logins, a static site isn’t the right thing for you. If you have a great deal of content, or similar content you want displayed in similar ways, this may also be the wrong tool.

所有主要缺点都体现在静态网站的概念中:难以更新内容以及对用户缺乏响应。 如果您的项目需要登录,则静态网站不适合您。 如果您有大量内容,或想要以类似方式显示类似内容,则这可能是错误的工具。

I don’t personally think a blog is a good candidate for a tool like this, because it requires too many steps to go from creation to publishing. If you’ve used something like Wordpress, it’s going to feel like a slog to get things live. Then again, you control your content from front-to-back, and that’s very attractive for many people.

我个人不认为博客是使用这种工具的理想选择,因为从创建到发布需要太多步骤。 如果您曾经使用过诸如Wordpress之类的工具,那将使一切变得生动。 再说一次,您可以从头到尾控制您的内容,这对许多人来说非常有吸引力。

The rest of this article will tackle the how of making a static site. Just a few years ago, if you wanted one, you’d have to write everything from scratch. Then potentially deploy via FTP or the like. But I’m here to say: you can build static websites using your React skills. Let’s jump in.

本文的其余部分将介绍如何制作静态网站。 就在几年前,如果您想要一个,就必须从头开始编写所有内容。 然后可能通过FTP等部署。 但是我要说的是:您可以使用自己的React技能来构建静态网站。 让我们跳进去。

我的项目 (My Project)

The reason I got into Gatsby.js in the first place is that I wanted to redo my portfolio site. I’d been using a modified template that I was uploading to my hosting site via FTP. It was such a pain in the butt to update, I’d gone literally years without touching it. I didn’t want to build it in React because then I’d have to host it on Heroku. Heroku puts its free tier apps to sleep if no one is using them — a delay I find unacceptable. I knew a static site would be much faster and would never have to sleep.

首先进入Gatsby.js的原因是我想重做我的投资组合网站。 我一直在使用经过修改的模板,该模板已通过FTP上传到托管站点。 更新的屁股实在是太痛苦了,我已经走了好几年没有碰它。 我不想在React中构建它,因为那时我必须在Heroku上托管它。 如果没有人使用Heroku,Heroku会将其免费应用程序置于睡眠状态,我认为这是无法接受的。 我知道静态站点会更快,并且永远都不需要睡觉。

I was delighted to find static site generators built in React! I could put my React skills to use building something I could deploy on Github pages. Score!

我很高兴找到在React中构建的静态站点生成器! 我可以将我的React技能用于构建可以部署在Github页面上的东西。 得分!

If you’re the kind of person who wants to jump right into the code, you are welcome to the github repo for my portfolio.

如果您是那种想直接进入代码的人,那么欢迎您访问我的投资组合github存储库

Gatsby.js与Next.js (Gatsby.js vs. Next.js)

In the course of researching this article, I found a lot of people pointing to Next.js. It does have an option to export static content, but it is more commonly run on a server (enter Heroku sleeping) and is typically used for folks who want to employ server-side rendering. I can’t speak to it as a tool for such, but it looks neat and if you need to do some SSR, you should give it a look.

在研究本文的过程中,我发现很多人都指向Next.js。 它确实具有导出静态内容的选项,但是它通常在服务器上运行(进入Heroku睡眠状态),通常用于想要使用服务器端渲染的人们。 我不能将其作为实现此目的的工具,但是它看起来很整洁,如果您需要执行一些SSR,则应该看看它。

For me, various interwebs recommended Gatsby.js. I instantly fell in love when I got to work on my own portfolio.

对我来说,各种互联网都推荐Gatsby.js。 当我开始自己的作品集时,我立即坠入爱河。

为什么选择盖茨比? (Why Gatsby?)

In a word: React. I already know how to build things in React and Gatsby leverages that skillset for me. But there’s more. Lots more.

一句话: React 。 我已经知道如何在React和Gatsby中构建东西,从而为我充分利用了这一技能。 但是还有更多。 还有更多。

社区 (Community)

Gatsby has a loyal following and scads of people developing libraries for use with the framework. As of this writing, there are 545 plugins for Gatsby. Additionally, you can use a great many of the standard React libraries for building your site.

盖茨比(Gatsby)有一群忠实的追随者,他们开发用于该框架的图书馆。 截至撰写本文时, Gatsby已有545个插件 。 另外,您可以使用许多标准的React库来构建您的站点。

GraphQL,API和互联网上的所有数据 (GraphQL, APIs, and all the data the internet has)

At build time (when you, the developer, build the site, and not when the user visits it), Gatsby can reach out to the internet and grab all the information your heart could desire from wherever you want to get it. Here you can access any API, including ones you’ve built. Gatsby then folds this data into the HTML it’s generating, and creates the pages based on that data.

在构建时(当您,开发人员构建站点时,而不是在用户访问该站点时),Gatsby可以连接到Internet并从您想从任何地方获取所需的所有信息。 在这里,您可以访问任何API,包括您已构建的API。 然后,盖茨比将这些数据折叠到它正在生成HTML中,然后根据该数据创建页面。

GraphQL is built right into the build package, so you can use a tool you may already be familiar with. If you’d prefer to use something like fetch (or the more widely supported axios) that’s fine too. Because you’re more or less writing React, you can use whatever React packages float your boat.

GraphQL内置在build软件包中,因此您可以使用可能已经熟悉的工具。 如果您更喜欢使用fetch东西(或者更广泛支持的axios ),那也很好。 因为您或多或少都在编写React,所以您可以使用随便什么React包。

Of course, because there’s no server interaction when the site is live, Gatsby dumps the data into JSON files. Gatsby pulls from there for rendering.

当然,由于该站点处于活动状态时没有服务器交互,因此Gatsby将数据转储到JSON文件中。 Gatsby从那里拉出来进行渲染。

内置延迟加载图像 (Built-in lazy loading of images)

If you’ve ever resized images for the web, you know how annoying it can be to deal with displaying images at a reasonable speed. Enter gatsby-image. This plugin allows you to pre-load your images and deliver them in the appropriate size for the browser, at that time.

如果您曾经为Web调整过图像的大小,那么您就会知道以合理的速度处理图像是多么令人讨厌。 输入gatsby-image 。 此插件可让您预先加载图片,并在那时以适合浏览器的尺寸交付它们。

快速燃烧 (Blazing fast)

Gatsby includes out-of-the-box code and data splitting, so your site will explode out of the gates. It also pre-fetches data for the parts of the site you are not looking at. When the time comes, it’s ready to throw new information at your users.

Gatsby包括开箱即用的代码和数据拆分功能,因此您的网站将一炮而红。 它还会预取站点中您未查看的部分的数据。 时间到了,就可以向用户抛出新信息了。

开箱即用的东西 (Out-of-the-box Goodies)

Gatsby makes it easy to get started. Second to being built on React, my favorite part of Gatsby is the automatic routing.

Gatsby使入门变得容易。 除了基于React之外,我最喜欢的Gatsby部分是自动路由。

路由 (Routing)

There’s a pages folder, and into it you place all of the links for your site. So you might have an index page, which you will by convention name index.js. You might also have an about page and maybe a contact page. Gatsby wants you to name the files in your pages folder the same as the links for your site.

有一个pages文件夹,在其中放置了网站的所有链接。 因此,您可能会有一个索引页,按照约定,该页将被命名为index.js 。 您可能还会有一个about页面,甚至一个contact页面。 Gatsby希望您将pages文件夹中的文件命名为站点链接

So when you make a About.js and Contact.js you will generate routing to /about and /contact automatically. Into these parent components you will place any code you want, including additional components, that will go and live somewhere other than your pages folder.

因此,当您创建About.jsContact.js您将自动生成到/about/contact路由。 在这些父组件中,您将放置任何您想要的代码(包括其他组件),这些代码可以在pages文件夹以外的地方使用。

If you have ever set up React Router, this feels like a damn revelation. There’s literally no work to be done at all. You put the correctly named parent components (you might have called them containers in your React projects) into the pages folder. Gatsby does all the work for you.

如果您曾经设置过React Router,那感觉就像是该死的启示。 实际上根本没有任何工作要做。 您将正确命名的父组件(您可能已在React项目中将其称为containers )放入了pages文件夹中。 盖茨比为您完成所有工作。

To link between pages, use a simple <Link to='/contact'>Contact&lt;/Link>.

要在页面之间链接,请使用简单的<Link to='/contact'>Contact& lt; / Link>。

工装 (Tooling)

The other great thing about Gatsby is how incredibly easy it is to get up and running. There’s a CLI tool, of course, so it’s a simple matter of:

关于盖茨比的另一件事是,启动和运行非常容易。 当然,有一个CLI工具,因此很简单:

npm install --global gatsby-cli
gatsby new site-name
gatsby develop

Gatsby takes care of everything, just like create-react-app. You’ve got hot reloading out of the box. When you’ve finished and are ready to send the bad boy off to your hosting provider, it’s just gatsby build and send that static content anywhere you want.

Gatsby会处理一切,就像create-react-app 。 开箱即用,您可以进行热重装。 完成并准备将坏孩子发送给托管服务提供商后,这就是gatsby build ,并将该静态内容发送到您想要的任何地方。

入门库 (Starter Libraries)

Another great thing about the community is the large number of starter libraries available so that you don’t have to begin each project from square one. If you know you want a blog, or a powerpoint-like presentation site, or even something that comes with design baked in, Gatsby can send you down that path quickly and efficiently.

社区的另一个很棒的事情是可用的启动库数量很多,因此您不必从每个项目开始。 如果您知道想要博客,类似于Powerpoint的演示站点,甚至是内置了某些设计的东西,盖茨比(Gatsby)都可以Swift有效地将您引向这条路。

(Make sure you pick a starter that is based on version 2 of Gatsby! I learned this one the hard way: upgrading was not pleasant.)

(确保您选择的是基于Gatsby版本2的启动程序!我很难学到这一点:升级并不令人愉快。)

代码 (The code)

So let’s take a look at what Gatsby project code looks like.

因此,让我们看一下Gatsby项目代码的外观。

layouts / index.js (layouts/index.js)

We start where the app starts: our components/layout.js. Here’s what mine looks like, after I delete some starter loading code I don’t particularly need or want:

我们从应用程序的开始位置开始: components/layout.js 。 这是我的样子,在删除一些我不需要或不需要的启动程序加载代码后:

import React from 'react'
import '../assets/scss/main.scss'

import Header from '../components/Header'
import Footer from '../components/Footer'

class Template extends React.Component {
  render() {
    return (
      <div className='body'>
        <Header/>
        {this.props.children}
        <Footer/>
      </div>
    )
  }
}

export default Template;

By convention we will wrap any page in this Template component. If we need different templates, of course we may use them wherever we like.

按照惯例,我们会将所有页面包装在此Template组件中。 如果我们需要不同的模板,那么我们当然可以在任何需要的地方使用它们。

(Note: Gatsby v1 automatically grabbed code from your layouts/index.js and applied it to all pages. Gatsby v2 expects you to manage your layouts manually.)

(注意:Gatsby v1自动从您的layouts/index.js代码并将其应用于所有页面。Gatsbyv2希望您手动管理布局。)

We need to import our stylesheet. And look — we can use Sass! You’ll need to add node-sass and gatsby-plugin-sass, but otherwise write your sass, import it at the top of your site and be happy.

我们需要导入样式表。 看看-我们可以使用Sass! 您需要添加node-sassgatsby-plugin-sass ,否则,请编写您的sass,将其导入网站的顶部,然后感到高兴。

pages / index.js (pages/index.js)

pages/index.js is where our app really “starts”.

pages/index.js是我们的应用程序真正“启动”的地方。

Here’s the whole component for my site. I …ed the texts to shorten things, but otherwise I left everything here so you can see that Gatsby code looks exactly like React code, because it is.

这是我的网站的整个组件。 我…编辑了文本以缩短内容,否则我将所有内容都留在了这里,因此您可以看到Gatsby代码看起来完全像React代码,因为它确实如此。

import React from 'react'
import me from '../assets/images/main/me.png'
import Helmet from 'react-helmet'
import Template from '../components/layout'
import Photography from '../components/Photography'
import Miscellaneous from '../components/Miscellaneous'

class IndexPage extends React.Component {
  state = {}

  ChevronLink = () => [...]

  render() {
    const { showMiscellaneous, showPhotography } = this.state

    return (
      <Template>
        <div>
          <Helmet>
            <meta charSet="utf-8"/>
            <title>Amber Wilkie, Software Engineer</title>
          </Helmet>

          <section id="aboutMe" className="main style1">
            <div className="grid-wrapper">
              <div className="col-6">
                <header className="major">
                  <h2>About Me</h2>
                </header>
                <p>Hi, it's me...</p>
                <div className='about-me-links' >
                  <a href='http://www.medium.com/@heyamberwilkie'>Tech Blog</a>
                  {this.ChevronLink('showPhotography', 'Photography')}
                  {this.ChevronLink('showMiscellaneous', 'Etc')}
                </div>
              </div>
              <div className="col-6">
                <span className="image fit">
                   <img src={me} alt="Amber near Dresden, Germany"/> 
                </span>
              </div>
            </div>
          </section>
          {showPhotography && <Photography />}
          {showMiscellaneous && <Miscellaneous/>}
        </div>
      </Template>
    )
  }
}

export default IndexPage;

Everything is pretty basic React stuff here: some spans that toggle sections of the site, imports/exports, you know this stuff. The only thing you might pay attention to is that we must import and then reference imported elements. I can’t “link” a local image: at build time, those references are generated dynamically. If you want to reference any of your assets, you’ll need to import them.

这里的一切都是非常基本的React内容:一些跨度切换网站的各个部分,导入/导出,您知道这些东西。 您可能要注意的唯一事情是,我们必须先导入然后引用导入的元素。 我无法“链接”本地映像:在构建时,这些引用是动态生成的。 如果要引用任何资产,则需要导入它们。

资料撷取 (Data fetching)

The most interesting component in my site is Photography . Again, I’ve removed some code and …ed others to make room for the important bits.

我的网站中最有趣的组件是Photography 。 同样,我删除了一些代码,并…另一些代码为重要的位子腾出空间。

import React, { Component } from 'react'
import { StaticQuery, graphql } from 'gatsby'
import Img from 'gatsby-image'
import { CSSTransition } from 'react-transition-group'
import { travelDescriptions } from '../utilities/constants'

class Photography extends Component {
  state = {
    currentImage: this.props.data.Images.edges[0].node,
    imageIndex: 0,
  }

  changeImage = () => [...]

  render() {
    const { currentImage } = this.state
    const imageSizes = currentImage.childImageSharp.sizes
    const imageName = currentImage.name

    return (
      <section id="photography" className="main style2">
       <div className="grid-wrapper">
         <div className='col-3'>
           <header className="major">
             <h2>Photography</h2>
           </header>
           <CSSTransition>
             [... photo descriptions ...]
           </CSSTransition>
         </div>
         <div className="col-9 image-holder">
           <div key={imageName}>
             <div className='left' onClick={() => this.changeImage(-1)}/>
           <Img
            title={imageName}
            alt={imageName}
            sizes={imageSizes}
            className="border-radius"
           />
          <div className='right' onClick={() => this.changeImage(1)}/>
        </div>
      </div>
    </div>
  </section>
)
  }
}

const query = graphql`
    query imagesQuery {
        Images: allFile(
            sort: {order: ASC, fields: [absolutePath]}
            filter: {relativePath: {regex: "/travel/"}}
        ) {
            edges {
                node {
                    relativePath
                    name
                    childImageSharp {
                        sizes(maxWidth: 1500) {
                            ...GatsbyImageSharpSizes
                        }
                    }
                }
            }
        }
    }
`
export default () => <StaticQuery
  query={query}
  render={data => <Photography data={data}/>}
/>
export default () => <StaticQuery  query={query}  render={data => <Photography data={data}/>}/>

GraphQL数据获取 (GraphQL data fetching)

Let’s look at the last part of that component. Though your site will be static at runtime, it can pull all kinds of data at build-time. Here’s where our GraphQL fetching comes in, included as part of Gatsby’s core library. Because I’m working in a component, I am required to use Gatsby’s StaticQuery, which will pass the results of my query into this.props.data.

让我们看一下该组件的最后一部分。 尽管您的站点在运行时将是静态的,但它可以在构建时提取各种数据。 这是我们的GraphQL获取的地方,它是Gatsby核心库的一部分。 因为我正在使用组件,所以需要使用Gatsby的StaticQuery ,它将把查询结果传递到this.props.data

If I were making this query on a page, I could simply dump my query into the code. It would automatically pass results to this.props.data. Note that StaticQuery cannot receive props, but anonymous queries on pages can.

如果要在页面上进行此查询,则可以简单地将查询转储到代码中。 它将自动将结果传递给this.props.data 。 请注意, StaticQuery无法接收道具,但是页面上的匿名查询可以。

It does the same thing here. If you get a more complicated data structure going on, you may prefer to create a data layer that can pass down data props instead. Here we’ll need the GraphQL query on the page to get data in props.

它在这里做同样的事情。 如果您遇到了更加复杂的数据结构,则可能更喜欢创建一个可以传递data属性的数据层。 在这里,我们需要页面上的GraphQL查询来获取道具中的data

This is just one example of how Gatsby can fetch data from within your local folders. For more, check the GraphQL reference from the Gatsby docs. There are a number of image-grabbing tools as well, baked right into the framework. More examples in the docs on this as well.

这只是Gatsby如何从本地文件夹中获取数据的一个示例。 有关更多信息,请查看Gatsby docs中的GraphQL参考。 也有许多图像捕捉工具,直接嵌入到框架中。 文档中的更多示例也是如此。

But here we’ll just talk about what I’m doing. I’m looking for any files in my travel folder. Then childImageSharp will create an array of sizes, which we pass into the Img component (from the massively popular gatsby-image plugin). Img will create a blurry placeholder for us and also provide efficient image sizes based on our browser size. Pretty neat, right?

但是在这里,我们只讨论我在做什么。 我正在寻找我的travel文件夹中的任何文件。 然后childImageSharp将创建一个尺寸数组,我们将其传递给Img组件(来自广受欢迎的gatsby-image插件)。 Img将为我们创建一个模糊的占位符,并根据我们的浏览器大小提供有效的图像大小。 很整洁吧?

Finally, don’t forget that image key. You’re not mapping over anything, but gatsby-image expects you to tell it where the image is loading so it can make that pretty blurred placeholder.

最后,不要忘记该图像key 。 您没有在任何内容上进行映射,但是gatsby-image希望您告诉它图像的加载位置,以便可以使该占位符变得非常模糊。

奖励:在Netlify上部署 (Bonus: deploy on Netlify)

It’s even easier to get your code on the internet with Netlify. These guys let you skip the build step and just upload your content to Github. Netlify will take your code from repo to available online, and basic tier is free, and includes SSL. There’s even a (ridiculously easy) step-by-step guide for getting Gatsby pages up and running. Every time you commit to master on Github, a Netlify build will be triggered. Because Gatsby grabs data from internal and external sources at build time, you’ll get new data every time a build is run.

使用Netlify在互联网上获取代码更加容易。 这些家伙让您跳过了构建步骤,只是将您的内容上传到Github。 Netlify将把您的代码从存储库带到在线可用,并且基本层是免费的,包括SSL。 甚至还有一个(非常简单的) 分步指南,用于启动和运行Gatsby页面 。 每次您承诺在Github上掌握时,都会触发Netlify构建。 由于Gatsby在构建时会从内部和外部来源获取数据,因此每次运行构建时都会获得新数据。

奖励:使用IFTTT自动部署 (Bonus: auto-deploy with IFTTT)

As an extra step, you might consider creating an auto-deploy of your site, so you can grab new content from your external sources. For instance, it’s possible to add Medium article summaries through the gatsby-source-medium plugin (which I can attest is magically easy to set up).

作为额外的步骤,您可以考虑创建网站的自动部署,以便可以从外部资源中获取新内容。 例如,可以通过gatsby-source-medium插件添加Medium文章摘要(我可以证明这很容易设置)。

Netlify will provide you with a URL for making POST requests. When you do, it will trigger a re-build and deploy of your site. You can condition this on whatever you want, using whatever tool you like.

Netlify将为您提供用于发出POST请求的URL。 当您这样做时,它将触发站点的重新构建和部署。 您可以使用所需的任何工具,以所需的任何条件为条件。

I can champion IFTTT, a service that will make your day if you’ve never heard of it before. If This Then That creates webhooks for you. So you can condition a build on, say, publishing a new Medium article. IFTTT will handle the listener and the action. If you publish to Medium, it will send that POST request. Your Gatsby site will pull in the new content via its GraphQL query to Medium. Your site will be re-deployed with your new article summary.

我可以为IFTTT提倡 ,如果您从未听说过的话,它将为您带来美好的一天。 如果这样做,那么将为您创建webhooks。 因此,您可以根据发布新的Medium文章来进行构建。 IFTTT将处理侦听器和操作。 如果您发布到Medium,它将发送该POST请求。 您的Gatsby网站将通过其GraphQL查询将新内容拉入Medium。 您的网站将与您的新文章摘要一起重新部署。

Go get it, friends.

去吧,朋友。

参考文献 (References)

翻译自: https://www.freecodecamp.org/news/how-to-leverage-your-react-skills-with-static-site-generator-gatsby-js-81843e928606/

gatsby

 类似资料: