Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

记录我的Blog构建过程 #11

Open
programmer-yang opened this issue Dec 30, 2019 · 0 comments
Open

记录我的Blog构建过程 #11

programmer-yang opened this issue Dec 30, 2019 · 0 comments

Comments

@programmer-yang
Copy link
Owner

programmer-yang commented Dec 30, 2019

这个 Blog 我选了一个我很不熟悉的技术栈 Gatsby,这应该算是就是跳出舒适圈吧。

002

先说说我的诉求,我希望我的 Blog 可控性比较高,这样方便我做一些自己想做的事情。然后我希望它尽可能的简洁跟简单,个人有点极简主义。然后我希望 Blog 的内容使用 MarkDown 编写,最后我希望它可以自动部署,我 push 到 Github 就可以自动发布。

好吧,就这些,让我们开始吧。

基础架构

Gatsby 是一个很优秀的基于 React 的开源架构,使用它,你可以很简单很快速构建你的网站,它已经帮你做了很多事情,比如静态化页面、统一的数据获取方式等。我很久前就有学习它的计划,但一直搁置,这次我选择使用它。

使用 Gatsby 跟我使用之前的 React 架构最大的区别应该是在数据资源层上,Gatsby 有一个内置的数据层,是基于 GraphQL 的,这个数据层包含了你开发过程需要的所有资源,比如,图片、视频、JSON 数据等。GraphQL 是一种查询语言,我在几年前就开始关注,但因为使用起来需要涉及到服务端的改造(原来的理解,但现在似乎也可以独立在展示层使用),就一直停留在只会基础的使用阶段,没有深入了解,我计划会在另一篇博客中在讲讲我的理解,这里就不明细说了。

Markdown

使用 Gatsby 开发 Blog 系统,markdown 文件也是一种静态资源,我们需要使用 Gatsby 的插件把 markdown 文件加载到 Gatsby 的数据层,然后在应用就可以随意的使用了。

module.exports = {
  plugins: [
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "content",
        path: `${__dirname}/src/content`,
      },
    },
    "gatsby-transformer-remark",
  ],
}

我们先使用 gatsby-source-filesystem 插件把我们 markdown 文件添加到系统内,然后使用 gatsby-transformer-remark 插件把刚刚添加的内容转换为我们可以使用的数据。

当你启动了 Gatsby 的开发模式,它会自同时给你启动一个 graphql 服务,可以通过http://localhost:8001/___graphql来访问。在使用了 gatsby-transformer-remark 插件后,你会发现你的数据源里多了 allMarkdownRemarkmarkdownRemark,一个是用来查询所有的 markdown 数据,一个是来获取单个 markdown 数据的详情

Gatsby 提供了很多类似生命周期的接口,你可以使用这些接口来完成你的业务,比如在我们这个场景下,我们要使用 Gatsby 的创建页面的接口,因为我的诉求是最终通过 markdown 的方式来写 blog,那么在我每次创建一个新的 markdown 文件后,都需要把这个文件转换为一个页面。

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const result = await graphql(`
    query MyQuery {
      allMarkdownRemark {
        edges {
          node {
            frontmatter {
              path
            }
          }
        }
      }
    }
  `)
  result.data.allMarkdownRemark.edges.forEach(edge => {
    const { node } = edge
    createPage({
      path: node.frontmatter.path,
      component: path.resolve(`src/templates/post.js`),
    })
  })
}

上面的代码就是使用 Gatsby 给我们提供 graphql,来查询到所有的 markdown 数据,然后通过 createPage 方法创建对应的页面,这样我们就可以通过路由来访问我们的页面了,这里需要注意,在创建页面的时候,我们还需要指定一个模板文件,每个页面的具体内容,我们需要在模板里再通过 markdownRemark 去查询,查询条件就是路由 path,如下所示:

export const pageQuery = graphql`
  query($path: String!) {
    markdownRemark(frontmatter: { path: { eq: $path } }) {
      html
      frontmatter {
        date(formatString: "YYYY MM DD")
        title
        path
      }
    }
  }
`

然后我们就可以写我们最熟悉的组件代码了

const Templates = props => {
  const { markdownRemark } = props.data
  const { html, frontmatter } = markdownRemark
  return (
    <div>
      <h1>{frontmatter.title}</h1>
      <h2>{frontmatter.date}</h2>
      <div dangerouslySetInnerHTML={{ __html: html }} />
    </div>
  )
}

自动发布

开始处理自动发布需求,虽然网上有很多类似的架构跟教程,但我觉得既然底层原理很简单,还是自己实现一个,这样比较好控制。

自动发布的核心是 Git 的 Hook 机制,在 Github 里对应的是 Settings 页面的 Webhooks 选项,可以让用户填写一个 API,在你的库发生改变的时候就自动调用里设置的 API。

然后我用 node 的 Express 在服务端运行了一个 Web 程序,通过 shelljs 这个库来执行一个写好的脚本,在脚本里做安装依赖、编译、重启 Nginx 的操作,这样看起来一个简单的自动化发布系统就做好了,虽然很简陋。

总结

到目前为止,我的需求都已经满足了,一个干净的用 Markdown 编写的可以自动发布的 Blog 系统。其实还有很多细节跟踩坑我没细说,主要是因为我不太会把控技术细节跟描述文字之间的界线,担心太多的技术内容导致阅读体验下降。

我比较喜欢兴趣式学习方式,所以我也用这种方式来学习前端技术,就像你看到的这个 Blog,因为兴趣,我在这个过程中学习了使用 Gatsby,学习了自动发布等工作中会遇到的一些技术,我很喜欢这种方式跟节奏。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant