Hexo 插件开发
眼馋 The Verge 的图片轮播功能,在有序图集中轮播比组图要好用,但是 Hexo 并没有相关插件,于是照猫画虎自己用 Splide 摸了一个适用于 NexT 主题的图片轮播插件,顺便记录下插件从开发到发布的全过程。
版本说明:
- Hexo:7.3.0
- npm:10.8.2
创建
- 首先创建一个文件夹来存放插件文件。
- 文件夹名称必须以
hexo-
开头,如hexo-splide-carousel
,否则Hexo不会识别这个插件。 - 文件夹不必放在博客目录中。
- 建议搭配
git
使用,比如在GitHub中新建一个同名仓库并克隆到本地。
- 文件夹名称必须以
- 在终端中执行
npm init
命令来初始化项目,跟随引导完成package.json
的创建,package.json
用于记录插件的名称、版本、依赖等信息,没想好或者不明白的选项保持默认即可,后续可以修改。- 有关
package.json
中各项的作用,详见官方文档 package.json。- 示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25{
"name": "hexo-splide-carousel",
"version": "1.2.1",
"description": "A package for Hexo blogs using the Next theme, provides image carousel and zoom functionality using Splide and medium-zoom libraries.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"hexo",
"theme-next",
"plugin",
"splide",
"carousel",
"medium-zoom"
],
"author": "Siriusq",
"homepage": "https://github.com/Siriusq/hexo-splide-carousel",
"bugs": "https://github.com/Siriusq/hexo-splide-carousel/issues",
"repository": {
"type": "git",
"url": "git://github.com:Siriusq/hexo-splide-carousel.git"
},
"license": "MIT"
}
- 示例:
- 懒得在这里一项一项填写的话就直接输入
npm init -y
,这个命令会直接生成一个默认的package.json
。
- 有关
- 初始化完毕后,文件夹中会出现
index.js
与package.json
两个文件,index.js
是插件的入口文件。
开发
这部分内容比较长,是我的插件中相关文件的说明,仅供参考,毕竟我也是第一次开发Hexo的插件,难免出现纰漏。
在开发前建议完整阅读官方文档。
我的插件属于标签类的,Hexo在生成静态文件的过程中,如果检测到markdown文件中存在相应的标签(如 {% splide %}
),就会将标签及其中的内容转换为我们指定的html结构。
如果你的插件类型不同,可以到下面的网站寻找类似插件,照猫画虎。
文件结构
我的插件结构如下,并不是很规范,比如splide-init.js我就不知道应该放在哪里,因为我也没找到相关的规范,就仿照了其他看起来文件结构比较规范的插件。
1 | hexo-splide-carousel |
index.js
前面已经说过,这个文件是插件的入口文件,也就是主文件,它在我插件中的功能为:
- 注册标签
- 引入模块
- 向页面中注入js脚本及css样式
注册标签
标签插件可以帮助开发者在文章中快速插入内容。相关文档:标签插件(Tag)。
我为插件注册了两个标签:splide
和sc
。
1 | // 注册 Hexo 自定义标签及其简写 |
const splideTag = require('./lib/scripts/tags/splide-tag')(hexo);
。require('./lib/scripts/tags/splide-tag')
:这里我将标签函数作为模块单独引入,方便后期修改,模块的路径为./lib/scripts/tags/splide-tag.js
。(hexo)
:如果你的标签函数中调用了hexo的配置文件等,就需要传递hexo实例到函数中。
hexo.extend.tag.register
用于标签注册。- 第一个参数为标签名称,也就是在markdown文件中使用的标签。
- 第二个参数为标签函数,因为我把它作为模块引入了,所以这里很简洁。
- 如果你的标签函数比较简单,也可以直接填入函数
function (args, content) { // ... },
。
- 如果你的标签函数比较简单,也可以直接填入函数
- 第三个参数是标签选项,Hexo共提供了两个选项,ends和async,两者默认都是false状态。
{ ends: true },
表示使用结束标签。反映在md文件中,就是使用end标签名称
来表示标签结束。
加载文件
首先加载Hexo提供的文件IO模块,详细用法请查看hexo-fs。
1 | const fs = require('fs'); |
然后通过fs模块加载其他文件
1 | // 加载 lib 中的文件 |
自定义配置
我在插件中开放了一些自定义功能,比如选择依赖使用的CDN供应商,调整组件的样式等,为了让用户更方便的进行调整,就需要在Hexo的配置文件中添加这些配置选项。
需要注意_config.yml
中使用的缩进均为两个空格。
下面以自定义CDN为例:
1 | # _config.yml |
然后就可以在index.js中读取配置。
1 | const cdn = hexo.config.splide.cdn || 'unpkg'; |
为了防止用户将选项留空,建议设置一个默认选项,|| 'unpkg'
就表示如果配置文件中未指定CDN,则使用默认CDN供应商unpkg。
注入器
注入器被用于将静态代码片段注入生成的 HTML 的 <head>
及 <body>
中。 Hexo 将在 after_render:html
过滤器之前完成注入。相关文档:注入器(Injector)
前面我们只是读取了js与css文件,但是它们的代码需要被注入到生成的 HTML 中才能生效。以注入自定义样式为例:
1 | // 前面引入的css样式 |
- 第一个参数是注入代码的位置。
head_begin
: 注入在<head>
之后(默认)head_end
: 注入在</head>
之前body_begin
: 注入在<body>
之后body_end
: 注入在</body>
之前
- 第二个参数是需要注入的代码片段。
- 第三个参数是注入代码的页面范围。
default
: 注入到每个页面(默认值)home
: 只注入到主页post
: 只注入到文章页面page
: 只注入到独立页面archive
: 只注入到归档页面category
: 只注入到分类页面tag
: 只注入到标签页面
splide-tag.js
./lib/scripts/tags/splide-tag.js
就是前面作为模块引入的标签函数,文件如下:
1 | // 生成html结构 |
标签函数会传入两个参数:args
和 content
。在md文件中,我的标签结构为:
1 | {% splide type:'loop' autoplay:true %} |
args
包含传入标签插件的参数,即上面的type:'loop' autoplay:true
。content
是标签插件所覆盖的内容,即![alt](url)
。
其他文件
splide-init.js
的作用为监听页面事件,并判断是否初始化轮播组件。splide-custom.css
会应用我自定义的样式,覆盖部分Splide的默认样式。
本地测试
在开发过程中我们需要频繁的进行测试,来确保插件正常工作。
- 首先在博客项目中安装我们的插件,安装方法有多种,包括但不限于:
- (推荐)在博客根目录执行命令
npm install 插件的路径
来安装我们的插件,这个命令相当于创建了一个链接,我们在插件项目的文件夹中对文件做出的改动会实时同步到博客根目录/node_modules/插件名
中。 - 如果你不打算上传插件的话,也可以直接将插件文件夹移动到
./node_modules
路径下,然后手动在博客根目录下的./package.json
中的dependencies
下添加我们的插件及其版本,如"hexo-splide-carousel": "^1.0.0",
。如果是最后一行,记得在前一行末尾添加逗号并删除自身的逗号。
- (推荐)在博客根目录执行命令
- 如果你的插件有自定义配置项,记得在Hexo的配置文件
_config.yml
中添加这些配置项。 - 然后就是老一套的
hexo cl
和hexo s
测试了。
发布
在插件制作完成后,我们可以选择将它上传到npm,这样其他人也可以安装使用我们制作的插件。
- 创建
README
文件,介绍插件的作用以及使用方法,更多内容详见官方文档 About package README files。 - 如果有需要忽略的文件,可以创建
.npmignore
文件,写法与.gitignore
类似,一些常见文件如.git
文件夹以及README
文件是默认忽略的,不需要添加到.npmignore
文件中。详见官方文档 Keeping files out of your Package。 - 完善
package.json
。 - 到npm官网注册一个账号。
- 在插件目录执行
npm login
,然后回车跳转到浏览器中登录账号。 - 执行
npm publish
,然后回车跳转到浏览器中验证身份。 - 在npm首页搜索自己的插件名就可以找到刚刚发布的插件了。
更新
如果在插件中发现了新的Bug或者添加了新的功能,就需要将更新后的插件再次推送到npm。
- 执行
npm version 版本号
。- 初始化后的默认版本号是
1.0.0
。 - 如果更新内容主要是Bug修复,那么只需要增加最后一位数字,如
1.0.1
。 - 如果添加了向后兼容的新功能,则改动中间的数字,如
1.1.0
。 - 如果改动非常大,添加了不能向后兼容的新功能,则改动第一位数字,如
2.0.0
。 - 有关版本号的详细规则,请查看官方文档 About semantic versioning。
- 初始化后的默认版本号是
- 执行
npm publish
,然后回车跳转到浏览器中验证身份,然后等待终端中的命令执行完成。
Hexo收录
插件发布后,我们还可以将插件推送到Hexo官方的插件列表中,方便更多人查找使用。
- Fork 一份 hexojs/site 到自己的仓库。
- 将 fork 后的仓库 clone 到本地。
- 在
./source/_data/plugins/
中新建一个yaml
文件,文件名同你的插件名。 - 在新建的文件中使用英语填写相关内容,示例如下:
1
2
3
4
5
6description: Server module for Hexo.
link: https://github.com/hexojs/hexo-server
tags:
- official
- server
- console - 将做出的更改推送到自己的仓库。
- 开启新的 pull request。
- 在 title 中描述做出的修改,如
Plugin: add plugin hexo-splide-carousel
。 - 勾选
Check List
中的相关选项。 - 提交后等待 Hexo 完成相关检查即可。
- 最后你的插件就会出现在Hexo官网的插件列表中。
参考及引用