开发指南

Hexo 插件开发的核心思路是:不修改核心源码,通过 Hexo 提供的扩展 API 注入自定义功能。下面是一份完整的开发指南。

插件的两种形式

形式 适用场景 位置
Scripts(脚本) 功能简单,无需发布 scripts/ 文件夹
Packages(包) 功能复杂,需发布到 NPM node_modules/hexo-xxx/

脚本方式最简单:把 .js 文件丢进博客根目录的 scripts/ 文件夹,Hexo 启动时自动加载。

Package

包(Package)插件的标准结构,文件夹名必须以 hexo- 开头,否则 Hexo 会忽略。

1
2
3
4
hexo-my-plugin/
├── index.js # 入口文件(必须)
├── package.json # 插件元信息(必须)
└── README.md # 文档(建议)

package.json 最小配置

1
2
3
4
5
6
7
8
{
"name": "hexo-my-plugin",
"version": "1.0.0",
"main": "index",
"description": "A Hexo plugin description",
"keywords": ["hexo", "plugin"],
"license": "MIT"
}

nameversionmain 三个字段缺一不可。

插件类型与 API

Hexo 初始化时会依次加载各类插件:

Console(控制台命令)

添加自定义 CLI 命令,如 hexo mycommand

1
2
3
4
5
6
7
8
9
// index.js
hexo.extend.console.register('hello', 'Say hello', {
usage: '[name]',
arguments: [
{ name: 'name', desc: 'Your name' }
]
}, function(args) {
console.log('Hello, ' + (args._[0] || 'World') + '!');
});

运行:hexo hello Kimi

Filter(过滤器)

在 Hexo 生命周期的特定阶段处理数据。

1
2
3
4
5
hexo.extend.filter.register('after_post_render', function(data) {
// 在文章渲染后修改内容
data.content = data.content.replace(/foo/g, 'bar');
return data;
});

常用钩子:

  • before_post_render / after_post_render — 文章渲染前后
  • after_render:html — HTML 渲染完成后
  • before_exit — 生成结束前

Generator(生成器)

生成自定义静态文件或页面。

1
2
3
4
5
6
7
hexo.extend.generator.register('my-page', function(locals) {
return {
path: 'custom-page/index.html',
data: '<h1>Hello from plugin</h1>',
layout: false // 不使用主题布局
};
});

Helper(辅助函数)

在模板中使用的函数。

1
2
3
hexo.extend.helper.register('custom_date', function(date) {
return new Date(date).toLocaleDateString('zh-CN');
});

模板中使用:<%= custom_date(post.date) %>

Tag(标签)

在 Markdown 中使用的自定义标签。

1
2
3
4
hexo.extend.tag.register('alert', function(args, content) {
const type = args[0] || 'info';
return `<div class="alert alert-${type}">${content}</div>`;
}, {ends: true});

Markdown 中使用:

1
2
3
{% alert warning %}
这是一个警告框
{% endalert %}

Processor(处理器)

处理源文件(source/ 目录下的文件)。

1
2
3
4
5
hexo.extend.processor.register('my-data/*.json', function(file) {
// file.source 是源文件路径
// file.path 是输出路径
// ...
});

Renderer(渲染器)

自定义文件格式的渲染,如把 .txt 渲染成 HTML。

1
2
3
hexo.extend.renderer.register('txt', 'html', function(data, options) {
return `<pre>${data.text}</pre>`;
});

Deployer(部署器)

自定义部署逻辑。

1
2
3
hexo.extend.deployer.register('my-deploy', function(args) {
// 实现部署逻辑
});

Injector(注入器)

向 HTML 的 <head><body> 注入内容。

1
2
3
hexo.extend.injector.register('head_end', function() {
return '<link rel="stylesheet" href="/my-style.css">';
});

本地测试方法

创建测试博客

1
2
3
mkdir hexo-test-blog && cd hexo-test-blog
hexo init
npm install

安装插件:直接复制

把插件文件夹复制到 Hexo 博客的 node_modules/ 下,并在博客的 package.jsondependencies 中添加:

"hexo-my-plugin": "^1.0.0"

每次修改插件代码后,务必执行 hexo clean,否则缓存可能导致修改不生效。

在插件里加日志,方便定位问题。用到函数:

hexo.log.debug();

然后,生成并检查输出

1
2
hexo clean
hexo generate --debug

发布到 NPM

1
2
3
4
5
# 1. 登录 npm
npm login

# 2. 发布
npm publish

更新时修改 package.json 中的 version 号,重新执行 npm publish

提交到 Hexo 官方插件列表

  1. Fork hexojs/site
  2. source/_data/plugins/ 下创建 hexo-my-plugin.yml
  3. 内容示例:
1
2
3
4
5
description: Add copyright footer to posts.
link: https://github.com/yourname/hexo-my-plugin
tags:
- copyright
- footer
  1. 提交 Pull Request

开发工具包

Hexo 官方提供了一些工具库,开发时可直接使用:

包名 用途
hexo-fs 文件读写操作
hexo-util URL 处理、HTML 转义、缓存等
hexo-i18n 多语言支持
hexo-pagination 分页数据生成

调试技巧

  1. 查看日志hexo.log.info() / hexo.log.warn() / hexo.log.error()
  2. 查看 Hexo 实例:在插件中 console.log(hexo) 了解可用 API
  3. 断点调试:在插件代码中加 debugger;,然后 node --inspect-brk $(which hexo) generate
  4. 查看生命周期:利用不同 Filter 钩子观察数据变化

背景

Typora 和 Hexo 路径解析机制的经典冲突。在 Typora 中为了正确预览 source/images/ 里的图片,相对路径必须带有 ../ 。但在 Hexo 编译时,默认不会处理这种越级目录,导致最终输出为 <img src="../images/文章1/图片1.png"> ,从而产生破图。

由于我==不希望改变 Typora 的书写习惯==,我们可以通过拦截渲染器( hexo-renderer-markdown-it )在编译期强行将 ../images/ 替换为 Hexo 支持的根目录相对路径 /images/ 。

详细说明与解决方案

我为你提供了一个直接在渲染器里拦截修改的方案,通过修改 node_modules/hexo-renderer-markdown-it/lib/images.js ,让 Hexo 在编译时自动兼容这种 Typora 路径。

  • 触发条件 :当 Markdown 里的图片路径以 相对路径 开头时,如 ./ 或 ../ 或 ./../ 等
  • 转换逻辑 :将其替换为 绝对路径 👉 /
  • Hexo 编译结果 :最终会被转换为 <img src="/images/文章1/图片1.png">

这样, 在 Typora 里因为有 ../ 可以正常预览,在 Hexo 里因为被转换为了绝对路径也可以正常显示,完美兼容。

图片路径写法?

这是文件路径里的相对路径写法:

符号 含义 举例
./ 当前目录(当前文件所在的文件夹) _post
../ 上级目录(当前文件夹的父文件夹) source
../../ 上两级目录 往上退两级

Typora/image/... 表示你电脑磁盘的根目录(如 C:/image/.../image/...

在文章开头的 YAML front matter 里加一行:

1
2
3
4
5
---
typora-root-url: ..
---

![图片描述](/image/文章1/图片1.png)

Typora 原生支持的字段(编辑/预览时生效)

字段 作用
typora-root-url 指定 根目录。指定以 / 开头的图片/链接在 Typora 预览时对应的本地磁盘根目录。例如 typora-root-url: ..,Typora 就会把 ![图](/image/1.png) 解析为当前文件上级目录下的 image/1.png

开发

发布

发布到 npm

这是让插件可以被 npm install 命令安装的基础。

  1. 准备工作:确保插件结构正确

    • 你的插件文件夹名必须为 hexo- 开头。
    • 文件夹内至少要包含 package.json 和入口文件(如 index.js)。
    • package.json 中必须包含 nameversionmain 这三个基本属性。
  2. 注册并登录 npm 账号

    • npm 官网 注册账号。

    • 在终端执行如下命令,Enter进入浏览器,输入用户名、密码和验证码(邮箱会收到验证码)。

      npm login
  3. 检查 npm 源

    • 确保指向官方 npm 仓库(而非淘宝镜像等国内源):

      npm config get registry
    • 如果不是 https://registry.npmjs.org/,则切换:

      npm config set registry https://registry.npmjs.org/

      操作完后记得切回来:发布成功后,为了在国内网络环境下获得更快的下载速度,建议把镜像源切换回淘宝源:

      npm config set registry https://registry.npmmirror.com
  4. 访问令牌

    • 访问 npmjs.com → 登录你的账号
    • 点击头像 → Access Tokens → Generate New Token
    • 填写 Token 名称(如 plugin-publish
    • Important:找到 Bypass 2FA 选项,务必勾选启用(这是关键!)
    • Packages and Scopes 部分:
      • Permissions:Read and write
      • Packages and scopes:All packages
    • 点击 Generate Token,复制保存(只显示一次)
  5. 发布插件

    • 在插件项目的根目录下,执行发布命令:

      npm publish --access public --//registry.npmjs.org/:_authToken=你的令牌
  6. 验证发布

  7. 版本更新

    • 每次更新插件后,需要修改 package.json 中的 version 字段,再执行 npm publish 发布新版本。

添加到 Hexo 插件列表

这一步能让插件出现在 Hexo 官网的插件页面,方便更多人发现和使用。这个过程通过向 Hexo 官网的仓库提交 Pull Request (PR) 来完成。

  1. Fork 官网仓库:在 GitHub 上 fork hexojs/site 仓库到你的账号下。

  2. 克隆仓库到本地

    1
    2
    3
    git clone https://github.com/<你的用户名>/site.git
    cd site
    npm install
  3. 添加你的插件信息

    • source/_data/plugins/ 目录下,创建一个新的 YAML 文件,文件名与你的插件名相同,例如 hexo-my-plugin.yml

    • 按照以下格式编辑该文件,填写你的插件信息:

      1
      2
      3
      4
      5
      description: 你的插件简短描述
      link: 你的插件GitHub仓库地址
      tags:
      - 标签1
      - 标签2

      tags 字段可以帮助用户快速找到你的插件,可参考官网其他插件的标签来填写。

    • 🌰文件名:hexo-typath.yml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      description: Convert any relative paths from Typora or local editors to absolute paths for Hexo. Supports Markdown and HTML img tags.
      link: https://github.com/Kkkika/hexo-typath
      tags:
      - typora
      - image
      - path
      - filter
      - asset
      - markdown
      - relative-path
  4. 提交 PR

    • 将改动提交到你 fork 的仓库分支,然后推送到 GitHub。
    • 在 GitHub 上向 hexojs/site 仓库的主分支发起一个 Pull Request (PR)。在 PR 中简单描述一下你的插件即可。

拓展学习

npm镜像源管理

如果经常需要在不同源之间切换,可以全局安装 nrm 这个管理工具:

npm install -g nrm

然后通过简单的命令切换源:

  • 切换到官方源:nrm use npm
  • 切换到淘宝源:nrm use taobao

prompt

  • 检查性能和安全问题
  • 优化性能和安全问题
  • 修复了哪些问题,还存在什么问题