深入了解 11 個靜態站點生成器

已發表: 2022-03-10
快速總結↬ Eleventy(又名 11ty)在靜態站點生成器中的排名正在上升。 這個基於節點的構建器因其零配置起點、純靜態輸出以及輕鬆實現令人夢寐以求的頂級 Lighthouse 性能得分(四個完美 100)而具有吸引力。 讓我們深入了解它的獨特之處,並了解一些基本概念以幫助您成功入門。

但首先——讓我們快速回顧一下“靜態站點”的含義以及生成器提供的內容。 靜態網站由靜態內容組成——例如,HTML、CSS、資產和所有內容在推送到網站主機之前已經編譯在一起。 這與動態站點不同,後者通過在運行時查詢數據庫(如 WordPress)或從客戶端的 API 提取內容(如沒有服務器端呈現的 JavaScript 框架)來編譯這些內容。

靜態站點生成器是一個環境和構建處理器,用於將您的內容編譯成靜態 HTML。 它們通常會提供幫助程序以提供編寫內容的靈活性(例如支持 Markdown)並包含模板方法。 因此,生成器將支持通過某種模板語言將這些內容分解為組件,而不是一個一個地編寫 HTML 頁面並複制和粘貼重複的部分。 然後生成器的構建過程會將所有內容組合在一起並輸出最終的 HTML,該 HTML 可以上傳到網絡主機作為您的網站。 根據您使用的網絡主機,此構建過程甚至可以由主機完成。

有許多可用的靜態站點生成器。 您可能聽說過甚至使用過 Jekyll、Hugo、Gatsby、Next 和 Nuxt 等。 Jamstack.org 提供了一個完整的列表。

是什麼讓 Eleventy 與其他靜態站點生成器不同?

Eleventy 在構建期間和瀏覽器中都非常快。 這在很大程度上要歸功於不需要加載客戶端 JavaScript 包來提供內容(與 Gatsby 之類的東西相比)。 服務器端渲染在這裡甚至不是問題,因為文件系統頁面創建默認為靜態 HTML。

真正讓 Eleventy 與眾不同的是能夠從多達十種不同的模板語言中進行選擇和混合:

來自 11ty.dev 文檔的屏幕截圖列出了可用的模板語言,包括 HTML、Markdown、JavaScript、Liquid、Nunjucks Handlebars、Mustache、EJS、Haml 和 Pug。
來自 11ty.dev 文檔的屏幕截圖列出了可用的模板語言,包括 HTML、Markdown、JavaScript、Liquid、Nunjucks Handlebars、Mustache、EJS、Haml 和 Pug。 (大預覽)

混合語言可以發生在同一個文件中,也可以在佈局之間發生。 例如,我經常使用 Markdown 編寫我的主要內容,這些內容會輸入 Nunjucks 佈局。 在某些項目中,我發現能夠在 Markdown 文件中使用 Nunjucks 循環訪問一些數據很有用。 這種組合語言的能力非常強大,允許您設計一個最適合您和您的項目的編寫和構建工作流程。

Eleventy 包含一個--serve標誌,該標誌使用 BrowserSync 來啟用在本地為站點提供服務,並在文件更改時進行熱重載。 這是一個極大的便利,如果您不是在尋找靜態站點生成器,而是從 Gulp 等構建工具升級,請記住這一點。

作為零配置的一部分,您的所有站點文件都可以位於項目的根目錄中。 要更改輸入和輸出目錄,您可以創建一個 Eleventy 配置,它應該是一個名為.eleventy.js的根文件。 這是一個快速片段,顯示如何進行此修改:

 module.exports = function (eleventyConfig) { return { dir: { // default: [site root] input: "src", // default: _site output: "public", }, }; };

如前所述,默認行為是創建文件系統頁面,這通常有很大的好處,特別是對於快速入門。 這很容易通過分配自定義permalink來覆蓋,並且可以為每個文件、整個目錄或動態一組數據完成。 固定鏈接還提供了另一種超能力,我們稍後將對其進行探索!

獨特的是,在構建過程中,您可以通過使用 JavaScript 並利用過濾器和短代碼(我們稍後將討論)來準備內容、數據和對該內容和數據的轉換。 同樣,這一切都發生在沒有添加 JavaScript 包客戶端的情況下,同時仍然可以使用 JavaScript 作為模板語言。

重要提示您可以在沒有 JavaScript 知識或 JavaScript 知識很少的情況下成功使用 Eleventy。

與 Gatsby 等其他 SSG 或 WordPress 等環境不同,大多數 Eleventy 網站不需要任何插件。 有一些插件可用,但它們對於基本功能不是必需的。

使用 Eleventy 構建時,您可以根據需要添加功能。 事實上,您可以只使用 HTML 而不使用任何其他模板語言。 Eleventy 的複雜程度取決於您的項目要求!

跳躍後更多! 繼續往下看↓

了解基本的 11 個概念

讓我們回顧一下有助於您成功創建 Eleventy 項目的一些術語和概念。

佈局和模板

您可能認為這些術語可以互換,但在 Eleventy 的上下文中,它們確實具有上下文含義:

  • 模板是所有內容文件的通用術語。
  • 佈局是包裝其他內容的特殊模板。

例如,模板引用您的所有 Markdown 文件,而佈局可能是一個 Nunjucks 文件,其中包含 HTML5 樣板和模板內容的插槽。 我們將在“入門”部分學習如何完成這項工作。

過濾器和簡碼

這些是修改內容輸出和創建可重用模板部件的其他方法。 它們可用於 Nunjucks、Liquid、Handlebars 和 JavaScript 模板。 過濾器和簡碼在.eleventy.js中定義。

除了您選擇的模板語言中可用的變量和運算符之外,Eleventy 還統一了之前列出的語言中的過濾器概念。 過濾器以某種特定於內容類型的方式轉換內容。 例如,您可以創建一個過濾器,用於將字符串大寫。 或者你可能有一個過濾器打算在數組上使用來改變返回的內容,比如選擇一個隨機項目。 Eleventy 提供了一些過濾器,其中一些我們將在入門教程中使用。

簡碼允許創建可重用的模板部分並且能夠接受參數。 它們可以是獨立的或成對的,這意味著它們用開始和結束標籤包裝內容。

我最喜歡的簡碼之一是呈現當前年份——這意味著您的頁腳中不再有過時的版權年份! 以下是創建year短代碼的方法:

 eleventyConfig.addShortcode("year", () => `${new Date().getFullYear()}`);

要在 Nunjucks 或 Liquid 模板中使用它,如下所示: {% year %}

您可以查看 Eleventy 文檔以獲取配對短代碼的示例。

收藏品

集合是相關內容的組,通常通過定義tags在 frontmatter 中創建。 標記語法選項包括單個字符串、單行數組 — ["tagA", "tagB"] — 用於多個標記或 YAML 樣式列表以分配多個標記。 例如,我可以通過將以下 frontmatter 添加到我希望包含在該集合中的所有內容來創建一個“頁面”集合:

 --- tags: pages ---

一旦你定義了一個集合,你可以通過你在全局collections對像中選擇的模板語言來訪問它。 訪問我們的“頁面”集合看起來像collections.pages 。 這將返回該集合數據的數組,因此您可以執行數組操作,例如對其進行循環,例如生成鏈接列表或文章預告卡。 您甚至可以抑制正常的文件輸出並僅使用集合來管理數據顯示,這對於管理單頁站點內容很有用。

自定義數據

到目前為止,我們已經討論了將內容創建為文件,但 Eleventy 還使維護不同的數據源變得非常容易。 這稱為“自定義數據”,在_data目錄中以 JavaScript 模塊導出或 JS​​ON 文件的形式存在。

自定義數據可用於:

  • 定義一個基本的 JSON 數組。
  • 返回 fetch 操作的結果。
  • 從無頭 CMS 中檢索和重新格式化內容。

_data使 _data 中的所有數據在與文件名匹配的變量下可用。 例如,如果我創建posts.json ,那麼我可以在我的模板中以posts的形式訪問它。 使用 Nunjucks,這是一個循環遍歷posts數據的示例:

 {% for post in posts %} {{ post.title }} {% endfor %}

分頁和從數據創建頁面

在 Eleventy 術語中,分頁是指遍歷數據集並為該數據“塊”的輸出定義模板。 這是通過定義 frontmatter 中的分頁的專用文件完成的。 該文件還包括為數據設置您的預期輸出,這意味著它也成為自己的模板。 我們可以定義一個佈局來發送內容,也可以添加標籤來創建一個集合,以便於參考和靈活的輸出。

注意如果您使用自定義數據從 CMS 中檢索內容,那麼分頁是您正在尋找的 Eleventy 方法,可以動態地將數據轉換為頁面。

這是一個引用我們的posts自定義數據的示例,我們假設我們是通過從無頭 CMS 中獲取來檢索的。 重要的是, size設置為 1,這意味著每個“分頁塊”應該產生一頁輸出。 然後,我們使用alias在分頁循環中創建對當前項目的引用,然後在permalink定義和模板正文中使用該引用。

定義分頁的文件可以放在輸入目錄中的任何位置。 我的組織偏好是創建一個generate目錄,然後將其命名為與將要創建的集合相同的名稱。 考慮以下是src/generate/posts.njk

 --- pagination: data: posts size: 1 alias: post addAllPagesToCollections: true permalink: "/{{ post.title | slug }}/" tags: posts layout: post templateEngineOverride: njk, md --- {{ post.body | safe }}

在這種情況下, permalink將頁面分配為直接從站點根目錄輸出。 您可以更改它以添加前綴,例如/posts/{{ post.title | slug }} /posts/{{ post.title | slug }} ,例如。

此外,如果您希望所有生成的頁面在由標籤創建的集合中可用,則必須將addAllPagesToCollections設置為true以包含比第一項更多的頁面。

最後,如果你的內容是以 Markdown 的形式出現而不是預編譯的 HTML,你需要使用templateEngineOverride 。 在示例代碼段中,我將其設置為njk, md ,這意味著模板內容需要作為 Nunjucks 進行處理才能轉換變量,然後使用 Markdown 編譯變量中返回的內容。

如果您想知道safe的含義,我們將在接下來學習!

如何開始使用十一

好的,所以你已經準備好開始你的第一個 Eleventy 項目了! 這個簡短的教程將幫助您建立一個起始結構以繼續構建。 我們將使用我們已經了解的概念並添加一些新想法。

這裡的第一個重要說明是 Eleventy 是一個作用域包,所以這裡是安裝命令:

 npm install @11ty/eleventy

接下來,我喜歡做的一個方便的事情是將以下腳本添加到我的package.json中:

 "scripts": { "start": "eleventy --serve", "build": "eleventy" }

如前所述, --serve標誌將通過 BrowserSync 啟用本地服務器。

我的偏好是更新我們已經看過的輸入/輸出目錄,所以現在是時候在src或您選擇的輸入目錄中創建一些內容了。

為了讓我們的項目從一開始就更加靈活和可擴展,我建議創建至少一個包含 HTML5 樣板的佈局。 佈局需要在直接調用的_includes中定義,這是少數預期目錄之一。

您在初學者中經常會發現的一個約定是將此佈局稱為base 。 我傾向於將其設為 Nunjucks 文件。

這是一個示例base.njk

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{ title }}</title> </head> <body> <header> <h1>{{ title }}</h1> </header> <main> {{ content | safe }} </main> </body> </html>

雙花括號是用於變量的 Nunjucks 語法。 在這裡,我們已經為即將通過前端提供的傳入title變量做好了準備。 content變量由 Eleventy 提供,並標記所有傳入的非前端內容應該去的位置。 重要的是,它與提供的safe過濾器結合使用,可防止編譯的 HTML 被轉義和呈現。

現在是時候創建我們的站點索引了,我們將其添加為index.md

 --- title: Hello Smashing Readers! layout: base.njk --- Thanks for reading — hope you're excited to try Eleventy!

請注意,在前面的內容中,我們添加了標題,還定義了佈局。

此時,我們可以使用我們添加的腳本運行我們的項目: npm start 。 這將觸發 BrowserSync 設置localhost:8080 (如果可用),但您需要在瀏覽器中手動打開它。 如果您希望它自動打開瀏覽器,請查看此快速提示。

最後一個關鍵步驟是添加樣式表。 目前,CSS 不被識別為自動包含的文件類型,因此我們在創建樣式表後將有一個額外的配置步驟。

您可以在輸入目錄中的任意位置添加 CSS 文件,例如css/style.css 。 然後,打開.eleventy.js (如果您沒有進行輸入/輸出自定義,則在項目根目錄中創建它)並添加以下內容:

 module.exports = function (eleventyConfig) { eleventyConfig.addPassthroughCopy("./src/css/"); eleventyConfig.addWatchTarget("./src/css/"); // - input/output customization if using - };

首先,我們將css目錄添加為“直通副本”,這意味著 Eleventy 應該將其包含在推送到輸出目錄中。 然後我們還將它添加為“監視目標”,這樣當我們在運行start命令時更改樣式時,Eleventy 將觸發重建以更新我們的本地站點。

最後,我們需要記住在base佈局中添加樣式表的鏈接:

 <link rel="stylesheet" href="{{ '/css/style.css' | url }}" />

當我們定義樣式表的位置時,我們將它傳遞給 Eleventy 的url過濾器,該過濾器將在構建時根據需要調整相對文件路徑。

接下來,讓我們創建一個“頁面”帖子類型來進一步探索使用集合和佈局。 為此,請添加pages目錄並創建一個或兩個 Markdown 文件,包括title前置鍵但包括佈局。

這次我們將使用一種稍微不同的方法來定義佈局——數據目錄文件。 此文件通常格式化為 JSON,使我們能夠添加應應用於目錄中所有文件的數據,從而避免跨文件複製它。 該文件需要與將使用的目錄命名相同,因此創建文件pages.json並添加以下內容:

 { "layout": "page.njk", "tags": "pages" }

我們還繼續定義標籤以創建“頁面”集合。 但是我們定義的佈局實際上還不存在,所以創建_includes/page.njk並添加以下內容:

 --- layout: base.njk --- <article> {{ content | safe }} </article>

在這裡,我們使用了佈局鏈的 Eleventy 概念,以便能夠重用我們的base模板,同時也為我們的page佈局添加一個獨特的元素,即<article> 。 這意味著我們頁面的所有內容都將使用page佈局和base佈局。

佈局鏈接通過允許重複使用樣板和基礎站點佈局結構來減少重複。

現在我們已經為pages內容類型創建了內容,並通過標籤將其定義為“pages”集合,讓我們看看如何訪問該集合。 在這裡,我們將使用 Nunjucks 循環遍歷集合併輸出每個頁面的鏈接列表。 這個循環將被添加到我們的index.md文件中。

 {% for post in collections.post -%} - [{{ post.data.title }}]({{ post.url }}) {% endfor %}

我們做了一些獨特的事情,那就是循環內部實際上切換回 Markdown 來呈現鏈接。 這不是處理這種情況的必需方法,但它可以非常方便! 有時,根據複雜性,這可能不起作用。 真正的原因是 Markdown 渲染器默認使用Liquid模板語言,所以如果您使用 Nunjucks 功能超出基本循環,則必須讓 Eleventy 知道如何處理文件。

在前面關於分頁的部分中,我們實際上已經研究了解決方案。 那就是利用templateEngineOverride來指示文件應該作為 Nunjucks 和 Markdown 處理。 以下完整的解決方案應該放在模板的前面: templateEngineOverride: njk, md

至此,您已經創建了一個基本的多頁站點! 如果您需要使用外部數據,請跳回分頁部分。

啟動 Eleventy 項目的其他方法

儘管其他一些靜態站點生成器和環境(如 WordPress)具有“主題”的概念,但 Eleventy 使用術語“啟動器”。 可供選擇的集合越來越多,許多可以在 Eleventy 文檔的列表中找到。

我的偏好是在我的 Eleventy 項目中使用 Sass,如果您想了解如何將其添加到構建過程中,我可以使用 Sass 啟動器。 如果其他人習慣於為資產和處理構建管道,他們可能會選擇添加 Gulp。

我還創建了一個包含本文中討論的功能並與教程結果有相似之處的最小啟動器。 它還有一個獲取外部數據的小示例,並展示瞭如何添加部分以顯示基於集合的站點導航。

擴展基礎

一旦您嘗試使用一些基本內容和一些自定義數據創建您的第一個站點,了解使用該內容的其他方法會很有幫助。 以下是一些其他需要注意的概念的簡要概述。

使用永久鏈接更改文件輸出類型

我之前提到過永久鏈接有一種超能力。 那就是您可以使用它們來輸出非 HTML 文件類型。

兩個有用的示例是創建一個 RSS 提要和一個站點地圖,這兩者通常都是 XML 文件。 真正強大的是,您可以繼續使用您選擇的模板語言來幫助生成這些文件,例如,您可以使用 Nunjucks 循環頁面數據以保持您的 RSS 提要新鮮。

自定義集合

有時使用標籤創建集合可能還不夠。 或者,您可能想要創建現有集合的過濾變體。 我們可以使用一系列提供的函數來更改或創建集合。 這些將存在於.eleventy.js配置文件中。

在此示例中,我們使用addCollection函數過濾現有集合中的項目。 新集合將基於前面事項中customKey的存在。 該鍵是從附加到所有生成的 Eleventy 內容的data對像中返回的。

 eleventyConfig.addCollection("specialCollection", function (collection) { return collection.getAll().filter((post) => post.data.customKey); });

您可以在 Eleventy 文檔中查看創建、修改和使用集合的其他方法。

使用數據級聯

Eleventy 對如何為稱為數據級聯的模板編譯數據有一個更完整的概念,我們在本指南中才剛剛開始探索。 如果您從文檔開始查看它的工作原理,您將充分利用 Eleventy。 Ben Myers 也有一個很好的理解數據級聯的指南。

推薦的 11 個插件

在介紹中,我簡要提到有可用的插件,但並不總是需要它們。 但是,我傾向於在大多數項目中使用一些,其中包括:

  • @11ty/eleventy-plugin-rss 如果你想要一個 RSS 提要,這個官方插件提供了一些過濾器來幫助你生成提要。 鏈接的 repo 包含一個示例提要,您也可以在某些啟動器中找到該提要。
  • @11ty/eleventy-plugin-syntaxhighlight 這個插件不是將 Prism 作為代碼高亮的腳本加載,而是允許將該處理作為 Eleventy 構建過程的一部分應用。 這意味著代碼塊被轉換為包含提前應用 Prism 主題的類,因此您只需要添加您選擇的 Prism CSS 主題。
  • @11tyrocks/eleventy-plugin-social-images 我在 Eleventy 探索早期發現的一個功能是生成社交媒體共享圖像的能力。 這導致我創建了一個插件,它在幕後使用 Puppeteer 來拍攝快照。 該插件帶有預構建的模板以及用於定義您自己的模板文件的配置選項。

我還建議您熟悉其他官方 Eleventy 插件,因為它們解決了其他常見需求,包括導航和圖像處理。

確定 Eleventy 是否適合您的項目

Eleventy 與大多數靜態網站一樣,最適合通常不需要動態或按需提供的內容。 這並不是說所有網站都必須是靜態的,或者沒有辦法使內容動態化。 您仍然可以加載 JavaScript 以啟用動態內容,例如從 API 獲取或創建交互式小部件。 如果您的主機支持構建 webhook 並且您有想要按計劃刷新的部分,您還可以使用 IFTTT 或 Zapier 等服務來幫助重建您的站點。

多虧了自定義數據和分頁,我們看到很容易包含來自無頭 CMS 或任何其他 API 的外部數據。 因此,儘管它將以靜態方式提供服務,但您在提取內容的位置和管理方式方面仍然具有很大的靈活性。

關於 Eleventy,我最喜歡的一點是,除了我們為_includes_data討論過的少數預期目錄(您也可以更新它們的命名約定)之外,它不會對我應該如何構建我的網站提出太多意見。 如果您希望遷移站點並且還能夠潛在地移動某些現有文件結構,這也很有幫助。 但是,如果您更喜歡固執己見的架構,您可能會尋求不同的選擇。

我也很享受如何通過利用多種模板語言以及過濾器、短代碼和佈局來塑造 Eleventy 以適應給定項目的心智模型。 初學者也有助於提升,以便您可以專注於真正重要的事情:您的內容。 而純靜態輸出的高性能也是一大利好。

如果您在構建過程中確實需要更多內容,您可以添加其他熟悉的工具,例如 Webpack、Gulp 或 Parcel。 您也許可以找到已經包含這些內容的啟動器。 請記住,您還可以利用 Eleventy 構建過程固有的 Node 腳本。

Eleventy 非常有能力處理大量的頁面生成。 它已被用於一些大型和復雜的網站,例如 Google 的 web.dev 和 Netlify 的營銷網站。 我還將 Eleventy 用於一些非常規用途,例如電子郵件和 Web 組件生成器,以及本概述中描述的其他一些用途。

其他資源

我希望本指南既能激發您的興趣,又能讓您為開始使用 Eleventy 做好準備! 它包含了很多點,當我用它創建我的第一個項目時,我發現這些點有點難以發現。 自從我在 2020 年 4 月第一次找到 Eleventy 以來,我已經構建了 20 多個 Eleventy 項目,包括初學者、插件、輔助項目和課程資料。 其中許多可以在我的網站 11ty.Rocks 上找到,該網站也有教程和技巧。 Eleventy 是我非常喜歡討論的話題,所以請隨時在 Twitter 上聯繫!

以下是幫助您學習和充分利用 Eleventy 的更多資源:

  • Andy Bell 提供了一個非常全面的付費課程——“從零開始學習十一”。
  • Tatiana Mac 的教程系列,從“11 歲初學者指南”開始,提供了詳盡的解釋,假設以前沒有使用靜態站點生成器的經驗。
  • Bryan Robinson 提供了一個 YouTube 課程,用於將免費的 HTML 主題轉換為 Eleventy 網站。

最後,我要指出的是,Eleventy 社區雖小但很活躍! 如果您在查找某些信息時遇到困難,可以將您的問題推特到官方@eleven_ty 帳戶。 Eleventy 的創建者 Zach Leatherman 可以快速回答或 RT 問題,幫助您重回正軌!