hexo是如何工作的
前言
官方文档自己的博客运行了也有一段时间了,想了解一下自己的博客站点整体是如何工作的?以及自己可以做点什么,来往这个博客站点中植入自己的插件来满足自定义的需求!
本文将具体分析一下hexo是如何工作的?它都有哪些组成?我们可以在这个框架上如何自定义自己的需求?以及这个框架给我们代码的可学习的地方!!!
hexo的组成
首先,不管怎么,代码到手,天下我有! 👉 先来看一下对应的
hexo的代码目录结构:
👾 通过package.json中的main,可以发现其中的入口在于bin/hexo文件
1 |
|
👾 而hexo则是调用的hexo-cli库来实现的,后面发现,hexo-cli则是反过来调用的hexo来进行 👉 创建一个Hexo对象,并最终调用这个Hexo对象的init()方法 !!
🌠 也就是说这个hexo-cli充当了一个执行者的作用!!
👽 而这里的Hexo对象,则是继承于EventEmitter对象,可针对其过程进行一系列的监听(也就是监听其生命周期过程方法)!
1. extend扩展(以console.clean为例)

⭐ 从上面可以看出,Hexo通过其extend对象中的各个属性,对外提供的可随意针对不同阶段进行扩展自定义业务的机制,也就是我们可以编写自己的插件来交付给hexo,让他来帮执行我们的需求!!
👉 这里我们仅分析一个插件,他是如何来编写以及如何被植入到扩展中的(以console为例)!!
😕 这里的console.register()方法,他做的一个怎样的动作的呢??来看一下对应的register()函数:
👇 是对应的简写版的register()函数内容:
1 | // this.store = {}; |
这里的register()方法对外提供了一个方法,用于将外部插件fn以及对应的描述和参数通过abbrev生成关键词参数,存储在store对象中,以便于后续Hexo拿来使用!
🌠 这里的abbrev三方库:可将一系列字符串参数转换为每个单词依次追加的对象,主要用于命令行的命令声明使用,如下图说明所示:
🌠 而于此同时,我们所传递进来的fn它可以是一个函数数组,也可以是一个普通的函数,如果传递的函数数组则表示我们将在这个命令上计划执行N个按照数组顺序排列执行的函数,每一个函数都是一个个待被执行的promise
👇 是对应的clean.js的程序内容!
1 | function cleanConsole(args) { |
🌠 针对上述的代码进行一个简单的分析,通过对外暴露一个方法函数,该函数接受一个args参数,执行3个动作:
- 删除Database数据库;
- 删除public目录;
- 触发过滤器
after_clean,并传递当前的上下文对象
这里有一需要 ⚠ 的地方,在插件中直接调用的this.execFilter方法,😕 那么这里的this指向的是谁呢?

2. warehouse本地json数据库
官方文档具有模型、模式和灵活查询接口的
JSON数据库,可以理解为是一个JSON文件,然后可通过其API来对其进行增删改查操作!
🌠 先来看一下这个warehouse的一般用法:
👾 与一般的db操作类似,创建db的引用(类似于连接),然后关联对应的数据表Schema,然后就可针对不同的数据表Schema进行增删查改操作,然后需要将操作缓存到json数据库中(这个save动作必须要执行,否则对应的json文件将没有任何的用处)!
😕 那么这个warehouse数据库的结构组成是怎样的呢?我们可以先看一下 👇 在内存中的数据库的内容形式:
🌠 结合实际的源码,我们可以得出 👇 的一个warehouse的组成结构图:
warehouse所支持的数据表字段类型SchemaType有:
| 数据表字段 | 描述 |
|---|---|
| array | 数组类型 |
| boolean | 布尔值类型 |
| buffer | 文件缓存类型 |
| cuid | 随机id类型 |
| date | 日期 |
| integer | 整型类型 |
| number | 数值类型 |
| object | 对象类型 |
⭐ 那么我们在定义数据表的时候, 😕 假如需要将对应表的字段给声明出来,不同的表对应用不同的Schema来表示,那么假如我们需要定义不同类型的字段,应该如何来声明呢?
1 | db.model('customs2', new Schema({ |

👽 在实际的coding过程中,我们还可以将Model的创建与数据的管理给分离开来:
hexo中是如何来运用这个warehouse的呢?
☝ 这里其实与我们平时使用类似,都是面向接口编程,统一操作database,由database自行去维护好与model之间的一个关联关系!
3. render渲染引擎(hexo server)
当我们执行的
hexo server命令的时候,从 ☝ 的学习可以得知,最终会执行到Hexo.call()方法,该方法主要负责从console已注册的扩展动作中取出函数来执行!,如下代码所示:
1 | call(name, args, callback) { |
😖 这里我们并没有在Console中找到关于hexo server对应的函数实现是怎样的,实际上这也是hexo实现插件化编程的灵活之处,将对于这个命令的实现,交由hexo-server另外一个库来实现!!!
hexo-server的实现过程

一切在
hexo中运行的插件,都可以直接访问到hexo上下文对象
由于可以直接访问到hexo上下文对象,因此可以直接针对hexo.extend来进行额外动作的补充
1 | hexo.extend.console.register('server', 'Start the server.', { |
因此,执行的hexo server其实就是调用的lib/server方法!
👉 而这里的动作无非也就是监听html相关文件的生成,并借助于connect + serve-static来监听运行在端口上的静态网站站点!!
能够做点什么
在学习完成了
hexo的相关知识点后,发现有不少可值得学习的地方:
1. 针对扩展新增自定义插件(新增的插件都是不能访问浏览器资源的)
2. 优化现有的站点
学到的东西
1. 模仿nodejs实现自定义的函数包裹,并从中获取额外的上下文对象

2. 对外暴露extend对象代表不同阶段的扩展,实现插件编程范式
3. 本地简易数据库warehouse-json编程
可以将当下的后台一些无须复杂数据库方能实现的逻辑,交由
warehouse来实现!!