靜態網站生成器是如何工作的
在過去的幾年裡,開源靜態網站生成器的數量增長迅速,StaticGen 上幾乎找得到每一種語言實現的版本。靜態網站相比動態網站具備無需依賴應用伺服器,性能優越,部署簡單等特點。特別適合生成靜態文檔,個人博客,飽受開發者的青睞。相比學會使用,掌握工作原理也尤為重要。
一個靜態網站生成器的工作流程通常有以下幾個步驟:
- 讀取源文件(e.g. 約定 markdown 格式)
- 資源預處理
- 模板引擎渲染
- 生成目標文件
第一步 讀取源文件
從使用者的角度,我們希望以 markdown 的形式進行寫作,相比純文本更容易控制格式,並且可以靈活地自定義配置(源目錄路徑、目標目錄路徑、頁面標題等等),覆蓋工具的默認配置,這一步很簡單。
以 Node.js 為例:
// 讀取 markdown 內容readFile(source, (err, data) => { console.log(data);})// 讀取配置內容console.log(require(config))
第二步 資源預處理
也是靜態網站生成器的核心工作部分。首先解析 markdown 內容,分離頭部元數據(通常採用 YAML 格式,用於單頁信息配置)與主體內容。
形似:
---title: Hello World---Awesome static site generator
解析成:
const result = { "path/to/hello-world.md": { title: "Hello World", content: new Buffer("Awesome static site generator.") }}
通常的做法是掃描文件,匹配分隔符`---`,分割內容,對頭部用相應格式的引擎解析(e.g. YAML 格式用 yaml-parser,JSON 格式用 JSON.parse),對主體內容,需要把 markdown 內容轉換成帶有標籤的 HTML 片段,用於排版與應用樣式,推薦比較流行的解析器 marked 。
經過轉換後:
const markedResult = { "path/to/hello-world.md": { title: "Hello World", content: new Buffer("Awesome static site generator."), html: "<p>Awesome static site generator.</p>" }}
對其它一些靜態資源(e.g. css, js, png),可以引入一系列工具鏈,CSS 預處理器,編譯器,打包器,流程構建工具,將全部資源相整合。由此,可以提供一套主題配置,甚至可以開放主題插件,豐富內容。所有的設計出發點都基於更好的內容寫作,而不必折騰繁瑣重複性的頁面開發工作。
第三步 模板引擎渲染
在上一步,我們得到了 markdown 解析後的 HTML 片段,接下來要做得就是將 HTML 片段嵌入預先定義的模板,復用頁面中公共部分(e.g. 導航欄、側邊欄、底部),還可以嵌入變數(默認配置及自定義配置)和靜態資源。
以模板引擎 EJS 為例:
<html><head><%= title %></head><body> <% include partials/navbar %> <%- html %></body></html>
// EJS 渲染const ejsResult = ejs.render(str, { ...markedResult["path/to/hello-world.md"]});
我們甚至可以拋棄以往模板引擎渲染這種比較傳統的方式,改用 MV* 框架(e.g. React, Vue, Angular),並結合服務端渲染技術,熱替換技術及其它工具鏈,打造一個更現代化的靜態網站生成器。
第四步 生成目標文件
經過前三步的解析,處理,編譯,轉換,我們得到了最終的資源文件,最後一步只需清理目標目錄,並輸出所有資源到目標目錄,結束工作。
// 生成目標文件writeFile(destination, ejsResult, err => { if (err) return console.error(err)}))
你可能還需要
- 一個本地伺服器通過啟動一個 Node.js Server 實時預覽界面,監聽本地文件改動,結合 live-reload 觸發頁面自動刷新,或者利用 Webpack 熱替換功能。
- 一個文件資料庫持久化存儲部分數據(e.g. 博客發表時間,文件哈希值,文件修改時間),重新編譯可以跳過未改動的文件。
- 一個日誌系統記錄編譯過程和編譯結果,增強 debug 可行性,按 log 層級格式化輸出不同信息到控制台。
- 一個自動化部署方案整合 Git 和 WebHook,一鍵發布到 GitHub Pages 或者自己的網站上。
小結
本文從宏觀角度解釋了靜態網站生成器的工作流程(輸入 => 預處理 => 渲染 => 輸出)。當然這個過程還涉及命令行的解析,合法性校驗,錯誤捕獲,解析器原理,編譯器原理,模板引擎原理,插件設計等等。See you next time ~
推薦閱讀:
※這種線條是怎麼畫出來的?
※WebSocket
※如何精確控制textarea的行數,若輸入超過指定的行數,則禁止輸入?
※請問這個網頁效果怎樣做?
TAG:JavaScript |