#5798·hexo

‌支持引入 Hexo Component System

Author: MHuiGCreated Jul 22, 2026Updated Jul 23, 2026

Check List

  • I have already read Docs page.
  • I have already searched existing issues.

Feature Request

目前hexo作用的最细粒度是整个页面,而vue和astro等现代框架的最细粒度是组件,astro还引入了群岛架构的概念。这是Hexo显得比较落后不够现代的原因之一。

Others

我咨询了 DeepSeek,它给出了一套路线图,不确定这是否有用。

路线图

引入“组件化”概念,本质上是要‌在静态生成阶段,将页面拆解为可独立开发、组合和复用的组件单元‌,同时保留 Hexo 的极速生成和 Markdown 中心化体验。这套方案可以称为 ‌Hexo Component System (HCS)‌。

以下是技术实现路径和关键设计:

  1. 扩展核心概念:定义“组件”为一级资源

在 Hexo 的现有架构中,source/ 目录下只有 _posts、_drafts、_data 等预定义资源类型。我们需要新增一个 _components 目录,作为组件的物理载体。

source/
  _components/
    my-card/
      template.njk      # 组件模板(支持 Nunjucks/EJS/Pug)
      style.styl        # 组件样式(Stylus/Sass/CSS)
      script.js         # 组件逻辑(可选的编译时辅助函数)
      config.yml        # 组件元数据(名称、分类、属性声明)

组件通过 config.yml 声明其接口(props),例如:

yaml
# config.yml
name: my-card
props:
  title: string
  image: string
  link: string

这样,组件就拥有了‌明确的输入约定‌,类似于 Vue 的 props。

  1. 注册与解析机制:利用 Hexo 的插件系统

Hexo 已具备强大的扩展能力(hexo.extend),我们可以通过几个新增的扩展点来接管组件生命周期:

hexo.extend.component.register(name, handler)‌:注册组件处理器,负责编译模板、合并样式、封装逻辑。 hexo.extend.filter.register('after_render:component', callback)‌:允许插件在组件渲染后对内容进行后处理(如注入 CSS 变量、添加作用域标识)。 hexo.extend.generator.register('component_assets')‌:生成组件的静态资源(样式、脚本),并自动注入到页面中。

核心实现流程:

Hexo 启动时,扫描 source/_components/ 下的所有组件目录。 读取每个组件的 config.yml,将其注册为 hexo.component 实例。 编译组件模板(使用已有的模板引擎),生成一个‌渲染函数‌,该函数接收 props 并返回 HTML 片段。 收集组件的样式和脚本,合并后通过注入器(injector)嵌入到最终页面中。 3. 在模板中使用组件:引入自定义标签

为了让用户像使用 Vue 组件一样在 Markdown 或模板中调用组件,我们需要扩展 Hexo 的‌标签插件(Tag Plugin)‌ 系统。

现有标签插件语法为 {% tagName %},我们可以升级为 {% component %}:

njk
{% component "my-card", title="Hello", image="/img/card.jpg", link="/post/hello" %}

这个标签插件在编译时:

找到对应的组件渲染函数。 传入 props,执行渲染,得到 HTML。 将 HTML 替换到页面中。

对于更复杂的场景,支持‌插槽(slot)‌ 机制,让组件内部可以嵌套内容:

njk
{% component "layout-wrapper" %}
  {% slot "main" %}
    ## 这是文章内容
  {% endslot %}
{% endcomponent %}

这需要增强标签解析器,使其能识别嵌套标签并传递 slots 数据。

  1. 作用域隔离与样式管理

传统 Hexo 主题的样式是全局的,这在组件化中容易引起冲突。我们可以借鉴 ‌CSS Modules‌ 或 ‌BEM‌ 的思想,但更适合静态站点的方案是‌自动添加组件前缀‌。

在编译组件模板时,为每个 HTML 标签增加一个 data-component="my-card" 属性,同时将组件样式中的选择器自动转换为:

stylus
.my-card {
  // 预设样式
}
// 编译后:
[data-component="my-card"] .my-card {
  // 自动加前缀,避免污染
}

这可以通过一个 after_render:component 过滤器实现,对组件 CSS 进行 AST 转换。

  1. 数据驱动与响应式支持(编译时)

Hexo 是静态生成器,无法像 Vue 那样在浏览器端响应数据变化,但我们可以实现‌编译时的响应式‌——即组件数据来源于 _data 目录、配置文件或前端 matter,构建时一次性计算。

组件可以声明自己的数据源:

yaml
# 组件 config.yml
data:
  posts: site.posts    # 引用 Hexo 的站点变量

Hexo 在生成时会将 site 变量注入到组件渲染上下文中,实现类似 Vue 的 computed 效果,但完全在构建阶段完成。

如果需要客户端交互,组件可附带一个 script.js,该脚本在浏览器端通过 hexo.component.init() 自动挂载,实现简单的交互逻辑(如折叠、轮播)。这相当于一个‌轻量级的渐进式增强‌。

  1. 主题与插件集成

为了让生态顺利过渡,我们提供:

主题开发者‌:可以将 layout/ 中的部分结构重构为组件,提升可维护性。主题的 _components 目录会覆盖站点级组件,实现主题定制。 插件开发者‌:可以通过 hexo.extend.component.register 直接注册纯逻辑组件(无模板),例如生成友情链接、动态归档等。 用户‌:安装 hexo-component 官方插件,即可在现有博客中启用组件系统,无需改动主题。 7. 性能与兼容性保障 增量编译‌:组件有独立的缓存键(基于 props 和模板版本),Hexo 的 --watch 模式只会重新编译发生变化的组件,未改变的部分直接复用上次渲染结果。 向后兼容‌:不强制使用组件,传统 Markdown 页面和模板依然有效。组件系统作为可选增强,通过 hexo.config.components.enable: true 开启。 资源去重‌:多个页面使用同一组件时,其样式和脚本只会被注入一次,避免重复加载。

通过以上改造,Hexo 将从一个“页面级”的静态博客框架,进化为‌组件驱动的静态站点生成器‌,既保留 Markdown 的书写便利性,又获得现代前端框架的模块化开发体验。这正是 Hexo 在下一个大版本中需要迈出的关键一步。