
最近独立博客圈子里聊 Pilgrim 的人明显多起来了。很多朋友问的第一个问题都是“怎么用”但网上的英文文档偏工程化中文社区里成体系的教程反而不多。这篇就把我从零开始用 Pilgrim 搭完一个个人博客、踩过哪些坑、最终怎么发布上线的全过程拆开讲。Pilgrim 本质上是一个极简的静态站点生成器没有数据库、没有后端服务你只需要维护 Markdown 文件和一份 YAML 配置它就能构建出一整套可以被任意静态托管平台直接托管的网站。这篇文章适合刚接触静态站点的小白也适合想从 Hugo、Jekyll 迁移过来换个工作流的同学读完你至少能独立完成一个可发布、可维护的个人站点。1. 先把 Pilgrim 的定位讲清楚它到底解决了什么问题1.1 它到底是什么极简、静态、Markdown 优先Pilgrim 的核心思路非常朴素——把所有内容写成 Markdown用约定好的目录结构放好然后执行一条构建命令生成纯静态的 HTML、CSS、JavaScript 文件。你不需要维护数据库不需要装 PHP 或者 Python 环境也不需要为一个简单博客租一整台服务器。它跟你直接写 HTML 的区别在于Pilgrim 会把内容、主题、配置三者彻底拆开你只需要关注文字剩下的版式、目录页、标签聚合页、RSS 都由工具自动完成。我用一个类比来理解传统建站方式像一个甜品店你得同时管后厨、柜台、菜单设计和收银而 Pilgrim 像半成品的中央厨房你只管把菜品原料Markdown准备好出餐模式已经帮你定好了。它生成的站点文件非常轻一个几十篇文章的博客构建产物往往只有几 MB。放到任意 Nginx、GitHub Pages、Netlify 或者对象存储上都能跑加载速度自然就快。这里要强调“静态”不等于“简陋”。通过模板和一点前端代码Pilgrim 一样能做出有导航、有侧边栏、有标签系统、有搜索框接口的完整站点。只是它把所有动态逻辑前置到构建阶段浏览器拿到的永远是最终文件。对个人博客、作品集、团队文档这类内容以文字为主、更新频率不高的场景这个模型反而比动态 CMS 更省心。1.2 和 Hugo、Jekyll、Eleventy 这些老牌工具比优势在哪工具选型不能只看名气得看你愿意为“复杂功能”付出多少维护成本。我整理了一张对比表方便你理解 Pilgrim 在生态里的位置工具语言/运行时主要特点最舒服的使用场景相对明显的短板PilgrimNode.js配置集中、模板直观、开箱即用个人博客、文档站、作品集生态规模还在增长期HugoGo极快的构建速度、内置功能多大规模内容站、技术文档模板语法偏底层学习曲线略陡JekyllRuby与 GitHub Pages 天然集成极简博客、GitHub 托管依赖管理容易出问题EleventyNode.js高度灵活、支持多种模板语言喜欢完全掌控构建流程的开发者自由度高初期配置成本也高选 Pilgrim 而不是 Hugo对我来说最重要的理由是“默认选择已经够用”。Hugo 的 taxonomy、shortcode、多语言这些概念本身没问题但个人博客根本用不到那么多反而每个概念都要花时间理解。Pilgrim 把默认做得更克制文章就是文章页面就是页面标签就是标签目录结构一目了然。模板引擎我用的是类似 Nunjucks 的语法会写 HTML 的人半小时内就能上手不需要先去啃一整套主题开发手册。当然如果你是追求极致构建速度、要管理几千篇文章的大型项目Hugo 依然有优势。Pilgrim 适合的是“内容不多但希望处处可控、维护省心”的创作者我至今不觉得这个选择有什么遗憾。1.3 什么样的项目适合用 Pilgrim什么情况别硬上我自己的经验是把 Pilgrim 用在三个场景个人博客、项目文档、活动落地页。前两个不用解释落地页是指那种内容更新不频繁、但需要一个有品牌感的静态页面的场景——用 Pilgrim 做一个独立页面比用在线建站工具更自由也比写死 HTML 更好维护。但我也要劝退几种情况。如果站点有大量用户注册、评论实时交互、付费流程你需要的是带后端能力的系统静态生成器不适合硬扛。如果团队需要一个可视化编辑器让运营同学自己改内容Pilgrim 给不了这种体验因为内容流转本质是走 Git 和 Markdown 的。再比如你需要多级权限、草稿审批流这类 CMS 能力也别为了“极简”两个字硬上不然做到后面全是在补工程化方案。认清边界工具才会真正为你服务。2. 安装与初始化把第一条命令跑通2.1 环境要求与安装方式Pilgrim 跑在 Node.js 上所以第一步是确保电脑里有可用的 Node 环境。我建议装 LTS 版本至少是 Node 18 以上因为新版 CLI 依赖了比较新的文件系统 API老版本 Node 会有兼容问题。Windows 用户建议提前装好 WSL 或者 Git Bash虽然 Pilgrim 在原生 CMD 里也能跑但路径处理和换行符在 Linux 风格环境下更省心。安装方式很简单全局安装 CLInpm install -g pilgrim安装完成后验证一下版本pilgrim --version如果之前用过旧版本记得先卸载再装新版避免全局残留的旧可执行文件干扰。国内网络环境如果 npm 源拉取慢可以换成国内镜像源但我不建议长期用镜像源出现依赖版本异常时排查起来更麻烦我一般只用镜像做临时加速。2.2 三条命令创建第一个站点安装完成后进入你准备放项目的目录执行初始化命令pilgrim init my-blogPilgrim 会在当前目录下生成一个叫my-blog的文件夹里面已经有完整的项目骨架。接着进入目录启动开发服务器cd my-blog pilgrim serve终端会打印一个本地地址默认是http://localhost:8080。浏览器打开它你会看到 Pilgrim 默认主题的欢迎页面带一篇示例文章这个流程就算跑通了。serve命令会启动一个带实时重载的本地服务之后你每次保存 Markdown 文件浏览器页面都会在几毫秒内自动刷新写内容的时候感受非常流畅。2.3 搞懂生成的目录结构与配置初始化完成后你会看到这样的结构my-blog/ ├── content/ │ ├── posts/ │ │ └── hello.md │ └── pages/ │ └── about.md ├── themes/ │ └── default/ ├── public/ ├── pilgrim.config.yml └── package.jsoncontent目录放的是你所有的文字内容文件格式是 Markdown。themes目录放主题模板一个项目可以同时放多套主题在配置里切换。public是构建产物所在目录就是最终可以上传到服务器的完整站点文件平时不需要手动改。pilgrim.config.yml是全局配置文件站名、描述、域名、语言、构建选项都在这里。这里最有价值的一点是目录结构本身已经代表了内容组织方式你不需要额外维护一份“栏目表”。在content/posts下新建文件它天然就是博客文章在content/pages下新建文件它天然就是独立页面。这种约定优于配置的设计极大降低了上手成本。3. 内容写作用 Markdown 搭建网页内容的节奏3.1 front-matter 让每篇文章自带“身份证”每篇 Markdown 文件顶部都可以写一段 YAML 格式的 front-matter用来声明这篇文章的元信息。最基本的例子长这样--- title: Hello Pilgrim date: 2025-01-12 tags: [随笔, 工具] draft: false summary: 这是我的第一篇 Pilgrim 文章简单记录一下初始化过程。 ---title是标题date是发布日期tags是标签draft是草稿标记。这里有个细节date最好写带时区的完整格式如果你用2025-01-12这种纯日期Pilgrim 在判断“最新文章”排序时会按当天零点算如果你人在东八区、构建服务器在美国偶尔会出现文章日期差一天的诡异现象。我习惯写成2025-01-12T09:30:0008:00一劳永逸。summary这个字段很多人会忽略但它会被自动用在首页文章列表、RSS 和分享卡片上。不写的话Pilgrim 会尝试截取正文开头结果往往是截到一半中文字符显示效果很难看。建议每篇文章动笔前先花三十秒写好 summary后面所有地方都省心。3.2 文章、页面与“合集”的门道Pilgrim 内置了posts和pages两种默认内容类型。content/posts/xxx.md会被统计进博客文章流参与首页列表、归档、标签聚合适合写有时效性的东西。content/pages/xxx.md是独立页面比如“关于我”“友情链接”“项目列表”它们不会出现在博客文章列表里只有通过导航或者链接才能访问。如果你想自定义一种内容类型可以在配置文件里新增合集collection。比如我想单独维护一个“读书笔记”专栏不跟日常博客混在一起就在配置里加上对应的合集定义。新增合集之后content/notes/目录下的文章会自动聚合并生成独立的列表页和 RSS。用这个方式可以把阅读笔记、技术折腾记录、生活随笔分成三个各自独立的频道互不干扰访客一目了然。这里提醒一句自定义合集的功能很强大但别一开始就规划一堆类型。我见过有人刚上手就定义了七八个合集结果写作时还要纠结“这篇文章该放哪个类目”反而降低更新的动力。先集中写博客文章等量上来了再拆更符合实际使用节奏。3.3 本地预览阶段该养成的写作习惯写作阶段我会一直开着pilgrim serve --drafts。加--drafts参数后草稿状态的文章也会在本地渲染这样写到一半就能看排版效果。写完一个段落保存浏览器即时刷新预览器支持目录锚点跳转点文章里的标题就能直接跳到对应位置。我还有一个习惯是草稿同样走 Git 提交。很多人的误区是草稿不提交结果换电脑或者误删文件之后追悔莫及。草稿虽然不用发布上线但它也是内容资产的一部分我会把整篇文章的待整理片段都写在同一个 Markdown 里用draft: true标记等全文完成后再改成false并构建发布。4. 主题与模板把默认外观换成自己的4.1 主题目录里的文件到底各自负责什么默认主题够整洁但如果你想要自己的视觉风格就得了解主题结构。一个 Pilgrim 主题大致是这样的themes/default/ ├── layouts/ │ ├── base.html │ ├── index.html │ ├── post.html │ ├── page.html │ └── partials/ │ ├── header.html │ └── footer.html ├── assets/ │ ├── css/ │ └── js/ └── theme.ymllayouts/base.html是整站的骨架包含html、head、导航和页脚的结构其他页面模板通过继承它来复用公共部分。index.html是首页列表模板post.html是单篇文章模板page.html是独立页面模板。partials目录里放被多处引用的局部组件比如页头、页脚。这种组织方式是模板引擎的通用做法理解一遍之后到其他工具里也同样适用。换主题只需要在配置里改一个字段。我一般把自己改的主题放进themes/my-theme/目录不动默认主题这样哪怕把主题改坏了切回default就能恢复。4.2 模板变量在“骨架”里渲染内容模板文件里可以访问到当前页面和站点信息。最常用的变量是page和site。举个例子在post.html里我要输出标题、日期和正文就写{% extends layouts/base.html %} {% block content %} article h1{{ page.title }}/h1 time datetime{{ page.date | date(%Y-%m-%d) }}{{ page.date | date(%Y-%m-%d) }}/time div classcontent {{ page.content }} /div /article {% endblock %}{{ page.title }}会输出 front-matter 里的标题{{ page.content }}会输出 Markdown 渲染后的 HTML。模板里还支持循环比如首页列表页要遍历所有文章{% for post in collections.posts %} a href{{ post.url }} h2{{ post.title }}/h2 p{{ post.summary }}/p /a {% endfor %}这里collections.posts代表博客文章合集post.url是文章链接。模板变量体系不复杂掌握page、site、collections三组就够应对绝大多数自定义需求。需要更复杂的逻辑时Pilgrim 也允许在配置里注册自定义过滤器或者函数但实际用下来大部分个人站点根本用不到不要被复杂模板技术吓到。4.3 链接与静态资源最容易翻车的一环自定义主题时最常遇见的问题不是模板语法而是资源路径。如果你在模板里写img src/images/pic.png本地预览没问题部署到 GitHub Pages 的子目录下就全部 404因为站点不是部署在域名根目录。Pilgrim 的思路是尽量在模板里使用相对路径。比如在文章模板里引用图片应该结合当前页面的路径来写或者在配置里统一指定baseUrl然后模板里这样写img src{{ site.baseUrl }}/images/pic.png构建时site.baseUrl会被替换成你配置的最终地址。如果暂时没有域名、直接部署在 GitHub Pages 的项目仓库下把baseUrl配成仓库路径即可这样无论本地还是线上资源都能正确加载。静态资源文件放在主题的assets目录下构建时会被复制到public对应的目录里别把它们手动塞进public因为public每次构建都可能被覆盖。5. 上线发布构建、部署和一点 SEO5.1 构建生产包先检查产物再上线发布前执行构建命令pilgrim build构建完成后检查public目录下的文件。重点看这么几个东西首页index.html是否更新sitemap.xml是否包含全部文章rss.xml是否能正常访问CSS 和 JS 文件是否存在于assets目录下。我有一次写完文章构建后首页文章列表没更新排查半天发现是构建缓存的问题清掉缓存重新构建就好了。在你把整个public目录推上线之前先本地静态预览一次确认所有页面、样式、图片都在。这一步能拦截掉大多数因为路径或缓存导致的线上问题省得部署后反复刷新验证。5.2 部署到 GitHub Pages 与普通服务器如果你用 GitHub Pages流程非常简单。把项目推到远程仓库然后在package.json里加一个部署脚本让pilgrim build结束后把public目录推送到gh-pages分支。GitHub Pages 会直接以gh-pages分支的根目录作为站点内容整个过程全自动非常稳定。如果你有自己的服务器思路也一样本地构建出完整的public目录然后用rsync或scp传到 web 根目录。Nginx 配置就一个要点确保 try_files 指向首页文件比如server { listen 80; server_name example.com; root /var/www/my-blog/public; location / { try_files $uri $uri/ /index.html; } }因为 Pilgrim 生成的页面路径不会带奇怪的参数普通静态文件的try_files就够了。如果后续想上 HTTPS用 Lets Encrypt 配置证书这里不再展开。5.3 SEO 基础配置标题、描述与结构化内容静态站点拿 SEO 是天然优势页面加载快、HTML 干净但你需要主动把信息喂给搜索引擎。我在pilgrim.config.yml里维护了站点描述、关键词、语言和分享用的封面图构建时 Pilgrim 会把它们写进每个页面的head里形成完整的 meta 信息。每篇文件的summary也是 SEO 的一部分它会被用在搜索结果摘要和社交卡片上。写完文章补充一张尺寸合适的封面图并把它放在 front-matter 的cover字段里这样分享到社交平台时不会只显示一个光秃秃的标题。RSS 和 sitemap 自动生成以后不需要手动维护搜索引擎也会更理解站点的更新时间规律。6. 我踩过的坑故障排查和效率笔记6.1 高频问题与解决办法我把自己用 Pilgrim 期间遇到的高频问题整理成了速查表现象常见原因解决办法改完文章页面不更新模板缓存或者开发服务器异常重启pilgrim serve再不行清缓存后重新构建首页列表少了一篇文章忘了给文章写date或日期写错格式补全 front-matter使用带时区的完整日期格式图片部署后 404用了绝对路径/images/改为基于site.baseUrl的路径标签页没有正常生成配置里启用了标签但文章没打标检查文章的tags字段重新pilgrim build中文链接变成一串乱码未启用 slug 化功能在 front-matter 里显式指定slug字段样式在本地正常、线上失效静态资源被复制到了错误的相对路径检查public目录结构和模板里的资源引用方式这里最值得花时间解决的是第五个问题。普通中文标题生成链接时如果不指定 slugURL 里可能会带着一长串无法阅读的字符。我习惯在每篇文章的 front-matter 里写一个英文短链比如slug: hello-pilgrim这样链接分享出去干净专业也不会因为中文编码造成兼容问题。6.2 让写作节奏更顺手的几个小习惯用了一段时间之后我总结出几个提升效率的小习惯。首先是给文章统一模板。我在项目里放了一个_template.md文件把 front-matter 里常用的字段全部写好每次新写文章直接复制改名打开就是可以填内容的状态不用每次都重新敲一遍 YAML。其次是给文章目录加一个简单的命名规则。文章文件名不直接影响 URL因为可以指定slug但会影响你找文件的速度。我用“日期-英文短名”的格式比如2025-01-12-hello-pilgrim.md在文件列表里按时间排序找几个月前的文章也很容易。最后是定期做一次“内容体检”。评分标准很简单每篇文章是否有 summary、是否有 tags、是否有合适的封面、文章里的链接是否还有效。对照标准逐个检查比等到访客发邮件告诉你链接失效再补救要舒服得多。6.3 最后分享一个小技巧我自己最受益的一个习惯是给 Pilgrim 项目加一个 Git hook在每次执行pilgrim build之后自动把public目录推送给托管平台。这样我写完文章只需要执行一个命令构建和发布就连贯完成了中间几乎不需要手动操作。很多工具都在追求“少操心”Pilgrim 已经帮我省掉了数据库和服务器这些麻烦我再把发布流程自动化一点点整个写作链路就变得非常轻。你如果也正在折腾静态站点值得从这些细节里找一找适合自己的节奏。