把Github當作資料庫,搭建部落格

ZHANGYU發表於2021-04-08

網上有很多種搭建部落格的方法,有前後臺一把梭的,有靜態網頁的,也有大佬喜歡直接在Github的Issues上寫文章。

今天給大家分享一種很方便的方法來搭建部落格,無需伺服器,前端可以是任意的技術棧。

可以實現的功能:

  1. 前端頁面自定義
  2. 帶評論系統
  3. 文章可以帶標籤分類
  4. 資料、圖片儲存在Github,長期儲存
  5. CDN加速
  6. 自定義域名

當然,這種方式還是需要自己動手,並不是現成的一套技術。

最後的效果可以看我的部落格Github倉庫

如何實現

其實原理說出來很簡單,因為Github有提供API介面的,可以訪問Issues,而我們只需要通過Issues的介面來請求文章資料,每一篇文章對應一個Issue,每一個Issue的評論功能對應該文章的評論系統。

圖片可以儲存在當前倉庫的另一個分支,用免費的jsdelivr來作CDN。

Github Page和一些Serverless提供商如vercel都可以修改自定義域名。

建立倉庫和Token

需要在Github上新建一個倉庫,然後申請一個Github Token,申請方式見官方文件

這個Token需要儲存好,不能傳到倉庫的,可以用.env.local這種方式來儲存和讀取。

讀取博文列表

博文列表也就是Github Issues,官方提供了2種方式來獲取,分別是REST APIGraphQL API,需要使用官方的請求庫core.js。我是使用的GraphQL API,因為它可以提前過濾不要的資料。

比如我想要請求的Issues列表是倉庫zhangyu1818/blog,擁有者為zhangyu1818,倉庫名為blog,它對應的GrpahQL請求如下:

{
  repository(owner: "zhangyu1818", name: "blog") {
    issues(
      states: CLOSED
      first: 100
      orderBy: { field: CREATED_AT, direction: DESC }
      filterBy: { createdBy: "zhangyu1818" }
    ) {
      nodes {
        number
        title
        createdAt
        updatedAt
        labels(first: 5) {
          nodes {
            color
            name
          }
        }
      }
      pageInfo {
        hasNextPage
        endCursor
      }
      totalCount
    }
  }
}
複製程式碼

這一串資料請求了由zhangyu1818建立前100個關閉的Issue,每一個Issue請求前5個label標籤,每一個Issue包含number、title、craetedAt等資料。

對應的REST API請求的方式和示例見文件

請求文章詳情

每一個Issue都是一個數字,用數字請求指定的Issue可以得到裡面的詳情。

query queryIssueByNumber($number: Int!) {
  repository(owner: "zhangyu1818", name: "blog") {
    issue(number: $number) {
      number
      title
      url
      createdAt
      bodyHTML
      labels(first:5) {
        nodes{
          color
          name
        }
      }
    }
  }
}
複製程式碼

Github API不僅可以請求Markdown的內容,也可以直接請求由Github渲染好的的內容HTML,這樣我們連本地的Markdown渲染都可以省去。

對應的REST API請求的方式和示例見文件

評論系統

評論系統是有很多現成的輪子,這裡推薦使用gitalk,使用方式見文件

需要先在Github建立一個應用,我的應用資訊如下。

image-20210408191220681

使用方式

const gitalk = new Gitalk({
  clientID: "GITHUB_CLIENT_ID", // 你的應用id
  clientSecret: "GITHUB_CLIENT_SECRET", // 你的應用secret
  repo: "blog", // 你的倉庫
  owner: "zhangyu1818", // 你的github名字
  admin: ["zhangyu1818"], // 你的github名字
  number: 1, // 需要issueNumber相同
})

gitalk.render('gitalk-container') // 渲染的元素
複製程式碼

圖片儲存在Github

這個也是現有工具就能實現的功能,圖形化工具PicGO,它也有命令列工具PicGo-Core,它同樣需要使用Github Token,可以是之前申請的Token,也可以重新申請一個。

具體配置可以看參考教程

我配置的是將圖片存在倉庫的另一個分支。

image-20210408192506499

這樣配置的話如果需要使用jsdelivr作CDN加速,配置的地址應該是

https://cdn.jsdelivr.net/gh/zhangyu1818/blog@files
複製程式碼

頁面的部署方式

部署方式推薦使用vercel,它可以很簡單的配置在Github的主分支更新後自動的拉取和部署,同時支援很多種不同的前端技術棧,Vue和Angular都支援的,可以看這裡

所以前端可以用任意的技術棧,我選擇的是Next.js,然後再通過vercel來部署。

vercel部署的還有一個好處是可以在頁面上配置一些環境變數,比如我們的Github Token,聊天的Client ID,同時也可以修改自定義的域名。

image-20210408193426232

配置好後程式碼裡可以直接這樣寫。

const gitalk = new Gitalk({
  clientID: process.env.NEXT_PUBLIC_GITHUB_CLIENT_ID,
  clientSecret: process.env.NEXT_PUBLIC_GITHUB_CLIENT_SECRET,
  // ...
})
複製程式碼

sitemap如何實現

如果是靜態頁面,可以需要在build之前先請求列表,再寫一個sitemap.xml到本地,如果是服務端渲染,可以直接寫一個API介面。

總結

這個部落格我也用了挺久了,總的來說非常方便,是我折騰部落格多年來說最好的一個方式,不需要本地儲存資料,也不需要後臺,也不需要買伺服器來部署,Github上和網頁就是一個映象,需要改文章內容或者是標籤,只需要在Github上改一下就行了。

唯一的缺點就是需要自己折騰折騰,對於愛動手的小夥伴來說,我覺得這種方式的自由度是很高的了。

相關文章