Eleventy:轻量级静态站点生成器的深度解析

2025-06-30 08:30:13

在现代前端开发中,静态网站生成器因其部署简单、性能优异、维护成本低等优势而广受欢迎。Eleventy(11ty)作为其中的佼佼者,凭借其无框架依赖、高度可定制和极简配置的特点,逐渐成为众多开发者构建博客、文档站、作品集等项目的首选工具。

Eleventy 由 Zach Leatherman 创建,目标是提供一个不依赖特定前端框架(如 React 或 Vue)的静态站点生成方案。它支持多种模板语言,包括 Markdown、Nunjucks、Liquid、Handlebars、JavaScript(.11ty.js)等,并通过数据文件(JSON、YAML、JavaScript)实现内容与模板的分离。这种灵活性使得 Eleventy 成为一个非常通用且易于集成的构建工具。

Logo

核心架构与工作原理

Eleventy 的设计哲学是“最小化抽象”,它没有内置复杂的构建流程或运行时框架,而是专注于将源文件转换为静态 HTML 文件。其核心处理流程可以分为以下几个阶段:

  1. 输入收集:Eleventy 扫描指定的输入目录(默认为 [.](file://d:\VSProjects\awesometop-spider\LICENSE)),识别所有符合模板规则的文件。
  2. 元数据提取:从 YAML Front Matter、数据文件(如 [.json](file://d:\VSProjects\awesometop-spider\node_modules@prisma\debug\package.json)、[.js](file://d:\VSProjects\awesometop-spider\node_modules@prisma\client\edge.js))中提取页面元信息,用于控制输出路径、模板继承、变量注入等行为。
  3. 模板渲染:根据模板引擎对文件进行编译,结合全局数据和局部数据生成最终的 HTML 内容。
  4. 输出写入:将生成的 HTML 文件写入指定的输出目录(默认为 _site)。

Eleventy 支持多层布局嵌套,允许开发者定义基础模板(layout),并通过子模板覆盖部分内容。例如,一个典型的博客文章页面可以继承自 layouts/post.njk,并在头部声明该布局并提供标题、日期等信息。

---
layout: layouts/post.njk
title: "我的第一篇博客"
date: 2023-10-01
---

这是文章正文内容。

Eleventy 还引入了“集合”(collections)的概念,开发者可以通过过滤和分组的方式创建自定义内容集合,比如“所有标签为 ‘javascript’ 的文章”。这为导航菜单、归档页、分类页等功能提供了强大的支持。

安装与初始化配置

Eleventy 是一个基于 Node.js 的命令行工具,因此首先需要确保系统已安装 Node.js 和 npm。

安装 Eleventy

推荐使用 npm 在项目本地安装 Eleventy,这样可以避免版本冲突问题:

npm init -y
npm install @11ty/eleventy --save-dev

随后可以在 [package.json](file://d:\VSProjects\awesometop-spider\node_modules@prisma\debug\package.json) 中添加启动脚本:

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

执行以下命令即可启动本地开发服务器:

npm run serve

默认情况下,Eleventy 会在当前目录查找源文件,并将生成的 HTML 输出到 _site 目录。如果需要更改输入输出路径,可在 .eleventy.js 配置文件中设置:

module.exports = function(eleventyConfig) {
  return {
    dir: {
      input: "src",
      output: "dist"
    }
  };
};

基础目录结构示例

一个典型的 Eleventy 项目结构如下:

my-site/
├── .eleventy.js
├── package.json
├── src/
│   ├── _data/
│   │   └── site.json
│   ├── _includes/
│   │   └── layout.njk
│   ├── index.md
│   └── posts/
│       └── hello-world.md
└── dist/
  • _data/:存放全局可用的数据文件,如站点名称、菜单项等。
  • _includes/:存放布局模板和组件片段。
  • posts/:存放 Markdown 博客文章。
  • index.md:首页内容。

模板系统与数据绑定

Eleventy 支持多种模板语言,开发者可以根据项目需求自由选择。每种模板都会被编译成 HTML 并写入输出目录。

使用 Nunjucks 模板

Nunjucks 是一种功能强大且语法清晰的模板语言,适合构建复杂页面。以下是一个基础布局模板:

<!-- src/_includes/layout.njk -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>{{ title }}</title>
</head>
<body>
  <header>
    <h1>{{ site.title }}</h1>
    <nav>
      <ul>
        {% for item in menu %}
          <li><a href="{{ item.url }}">{{ item.text }}</a></li>
        {% endfor %}
      </ul>
    </nav>
  </header>

  <main>
    {{ content | safe }}
  </main>
</body>
</html>

在 Markdown 文件中引用该布局:

---
layout: layout.njk
title: 首页
menu:
  - text: 首页
    url: /
  - text: 关于我
    url: /about/
---

欢迎来到我的网站!

在这个例子中,menu 数据来自当前页面的 Front Matter,site.title 则来源于 _data/site.json

使用 JavaScript 模板

对于更高级的逻辑处理,Eleventy 允许使用 .11ty.js 文件编写模板。这种方式特别适用于动态生成内容,如 RSS Feed、sitemap.xml 等。

// src/rss.11ty.js
module.exports = {
  data() {
    return {
      permalink: "/rss.xml",
      eleventyExcludeFromCollections: true
    };
  },
  render(data) {
    const itemsXml = data.collections.all.map(item => `
      <item>
        <title>${item.data.title}</title>
        <link>${item.url}</link>
        <description>${item.templateContent}</description>
      </item>
    `).join("");

    return `
      <?xml version="1.0" encoding="utf-8"?>
      <rss version="2.0">
        <channel>
          <title>我的博客</title>
          <link>https://example.com</link>
          ${itemsXml}
        </channel>
      </rss>
    `;
  }
};

上述代码会生成一个 RSS 订阅源,并将其输出为 /rss.xml

集合与内容组织

Eleventy 提供了灵活的内容组织机制,其中最核心的是“集合”(collections)。集合是一组具有相同特征的模板对象,可用于生成归档页、分类列表、标签云等内容。

创建自定义集合

.eleventy.js 中注册一个新的集合:

module.exports = function(eleventyConfig) {
  eleventyConfig.addCollection("blogPosts", function(collectionApi) {
    return collectionApi.getFilteredByGlob("src/posts/*.md");
  });

  return {};
};

然后可以在模板中访问这个集合:

<ul>
  {% for post in collections.blogPosts %}
    <li>
      <a href="{{ post.url }}">{{ post.data.title }}</a>
    </li>
  {% endfor %}
</ul>

分类与标签

Eleventy 支持通过 Front Matter 定义标签,并自动聚合相关内容。例如,在 Markdown 文件中添加:

tags:
  - javascript
  - tutorial

随后可以创建一个按标签分组的页面:

// src/tags.11ty.js
module.exports = {
  data() {
    return {
      permalink: "/tags/{{ tag }}/",
      pagination: {
        data: "collections",
        size: 1,
        alias: "tag",
        filter: (item) => item.startsWith("tag-")
      }
    };
  },
  render(data) {
    const posts = data.collections[data.tag];
    return `
      <h1>标签:{{ tag }}</h1>
      <ul>
        {% for post in posts %}
          <li><a href="{{ post.url }}">{{ post.data.title }}</a></li>
        {% endfor %}
      </ul>
    `;
  }
};

总结

Eleventy 以其简洁的设计理念、灵活的模板系统和强大的内容管理能力,成为静态网站生成领域的一匹黑马。它不仅适合构建个人博客、技术文档、企业官网等项目,也因其轻量无依赖的特性,能够轻松集成到 CI/CD 流程中,提升部署效率。

通过合理的目录结构、多样化的模板语言支持以及丰富的数据绑定机制,Eleventy 为开发者提供了一个既能满足基本需求又能应对复杂场景的工具链。

11ty
Eleventy 是一个更简单的静态站点生成器,支持将不同的模板类型转换为HTML。
JavaScript
MIT
18.4 k