WEB程序员笔记

一个前端开发工程师的个人博客

盖茨比一传呼机

如何建立盖茨比网站?为什么在线指南如此零散?没有针对盖茨比的单一寻呼机指南,带有一个可行的示例吗?好吧,你已经找到了。这份一页指南将帮助您使用以下方法构建静态网站:

  • [x]基于Markdown的博客文章
  • [x]客户端搜索
  • [x]分页
  • [x]代码突出显示
  • [x] Google Analytics(分析)
  • [x]自适应设计,我们不会真正涉及到这一点,但是您可以看一下Github代码。

https://www.codeallnight.com上查看其运行情况,或查看git repo。随时在其之上构建。清空src/posts文件夹,然后开始编写自己的文件夹。

1.先决条件

首先,安装gatsby-cli并克隆仓库。克隆存储库是可选的,但是拥有一个示例代码并不总是更好吗?

npm install -g gatsby-cli
git clone [email protected]:djoepramono/code-all-night.git
cd code-all-night
npm install
gatsby develop -H 0.0.0.0

gatsby develop仅运行,使该站点仅可通过localhost在主机计算机上使用。但是有时您想使其可以被本地网络访问,以便可以使用手机测试站点。为此,您需要-H 0.0.0.0

本指南的每个部分都可能取决于特定的npm软件包。这些软件包已经包含在仓库中package.json。如果您不克隆存储库而重新开始,请确保安装它们。

2.降价帖子

可以在gatsby-transformer-remark的帮助下将Markdown文件制作成Gatsby页面

将您的markdown文件放入src/posts已经有一些例子了。接下来,您需要将以下条目放入gatsby-node.js

exports.createPages = async ({ actions, graphql, reporter }) => {
  const { createPage } = actions
  const blogPostTemplate = path.resolve(`src/templates/post.js`)
  const result = await graphql(`
    {
      allMarkdownRemark(
        sort: { order: DESC, fields: [frontmatter___date] }
        limit: 1000
      ) {
        edges {
          node {
            frontmatter {
              title
              date(formatString: "DD MMMM YYYY")
              author
              path
            }
            excerpt
            timeToRead
          }
        }
      }
    }
  `)
  // Handle errors
  if (result.errors) {
    reporter.panicOnBuild(`Error while running GraphQL query.`)
    return
  }

  // Create post pages
  result.data.allMarkdownRemark.edges.forEach(({ node }) => {
    createPage({
      path: node.frontmatter.path,
      component: blogPostTemplate,
      context: {},
    })
  })
}

上面的代码利用Gatsby的createPagesAPI为每个markdown帖子创建一个静态页面。每个markdown文件都可以使用frontmatter,在每个markdown文件顶部存在一组键值对来丰富。

在幕后,盖茨比使用了GraphQL,您可以在此处阅读更多内容。它还在http:// localhost:8000 / __ graphql处为您提供图形UI客户端。这是一个探索可以使用哪些查询的很好的工具。

如果您想更改模板,则可以更改src/templates/posts。这是一个React组件,因此如果您已经熟悉React,请多多注意

好吧,现在您应该知道会createPages做什么。

3.客户端搜索

在讨论分页之前,让我们先讨论搜索。我正在使用js-search来驱动搜索页面。这个概念非常简单,在post页面创建过程中,我们还希望为搜索页面构建上下文。如果您想了解更多,请在这里看看。

在您gatsby-node.js的中createPages,输入以下代码

const posts = result.data.allMarkdownRemark.edges.map(transformRemarkEdgeToPost)

createPage({
  path: "/posts/",
  component: path.resolve(`./src/templates/clientSearch.js`),
  context: {
    search: {
      posts,
      options: {
        indexStrategy: "Prefix match",
        searchSanitizer: "Lower Case",
        TitleIndex: true,
        AuthorIndex: true,
        SearchByTerm: true,
      },
    },
  },
})

这里transformRemarkEdgeToPost只是简单的数据转换如下

const transformRemarkEdgeToPost = edge => ({
  path: edge.node.frontmatter.path,
  author: edge.node.frontmatter.author,
  date: edge.node.frontmatter.date,
  title: edge.node.frontmatter.title,
  excerpt: edge.node.excerpt,
  timeToRead: edge.node.timeToRead,
})

这里的搜索是客户端搜索。这意味着它在搜索过程中不会与服务器通讯,因为javascript客户端已经知道了整个内容context,该内容通过传入了页面createPages。这使得搜索非常敏感。试试看!

现在,希望您了解通过传递数据到页面的概念context。至于模板,它使用了自定义的React类组件,因为它将需要使用状态。可在的回购中找到src/components/clientSearch

4.列表页面分页

接下来,我们将创建带有分页的列表页面。在默认的盖茨比引导是不够好,但我去稍远。

将以下内容放入gatsby-node.jscreatePages功能

const postsPerPage = config.noOfPostsPerPage
const noOfPages = Math.ceil(posts.length / postsPerPage)
Array.from({ length: noOfPages }).forEach((_, i) => {
  createPage(
    createListPageParameter(
      `/list-${i + 1}`,
      "./src/templates/list.js",
      posts,
      postsPerPage,
      i
    )
  )
})

基本上,它遍历您的所有posts页面,并创建包含全部的子集的页面posts。同时createListPageParameter是转换数据的另一个功能

const createListPageParameter = (
  routePath,
  templatePath,
  posts,
  noOfPostsPerPage,
  currentPageIndex
) => ({
  path: routePath,
  component: path.resolve(templatePath),
  context: {
    limit: noOfPostsPerPage,
    skip: currentPageIndex * noOfPostsPerPage,
    noOfPages: Math.ceil(posts.length / noOfPostsPerPage),
    currentPage: currentPageIndex + 1,
  },
})

现在,由于我们希望索引页面/登录页面与列表页面相同。我们需要在中以相同的方式创建它gatsby-node.js

createPage(
  createListPageParameter(
    "/",
    "./src/templates/list.js",
    posts,
    postsPerPage,
    0
  )
)

到目前为止好,现在你可以看到context通过包含之类的东西limitskipnoOfPages,和currentPage。这些元数据然后在模板中用于调用另一个GraphQL查询,如src/templates/list.js

export const listQuery = graphql`
  query listQuery($skip: Int!, $limit: Int!) {
    allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      limit: $limit
      skip: $skip
    ) {
      ...MarkdownEdgesFragment
    }
  }
`

调用的结果可以在定制的React组件的 props.data.allMarkdownRemark.edges

在这里学到什么?context例如skiplimit您可以通过将某些元数据传递给页面之后,就可以使用它们进行另一个GraphQL调用。这是一个强大的概念,可让您向页面中添加更多数据。

但是什么...MarkdownEdgesFragment呢?这是GraphQL 片段。但是在盖茨比,它的行为略有不同。

5.片段

不管是好是坏,盖茨比都使用了自己的GraphQL版本。这就是为什么在执行GraphQL查询的文件上通常会有此导入的原因

import { graphql } from "gatsby"

Gatsby处理GraphQL片段的方式与标准GraphQL略有不同。通常,会导入GraphQL片段,在GraphQL查询的顶部进行内插,然后通过扩展它来使用。在Gatsby的GraphQL中,不需要第一步和第二步,因为Gatsby会爬行所有文件并自动使所有片段在查询中可用。

让我们回头看看 src/templates/list.js

export const query = graphql`
  query HomePageQuery {
    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
      ...MarkdownEdgesFragment
    }
  }
`

MarkdownEdgesFragment没有在任何地方显式导入/内插,但是可以在GraphQL查询中使用它。这是魔法。

6.样式化的组件

默认情况下,Gatsby使用CSS模块。但是我更喜欢使用样式化组件。不过有一个陷阱。根据我的经验,有时在生产中会丢失生产的CSS,即使通过运行时一切正常gatsby develop。这种情况最常发生在首页加载中。

我该如何解决?显然我缺少一个模块。因此,请确保已安装这3个。

npm install --save gatsby-plugin-styled-components \
  styled-components \
  babel-plugin-styled-components

并确保gatsby-config.js以下内容

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-styled-components`,
      options: {
        // Add any options here
      },
    },
  ],
}

7.代码突出显示

为了突出帖子中的代码,我发现PrismJs似乎很流行并且易于使用。根据本教程,您可以使用gatsby-remark-prismjs或手动进行设置,如下所示:

从命令行安装依赖项

npm install --save prismjs \
  babel-plugin-prismjs \

.babelrc在项目的根文件夹中进行设置。确保配置中包含要突出显示的语言。

{
  "presets": ["babel-preset-gatsby"],
  "plugins": [
    ["prismjs", {
      "languages": ["javascript", "css", "markup", "ruby"],
      "plugins": ["show-language"],
      "theme": "tomorrow",
      "css": true
    }]
  ]
}

最后,请确保您在页面/模板上调用它,即 src/templates/post.js

useEffect(() => {
  Prism.highlightAll()
})

8. Google Analytics(分析)

没有任何跟踪的网站尚不完整,我们正在通过Gatsby Plugin GTag实施Google Analytics(分析)。

使用起来相当简单。将以下内容添加到中gatsby-config.js

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-gtag`,
      options: {
        trackingId: "YOUR_GOOGLE_ANALYTICS_ID",
        head: true,
        anonymize: true,
        respectDNT: true,
        pageTransitionDelay: 0,
        sampleRate: 5,
        siteSpeedSampleRate: 10,
        cookieDomain: "codeallnight.com",
      },
    },
  ],
}

这里有几件重要的事情。

  • Google Tag Assistant更喜欢将跟踪脚本放入<head>,因此head:true
  • 该插件必须作为数组中的第一个插件放置plugins。我第一次尝试时就错过了。

最初,我尝试遵循此默认指南,但由于我在Google Tag Assistant上看不到任何流量,因此无法正常运行。简单地说No HTTP response detected。切换到Gatsby插件GTag后,我可以在Google Analytics(分析)上实时查看跟踪数据。我不是100%知道为什么,但是可能与analytics.js被弃用有关

9.结语

在那里,您可以找到一份有关盖茨比的寻呼机指南。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注