尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于Eleventy与new.css构建极简静态博客:从技术选型到部署实践

基于Eleventy与new.css构建极简静态博客:从技术选型到部署实践 1. 项目概述一个AI开发者代理的静态博客最近在折腾个人博客发现了一个挺有意思的开源项目叫“Rooks Gambit”。这是一个由名为“Rook”的AI开发者代理Agent维护的技术博客。项目本身结构清晰技术栈选型也很有特点使用了静态站点生成器Eleventy11ty搭配一个名为“new.css”的终端风格主题。对于想快速搭建一个极简、高效、且自带“极客范儿”博客的开发者来说这个项目提供了一个非常不错的起点和参考。我自己也基于它做了一些定制和深度使用今天就来拆解一下这个项目的核心设计、实操细节以及我在部署和内容管理过程中踩过的一些坑。这个博客的定位很明确一个纯粹以内容为中心的开发者日志。它没有复杂的后台没有数据库所有文章都是Markdown文件通过11ty编译成静态HTML。这种架构决定了它的核心优势速度快、安全性高、几乎零维护成本并且可以轻松托管在GitHub Pages、Netlify、Vercel等任何静态托管服务上。特别适合像我这样希望把精力聚焦在写作本身而不是折腾服务器和运维的开发者。2. 技术栈选型与设计思路解析2.1 为什么是Eleventy11ty在众多静态站点生成器SSG中11ty可能不像Hugo或Gatsby那样名声在外但它有几个独特的优势恰好契合了这个AI代理博客的需求。首先零配置与灵活性的平衡。11ty号称“更简单的静态站点生成器”它确实可以开箱即用但你也能通过配置文件.eleventy.js或eleventy.config.js进行深度定制。对于Rooks Gambit这个项目它需要在子目录/agents/rook/下部署这通过11ty的pathPrefix配置可以轻松实现避免了路径混乱的问题。很多其他SSG在处理子路径时需要额外的插件或复杂的重写规则而11ty原生支持就很好。其次模板语言的自由选择。11ty不强制你使用某一种模板语言它支持Liquid、Nunjucks、Handlebars、Markdown等多种语言甚至可以在同一个项目中混用。这给了开发者极大的自由度。从项目代码看它主要使用了Nunjucks这种语法对于有Jinja2或Django模板经验的开发者来说非常友好功能强大且逻辑清晰。最后构建速度极快。由于11ty不捆绑前端框架如React它的构建过程非常轻量和快速。对于一个博客项目文章数量增长后构建速度是一个很重要的考量点。我实测过一个包含上百篇文章的项目11ty能在几秒内完成全量构建这对于自动化部署流程如GitHub Actions的体验提升是巨大的。2.2 “new.css”主题极简主义的终端美学项目的视觉风格由new.css框架定义。这不是一个传统的CSS框架如Bootstrap而是一个“极简的、类终端风格的CSS框架”。它的设计哲学是仅通过语义化HTML标签来定义样式无需添加额外的CSS类。这意味着你写一个h1它自动就是终端风格的大标题写一个code块它自动呈现为等宽字体加背景色。这种设计带来了几个好处极致的写作体验作者只需要关注Markdown内容本身即语义化结构无需分心去考虑样式类名。极小的体积整个框架的CSS文件非常小对页面加载速度有极大提升。独特的风格终端风格在技术博客中辨识度很高能立刻营造出“开发者专属”的氛围。当然这种设计也有局限。如果你想进行深度定制比如改变颜色方案或布局结构就需要直接修改new.css的源码或覆盖其样式而不是通过添加类名的方式。对于追求高度定制化的开发者来说这可能是一个需要考虑的点。不过对于Rooks Gambit这个项目这种“约定大于配置”的风格恰恰符合其简洁、专注内容的定位。2.3 子目录部署的考量项目明确配置了pathPrefix用于子目录/agents/rook/托管。这是一个非常实用的设计尤其适用于以下场景作为大型网站的一部分比如你的个人主站在根目录而博客只是其中一个子版块如yourdomain.com/blog。GitHub Pages的项目站点GitHub Pages支持用户仓库username.github.io和项目仓库两种。项目仓库的站点默认地址就是username.github.io/repo-name这正是子目录结构。多代理/多博客管理从项目中的AGENTS.md文件可以推测这可能是一个更大项目的一部分其中包含多个“代理”Agent每个代理都有自己的博客子目录。这种结构便于统一管理。在11ty中配置pathPrefix后所有资源路径CSS、JS、图片和内部链接都需要通过{{ ‘/path/to/file’ | url }}过滤器进行处理以确保在子目录下能正确加载。这是使用11ty进行非根部署时必须注意的关键点否则很容易出现404错误。3. 项目结构与核心文件详解拿到一个开源项目理清其目录结构是第一步。Rooks Gambit的结构非常典型遵循了11ty的最佳实践。rook-blog/ ├── _site/ # 构建输出目录.gitignore忽略 ├── src/ # 源代码目录 │ ├── posts/ # 博客文章Markdown文件 │ ├── css/ # 样式文件包含new.css │ ├── js/ # 可选的JavaScript脚本 │ └── _includes/ # 模板组件Nunjucks │ ├── layouts/ # 基础布局模板 │ └── (其他局部模板) ├── eleventy.config.js # 11ty核心配置文件 ├── package.json # 项目依赖和脚本 └── README.md # 项目说明3.1 核心配置文件eleventy.config.js这个文件是项目的大脑。我们来看一下它通常需要配置的关键部分基于项目描述和常见实践module.exports function(eleventyConfig) { // 1. 设置路径前缀用于子目录部署 eleventyConfig.addPassthroughCopy(src/css); eleventyConfig.addPassthroughCopy(src/js); eleventyConfig.addPassthroughCopy(src/images); // 2. 配置输入、输出目录 return { dir: { input: src, output: _site, includes: _includes, data: _data }, pathPrefix: /agents/rook/, // 关键配置子目录路径 templateFormats: [md, njk, html], markdownTemplateEngine: njk, htmlTemplateEngine: njk }; };关键配置解析addPassthroughCopy: 这条指令告诉11ty将src/css/等目录下的文件原样复制到输出目录_site中。这对于静态资源样式表、脚本、图片是必须的因为11ty默认只处理模板文件。pathPrefix: “/agents/rook/”: 这是项目的灵魂配置。它确保了所有生成的页面链接和资源引用都会自动带上这个前缀。markdownTemplateEngine: “njk”: 这指定了Markdown文件将使用Nunjucks模板引擎进行预处理。这非常重要因为它允许你在Markdown文章中使用Nunjucks的模板语法比如调用{{ ‘/css/style.css’ | url }}过滤器来生成正确的资源路径。3.2 文章模板与Front Matter所有博客文章都存放在src/posts/目录下文件名格式为YYYY-MM-DD-post-title.md。这种命名方式不仅便于按日期排序也使得URL清晰易读。每篇文章的头部都有一个YAML格式的Front Matter用于定义元数据--- title: “深入理解JavaScript事件循环” date: 2023-10-27T14:30:00 description: “本文通过实例详细讲解了浏览器中JavaScript事件循环的工作原理以及宏任务与微任务的区别。” tags: - JavaScript - 前端 - 核心概念 ---Front Matter各字段解读与实操技巧title和description: 除了用于页面显示更是SEO搜索引擎优化的关键。description会生成页面的meta name“description”标签是搜索结果中显示的片段务必简洁、准确地概括文章核心。date: 注意格式是ISO 8601YYYY-MM-DDTHH:MM:SS。你可以省略时间部分只写日期。这个日期用于文章排序和存档页面的生成。tags: 这是一个数组用于给文章打标签。在11ty中你可以非常方便地创建一个“标签”合集页面自动聚合所有包含某个标签的文章。这是组织内容、提升站内导航体验的利器。实操心得我建议在Front Matter中增加一个slug字段。有时文章的标题可能很长或者包含特殊字符你不希望它直接出现在URL中。你可以设置slug: “understanding-js-event-loop”然后在11ty配置中通过permalink函数来生成更简洁、友好的URL这对SEO和可读性都有好处。4. 从零开始的完整搭建与部署流程假设你现在想基于Rooks Gambit搭建自己的博客以下是详细的步骤和注意事项。4.1 本地开发环境搭建获取代码git clone https://github.com/haliphax-ai/rook-blog.git my-blog cd my-blog安装依赖 项目使用npm管理依赖执行npm install。这一步会安装11ty及其相关插件。如果网络较慢可以考虑配置国内镜像源或使用yarn、pnpm等替代工具。启动本地开发服务器npm start这通常对应着package.json中scripts下的“start”: “eleventy --serve”命令。--serve参数会启动一个本地服务器默认在http://localhost:8080并启用热重载功能。当你修改任何源文件Markdown、模板、CSS时浏览器页面会自动刷新开发体验非常流畅。编写第一篇文章 在src/posts/目录下新建文件2023-10-27-my-first-post.md。按照上述Front Matter格式填写标题、日期和描述然后在下面用Markdown语法开始写作。保存后立即在浏览器中查看效果。4.2 构建与生产发布当文章写完准备发布到线上时需要执行构建命令npm run build这对应“build”: “eleventy”脚本。11ty会读取所有模板和内容进行渲染并将最终的静态文件输出到_site目录。你可以直接检查这个目录里面就是完整的、可以托管到任何Web服务器上的网站文件。构建过程深度解析数据聚合11ty首先会读取_data目录下的全局数据文件如site.json以及每篇文章的Front Matter。模板渲染它遍历所有模板文件.njk, .md等将数据注入模板。对于文章列表页它会使用“合集”Collections功能自动将所有文章按日期排序并传递给模板。资源复制通过addPassthroughCopy指定的静态资源被复制到输出目录。路径处理所有在模板中使用了| url过滤器的链接都会自动加上pathPrefix中配置的前缀。文件生成最终一个个HTML、CSS、JS文件在_site目录下生成。4.3 部署到GitHub Pages实战示例这是最常用且免费的托管方式之一。假设你的GitHub用户名是yourusername仓库名是my-blog。修改配置在eleventy.config.js中将pathPrefix修改为你的仓库名。因为项目站点的访问地址是https://yourusername.github.io/my-blog/。pathPrefix: process.env.NODE_ENV ‘production’ ? ‘/my-blog/’ : ‘’,这里用了一个小技巧通过环境变量NODE_ENV来判断是开发环境还是生产环境。开发时路径前缀为空方便本地预览构建生产包时前缀生效。创建GitHub仓库在GitHub上新建一个名为my-blog的公共仓库。关联并推送代码# 移除原有的git历史如果是克隆的rook-blog rm -rf .git git init git add . git commit -m “Initial commit” git branch -M main git remote add origin https://github.com/yourusername/my-blog.git git push -u origin main配置GitHub Actions自动部署 在项目根目录创建.github/workflows/deploy.yml文件name: Deploy to GitHub Pages on: push: branches: [ main ] jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkoutv3 - name: Setup Node.js uses: actions/setup-nodev3 with: node-version: ‘18’ - name: Install Dependencies run: npm ci - name: Build run: NODE_ENVproduction npm run build - name: Deploy uses: peaceiris/actions-gh-pagesv3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./_site publish_branch: gh-pages # 部署到gh-pages分支这个工作流会在你每次推送代码到main分支时自动触发安装依赖、构建项目并将_site目录下的内容推送到仓库的gh-pages分支。GitHub Pages会自动从gh-pages分支获取内容并发布。启用GitHub Pages在仓库的Settings - Pages页面将Source设置为Deploy from a branch分支选择gh-pages根目录/。保存后稍等几分钟你的博客就可以通过https://yourusername.github.io/my-blog/访问了。5. 深度定制与功能扩展指南原项目是一个极简的起点但一个成熟的博客通常需要更多功能。以下是几个常见的扩展方向。5.1 添加代码高亮技术博客离不开代码片段。原生的new.css只是给code和pre加了基本样式没有语法高亮。我们可以集成Prism.js。安装Prismnpm install prismjs创建高亮模板在src/_includes/下创建一个code.njk宏macro或短代码shortcode。// 在 eleventy.config.js 中添加 const Prism require(‘prismjs’); const loadLanguages require(‘prismjs/components/’); // 加载你需要的语言例如javascript, bash, python loadLanguages([‘javascript’, ‘bash’, ‘python’, ‘css’, ‘markup’]); eleventyConfig.addPairedShortcode(‘code’, function(content, language) { const highlighted Prism.highlight(content, Prism.languages[language], language); return pre class“language-${language}”code class“language-${language}”${highlighted}/code/pre; });在文章中使用{% code “javascript” %} function hello() { console.log(‘Hello, Rook!’); } {% endcode %}5.2 实现文章搜索功能静态站点的搜索是一个经典问题。一个轻量级的方案是使用lunr.js在客户端实现搜索。生成搜索索引在构建时创建一个包含所有文章标题、描述、内容和URL的JSON索引文件。// 在 eleventy.config.js 中添加 eleventyConfig.addCollection(‘searchIndex’, function(collectionApi) { return collectionApi.getAll().filter(item item.data.tags).map(item ({ title: item.data.title, description: item.data.description, content: item.templateContent, url: item.url, tags: item.data.tags })); });然后在模板中生成这个索引的JSON文件。创建搜索页面新建一个search.njk页面引入lunr.js和上面生成的索引JSON。编写JavaScript代码读取索引提供实时搜索和结果展示功能。优化体验对于文章数量很多比如超过100篇的博客索引文件可能会很大。可以考虑只索引标题、描述和标签或者对内容进行截断以控制文件大小提升页面加载速度。5.3 优化SEO与社交媒体分享虽然11ty生成的静态站点对SEO天生友好但我们还可以做得更好。自动生成Sitemap使用quasibit/eleventy-plugin-sitemap插件可以自动生成sitemap.xml帮助搜索引擎抓取。优化Open Graph和Twitter Cards在_includes/layouts/base.njk这样的基础布局中动态生成meta property“og:title”、og:description、og:image等标签。这些标签决定了你的文章在微信、Twitter、LinkedIn等社交媒体上分享时的预览效果。图片og:image尤其重要可以设置为文章首图或者一个统一的博客Logo。规范链接Canonical URL确保每个页面都有正确的link rel“canonical”标签指向页面的权威网址避免重复内容问题。6. 常见问题与故障排查实录在实际使用和部署过程中我遇到并解决了一些典型问题。6.1 路径错误导致CSS/JS无法加载问题现象本地开发一切正常但部署到GitHub Pages或其他子目录后页面样式丢失控制台报错找不到CSS/JS文件。根本原因模板中的资源链接没有使用| url过滤器或者pathPrefix配置不正确。解决方案检查模板确保所有资源引用都像这样link rel“stylesheet” href“{{ ‘/css/new.css’ | url }}”。注意路径以/开头。检查配置确认eleventy.config.js中的pathPrefix与你的实际部署路径完全一致。对于GitHub Pages项目站点通常是‘/repository-name/’。环境变量区分如前所述使用环境变量来区分开发和生产环境的pathPrefix是最佳实践。6.2 文章日期排序混乱或无法显示问题现象文章列表页的文章顺序不对或者文章的发布日期没有显示。原因分析Front Matter日期格式错误确保日期格式是YYYY-MM-DD或YYYY-MM-DDTHH:MM:SS。错误的格式会导致11ty无法正确解析。合集Collection配置默认情况下11ty会按照文件创建日期排序。为了按文章Front Matter中的date字段排序你需要在创建合集时指定排序方式。解决方案在eleventy.config.js中可以这样配置一个按日期降序排列的文章合集eleventyConfig.addCollection(‘posts’, function(collectionApi) { return collectionApi.getFilteredByGlob(‘src/posts/*.md’).sort((a, b) { return b.date - a.date; // 降序最新的在前 }); });然后在模板中遍历collections.posts即可。6.3 构建速度突然变慢问题现象随着文章数量增加npm run build的时间显著变长。排查与优化检查图片处理如果你使用了eleventy-img这类图片处理插件并且文章中有大量高清图片这会是构建的主要瓶颈。考虑在开发时跳过图片优化或者使用缓存。精简模板逻辑检查你的Nunjucks模板避免在模板中进行过于复杂的计算或数据操作。尽量将数据处理逻辑移到11ty的配置或自定义过滤器中。启用增量构建在开发时使用eleventy --serve --incremental命令。--incremental参数会只重新构建更改过的文件极大提升开发服务器的热重载速度。但注意对于某些复杂的依赖关系增量构建可能不会完全更新必要时仍需全量构建。升级Node.js和11ty版本新版本通常有性能改进。6.4 自定义样式与new.css的冲突问题现象你想修改某个元素的样式比如链接颜色但自己写的CSS规则似乎不生效。原因与解决new.css是一个“CSS框架”它直接为HTML标签定义了样式。CSS的层叠规则是后定义的样式会覆盖先定义的。你需要确保你的自定义CSS文件在HTML中晚于new.css被引入。head link rel“stylesheet” href“{{ ‘/css/new.css’ | url }}” !-- 你的自定义样式必须放在后面 -- link rel“stylesheet” href“{{ ‘/css/custom.css’ | url }}” /head在custom.css中你可以使用相同的标签选择器或更具体的选择器来覆盖new.css的样式。例如要修改链接颜色/* custom.css */ a { color: #ff6b6b; /* 这会覆盖new.css中的链接颜色 */ } a:hover { color: #ee5a52; }7. 从“博客引擎”到“内容系统”的思考使用Rooks Gambit这类静态生成方案最大的收获不仅仅是搭建了一个博客而是理解了一种内容管理的哲学将内容Markdown与表现模板/样式分离并通过版本控制Git来管理一切。这种模式带来了几个深远的好处可移植性你的所有文章都是纯文本文件未来无论想迁移到Hugo、Gatsby还是其他任何系统转换成本都极低。可追溯性每一篇文章的每一次修改都通过Git提交历史记录了下来。你可以清晰地看到内容的演进过程。自动化集成结合GitHub Actions/GitLab CI等工具可以实现“写作 - 推送 - 构建 - 部署”的全自动化流水线。你甚至可以用脚本自动提取文章摘要、生成社交分享图等。对于“AI开发者代理”这个背景这种架构更是完美契合。AI可以像开发者一样通过编写和提交Markdown文件来“发布”文章整个流程完全代码化、自动化无需人工干预内容发布平台。这或许就是未来内容创作与运维的一种新形态。我个人在将这个博客框架用于自己的技术笔记后最大的体会是“心无旁骛”。我再也不用担心数据库备份、服务器安全、WordPress插件更新这些问题。所有的“运维”工作就是偶尔运行一下git push。剩下的时间可以全部投入到思考和写作本身。如果你也受够了动态博客的繁琐或者想拥有一个完全属于自己的、高速且稳定的内容基地那么基于Eleventy和类似Rooks Gambit这样的起点亲手搭建一个会是一个非常值得投入的选择。
返回列表