支持引入 Hexo Component System
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)。
以下是技术实现路径和关键设计:
- 扩展核心概念:定义“组件”为一级资源
在 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),例如:
# config.yml
name: my-card
props:
title: string
image: string
link: string这样,组件就拥有了明确的输入约定,类似于 Vue 的 props。
- 注册与解析机制:利用 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 %}:
{% component "my-card", title="Hello", image="/img/card.jpg", link="/post/hello" %}这个标签插件在编译时:
找到对应的组件渲染函数。 传入 props,执行渲染,得到 HTML。 将 HTML 替换到页面中。
对于更复杂的场景,支持插槽(slot) 机制,让组件内部可以嵌套内容:
{% component "layout-wrapper" %}
{% slot "main" %}
## 这是文章内容
{% endslot %}
{% endcomponent %}这需要增强标签解析器,使其能识别嵌套标签并传递 slots 数据。
- 作用域隔离与样式管理
传统 Hexo 主题的样式是全局的,这在组件化中容易引起冲突。我们可以借鉴 CSS Modules 或 BEM 的思想,但更适合静态站点的方案是自动添加组件前缀。
在编译组件模板时,为每个 HTML 标签增加一个 data-component="my-card" 属性,同时将组件样式中的选择器自动转换为:
.my-card {
// 预设样式
}
// 编译后:
[data-component="my-card"] .my-card {
// 自动加前缀,避免污染
}这可以通过一个 after_render:component 过滤器实现,对组件 CSS 进行 AST 转换。
- 数据驱动与响应式支持(编译时)
Hexo 是静态生成器,无法像 Vue 那样在浏览器端响应数据变化,但我们可以实现编译时的响应式——即组件数据来源于 _data 目录、配置文件或前端 matter,构建时一次性计算。
组件可以声明自己的数据源:
# 组件 config.yml
data:
posts: site.posts # 引用 Hexo 的站点变量Hexo 在生成时会将 site 变量注入到组件渲染上下文中,实现类似 Vue 的 computed 效果,但完全在构建阶段完成。
如果需要客户端交互,组件可附带一个 script.js,该脚本在浏览器端通过 hexo.component.init() 自动挂载,实现简单的交互逻辑(如折叠、轮播)。这相当于一个轻量级的渐进式增强。
- 主题与插件集成
为了让生态顺利过渡,我们提供:
主题开发者:可以将 layout/ 中的部分结构重构为组件,提升可维护性。主题的 _components 目录会覆盖站点级组件,实现主题定制。 插件开发者:可以通过 hexo.extend.component.register 直接注册纯逻辑组件(无模板),例如生成友情链接、动态归档等。 用户:安装 hexo-component 官方插件,即可在现有博客中启用组件系统,无需改动主题。 7. 性能与兼容性保障 增量编译:组件有独立的缓存键(基于 props 和模板版本),Hexo 的 --watch 模式只会重新编译发生变化的组件,未改变的部分直接复用上次渲染结果。 向后兼容:不强制使用组件,传统 Markdown 页面和模板依然有效。组件系统作为可选增强,通过 hexo.config.components.enable: true 开启。 资源去重:多个页面使用同一组件时,其样式和脚本只会被注入一次,避免重复加载。
通过以上改造,Hexo 将从一个“页面级”的静态博客框架,进化为组件驱动的静态站点生成器,既保留 Markdown 的书写便利性,又获得现代前端框架的模块化开发体验。这正是 Hexo 在下一个大版本中需要迈出的关键一步。
Source: hexojs/hexo