GitHub Pages 與 Gitee Pages 上的 Jekyll


本文已不再於此更新,最新版本請見: xjtu-blacksmith.cn/essay/jekyll-of-pages

GitHub 與 Gitee 提供的 Pages 服務中,均內嵌了 Jekyll 支持(Gitee 還提供了 Hugo 與 Hexo 支持)。所謂「支持」,即指這些生成工具掛在雲端;你只需要提供原始代碼(如 Markdown 文檔、Sass/Stylus/Less 樣式表),再由 Pages 服務自動編譯、部署即可。這樣,搭建網站的技術門檻進一步下降,你只需要會兩件事就能搭建網站了:

  1. 會寫 Markdown 文檔;
  2. 注冊 GitHub 或 Gitee 賬號,點點鼠標,在你的代碼倉庫中啟用 Pages 服務。

因為技術門檻如此之低,導致不少用戶壓根就意識不到 Pages 服務內置了 Jekyll 工具,甚至以為每一個 Markdown 文檔理所當然地就能變成一個網頁。此外,另一個常被忽視的問題是:由 Pages 服務調用的 Jekyll 工具,並非最新版本,而且隱性地增添了許多插件,這可能使用戶在本地使用 Jekyll 或遷移平台時碰上「不協調」的問題。最常見的一個問題就是:在 GitHub Pages 上正常生成的代碼倉庫,到 Gitee Pages 上就變得一團糟。這不是因為 Gitee Pages 的功能「不如」GitHub Pages,而是因為:

GitHub Pages 沒有告訴你它們為自己的 Jekyll 多加了幾個插件,Gitee Pages 也沒有告訴你它們的 Jekyll 並沒有這些插件。

這里對 GitHub Pages 與 Gitee Pages 所使用的 Jekyll 進行一個簡單的分析(后面姑且簡稱為 GitHub Jekyll 與 Gitee Jekyll),以說明它們隱性地附加了哪些功能,需要特別注意。

Jekyll on GitHub Pages

GitHub Pages 中所采用的 Jekyll 及插件、依賴,被匯總到名為 github-pages 的 Gem 中(主頁)。如果你在本地安裝了這個 Gem,可以運行它來查看其所要求的各項依賴版本。以目前最新的 204 版本為例,在 shell 中運行:

$ github-pages versions
+------------------------------+---------+
| Gem                          | Version |
+------------------------------+---------+
| jekyll                       | 3.8.5   |
| jekyll-sass-converter        | 1.5.2   |
| kramdown                     | 1.17.0  |
| jekyll-commonmark-ghpages    | 0.1.6   |
| liquid                       | 4.0.3   |
| rouge                        | 3.13.0  |
| github-pages-health-check    | 1.16.1  |
| jekyll-redirect-from         | 0.15.0  |
| jekyll-sitemap               | 1.4.0   |
| jekyll-feed                  | 0.13.0  |
| jekyll-gist                  | 1.5.0   |
| jekyll-paginate              | 1.1.0   |
| jekyll-coffeescript          | 1.1.1   |
| jekyll-seo-tag               | 2.6.1   |
| jekyll-github-metadata       | 2.13.0  |
| jekyll-avatar                | 0.7.0   |
| jekyll-remote-theme          | 0.4.1   |
| jemoji                       | 0.11.1  |
| jekyll-mentions              | 1.5.1   |
| jekyll-relative-links        | 0.6.1   |
| jekyll-optional-front-matter | 0.3.2   |
| jekyll-readme-index          | 0.3.0   |
| jekyll-default-layout        | 0.1.4   |
| jekyll-titles-from-headings  | 0.5.3   |
| jekyll-swiss                 | 1.0.0   |
| minima                       | 2.5.1   |
| jekyll-theme-primer          | 0.5.4   |
| jekyll-theme-architect       | 0.1.1   |
| jekyll-theme-cayman          | 0.1.1   |
| jekyll-theme-dinky           | 0.1.1   |
| jekyll-theme-hacker          | 0.1.1   |
| jekyll-theme-leap-day        | 0.1.1   |
| jekyll-theme-merlot          | 0.1.1   |
| jekyll-theme-midnight        | 0.1.1   |
| jekyll-theme-minimal         | 0.1.1   |
| jekyll-theme-modernist       | 0.1.1   |
| jekyll-theme-slate           | 0.1.1   |
| jekyll-theme-tactile         | 0.1.1   |
| jekyll-theme-time-machine    | 0.1.1   |
+------------------------------+---------+

能看到其列出來一大串的 Gem。通過這個頁面也可以看到 GitHub Pages 上的 Jekyll 版本及相關依賴。

以上這些 Gem,可以大致划分為四類:

  1. Jekyll 及其依賴,比如 Sass 轉換、Kramdown 引擎、Liquid 模板語言、Rouge 高亮器等等。這些算是常規構件,不可或缺。注意,目前 GitHub Pages 使用的 Jekyll 版本為 3.8.5,而最新版本是 4.0.0,有一個「適當」的延遲。
  2. 為 GitHub Pages 定制的額外功能,主要有兩個:jekyll-commonmark-ghpages,在 Commonmark 基礎上改出來的 GFM 引擎(但 Jekyll 仍然默認用 Kramdown);github-pages-health-check,用於檢查域名(DNS 服務)和 GitHub Pages 服務是否正常。
  3. 若干 Jekyll 插件,基本上都是 jekyll 開頭。后面會詳細分析。
  4. 若干 Jekyll 主題,除了 Jekyll 的默認主題 minima 和一個基本主題 jekyll-swiss 之外,還有 13 個 jekyll-theme 開頭的,它們就是你在 GitHub Pages 服務里即選即用的 13 個主題。

從以上后三類可以看到,GitHub Jekyll 其實「加持」了很多的輔助件,並不單純。而這樣多的輔助構件,最終營造出了前面所提的「每一個 Markdown 文檔理所當然地可以變成一個網頁」之幻覺。事實上,如果是純粹用 Jekyll 搭建網站,所需要做的工作仍然是不少的。

下面再詳細分析一下 GitHub Jekyll 所采用的插件。

Jekyll 的 Markdown 引擎

在 Maruku 停止更新后,Jekyll 的默認 Markdown 引擎變成了 Kramdown,同樣也是一個用 Ruby 開發的工具。Kramdown 實現了相當多的拓展功能,典型者如 LaTeX 公式、行內屬性標記等,拓展了用 Markdown 實現網頁(HTML)的可能性。

GitHub Jekyll 也是默認用 Kramdown 渲染 Markdown,不過前面看到其也提供了一個 GFM 引擎。在 GitHub 的官方文檔中對此有特別說明,並強調「只有使用后者才能保證網站效果與 GitHub 中(渲染的 Markdown 頁面)的一樣」。仔細想想,有這個需求的用戶應該不在少數。

常規插件

在 GitHub Jekyll 所用插件之中,下面這些是比較常規、常見的(強調者表示默認啟用):

  • jekyll-sitemap,用於生成站點地圖文件 sitemap.xml 供搜索引擎抓取;
  • jekyll-feed,用於生成 RSS 訂閱鏈接 feed.xml
  • jekyll-coffeescript,CoffeeScript 轉換器;
  • jekyll-redirect-from,重定向插件,從功能上可以理解為 permalink 的反面;
  • jekyll-paginate,分頁器;
  • jemoji,表情包;
  • jekyll-avatar,提供了形如 {% avatar [username] %} 的標簽,用於獲取 GitHub 用戶的頭像;
  • jekyll-remote-theme,使你能夠使用掛在 GitHub 上的 Jekyll 主題;
  • jekyll-gist,提供了形如 {% gist xxx %} 的標簽,用於在頁面上展示 Gist 的內容;
  • jekyll-mentions,使得 GitHub 上的 @ 用戶功能在網站中得到支持;
  • jekyll-relative-links,能夠將指向 Markdown 文檔的鏈接轉換為指向對應 HTML 頁面的鏈接(有點雞肋)。

其中許多算是 Jekyll 的標配插件,經常被使用。它們更多地是提供了一種可選項,不會對網站的生成效果有太大影響。

靜默增強插件

除了上面所提的基本插件,另外的插件則非常「陰險」,默認啟用,發揮了一些你根本意識不到的功能。包括:

  • jekyll-seo-tag:定制了 {% seo %} 這個 Liquid 標簽的功能。SEO 的其他方面不說,網站的 <title> 元素就是它搞定的(使用了 _configs.yml 文件中的 titledescription 屬性)。所以在用 GitHub Jekyll 時要想改變網頁標題的格式,就必須要求它停止輸出標題:{% seo title=false %},否則你會以為標題是「無中生有」的。
  • jekyll-github-metadata:用於從 GitHub 獲取元信息,比如項目名稱、作者之類的。它主要是給 GitHub Pages 生成的網站提供一些默認參數,比如上面的 SEO 插件就會使用 GitHub 倉庫的項目名稱、描述作為網站的標題和副標題。在本地用 Jekyll 構建 Pages 上的網站時,十有八九會出現「No GitHub API authentication」的警告,這個鍋也得由它來背(它要用 GitHub API 來獲取這些信息)。
  • jekyll-optional-front-matter:根據 Jekyll 的機制,其只會轉換有 YAML 頭信息(哪怕是空的)的 Markdown 文件,這個插件則取消了這一要求。所以如果你發現用在其他場合使用 Jekyll 時許多 Markdown 文件沒有被轉換,你會意識到這個插件的作用:讓你不用寫頭信息。(另外,這個規則對 Sass 文件不使用,所以你得對自己寫的、放在 _sass 目錄以外的 Sass 文件至少給一個空的頭信息。)
  • jekyll-readme-index:這個插件使得 Jekyll 在找不到 index.htmlindex.md 時,將 README.md 轉換為 index.html 作為替代。這個功能的好處在於實現了 GitHub 頁面預覽和網站構建的統一,因為在 GitHub 頁面上 README 的作用就相當於一般網站的 index.html
  • jekyll-default-layout:幫助你自動給首頁套 layout: home、給推送文章套 layout: post、給一般頁面套 layout: page、實在不行就套 layout: default。作用很明顯:讓你不用寫頭信息。
  • jekyll-titles-from-headings:自動將一個沒有指明 title 的 Markdown 文件之首級標題提取為 title。從頁面顯示來說,一個頁面有沒有 title 其實無關緊要,但需要生成網站導航、文章列表等的時候就必須確保每個頁面都有 title。這個功能的作用也很明顯:讓你不用寫頭信息。

以上幾個插件,都是「靜默」生效;其中不少在 Jekyll 中並不默認啟用,但它們在 GitHub Jekyll 中全都是默認啟用的。它們發揮的作用,也許你之前從未意識到,但現在一看即知。

GitHub Pages 主題

GitHub Pages 提供的 13 個基本主題,也被包含在依賴當中,這意味着你不需要安裝就能使用它們。它們在 _configs.yml 中用 theme 屬性啟用(也許這是許多人見過的第一行 YAML 代碼?),這會給初學者造成一種誤解,以為其他的主題也可以這樣通過一行代碼來使用。

事實上,如果要在 GitHub Jekyll 中使用其他主題,有這樣兩種辦法:

  1. 啟用 jekyll-remote-theme 插件,這樣你就可以使用任意一個在 GitHub 上公開的 Jekyll 主題(其他地方的不行);
  2. 把主題下載下來,將對應文件拷貝到指定位置——注意清理之前的主題。(Jekyll 的主題管理不是很靈活,不如 Hugo、Hexo 等工具。)

當然,如果你是在本地生成網站文件后再借 Pages 的服務器發布,方法就比較多了。

總結

經過以上對各個依賴的分析,我們可以發現:GitHub Jekyll 提供了相當多的輔助功能,極大的化簡了網站的生成,而我們甚至還不自知。在不清楚這些背景的情況下,嘗試從 GitHub Pages 服務下遷移出 Jekyll 項目,很有可能會踩坑,比如:

  • 為什么這個 Markdown 文件沒有被轉換?(因為你沒有寫頭文件,怪 jekyll-optional-front-matter
  • 為什么文章列表里的文章標題都是空的?(因為它們的標題是正文中的 h1 標簽,沒有寫到頭信息中的 title 里,怪 jekyll-titles-from-headings
  • 為什么這個路徑下的頁面不見了?(因為你原來用的是 README.md 轉換成 index.html,怪 jekyll-readme-index

當然,問題的可能性不多,一一排除總能解決。所以歸結出一個結論:與其花時間琢磨上面這么多 Gem 的關系,還不如自己去踩踩坑。

坑歸坑,好話也還是要說幾句:如果只是一直用 GitHub Jekyll,以上這些都不算是問題,而算優勢。「Markdown 文件自動變成網頁」這樣的好事,還是人人所欲的;它畢竟能讓許多完全不了解前端技術的人構建一整個網站出來,應該算是大好事。

Jekyll on Gitee Pages

Gitee Pages 究竟用的是綠 Jekyll 還是花 Jekyll,沒有公開信息,只能間接地尋找一些蛛絲馬跡了。

嘗試在一個 Gitee 倉庫中啟用了 Gitee Pages,發現它支持 jekyll-seo-tag,但在生成的 HTML 頁面上赫然顯示該插件版本為 2.3.0。經過檢查,這個版本是 2017 年八月發布的,看來有些年頭了。

但是僅從這一個插件不能推斷出所有信息。為此,我又測試了其他幾個插件,發現:

  • jekyll-sitemapjekyll-feed 兩個插件都可以正常使用,說明它們算是 Gitee Jekyll 的依賴。
  • 另外,在 jekyll-feed 生成的 feed.xml 中意外發現了 Jekyll 的版本信息:3.6.2。檢查發現這是 2017 年十月發布的版本
  • jekyll-mentions 插件竟然可以用,指向 GitHub 的用戶主頁——自己做一個 Gitee 版本的應該也挺容易吧?跟 GitHub 有什么關系?
  • jemoji 用不了。
  • 幾個靜默強化插件中,除了 jekyll-github-metadata 未啟用之外,其他的都能正常工作。這造成的后果是,在 Gitee Pages 中必須自己寫 baseurl,否則站點的樣式表就找不着了,鏈接也會錯亂。
  • jekyll-remote-theme 居然能用……前提是把 baseurl 寫對。

根據以上的分析,可以得出以下幾個結論:

  1. Gitee Jekyll 的版本很舊了,一整套工具可能只是 2017 年末的「最新版」。找到了 Gitee Pages 的上線說明,發布時間是在 2018 年年中,差不太遠(也許前端支持做好之后半年在做后端支持)。
  2. Gitee Jekyll 跟 GitHub Jekyll 對接不良,遷移或同步的話得增補很多信息,並且不少插件用不了。
  3. Gitee Jekyll 竟然支持 GitHub 上的遠程主題,但是用起來似乎也存在若干問題,不穩定。

以上三條再歸納為一個最終的結論:(目前的)Gitee Jekyll 不可靠。為了用 Gitee Pages,只有在本地生成網站文件再發布了。和 GitHub Pages 比起來,這無疑抬高了使用門檻;這倒不算什么,重要的是在這種情況下 Gitee Jekyll 形同虛設,不會有什么人去用了。

冷嘲熱諷不能解決問題。剛剛和 Gitee 管理團隊聯系上,表示將來會改進這些問題。持續關注。如果 Gitee Pages 的生態做出來了,肯定是也是一件大好事吧!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM