怎样编写一个Saber插件

一直用的 Saber 博客系统没有全局的 tag 和 category 统计,issue 板上也有不少类似问题和讨论,但作者估计是出于什么考虑没有加入这个功能,所以我就来实现一下,做成一个 Saber 插件发布到 npm 上。

思路

API

Saber 这个框架下有两套 API,分为 Saber Browser APIs 和 Saber Node APIs。

  • Saber Browser APIs: 页面在浏览器运行时可调用的 api
  • Saber Node APIs:saber 在编译打包时可调用的 api,主要是调用 hooks。

从 api 设计上可以看出 saber 作者应该是参考了 Gastby 的部分设计

为了实现这个功能,需要在 saber 实例创建后遍历所有文章拿到全部的 tag 和 category 信息,因此需要在编译时调用 saber node api 中的 pages.createPage(page) 方法。

调用方法

那么具体怎么在插件中调用这个 hook 呢?这个方法在 Saber Instance - Saber#hooks 中有说明和示例代码:

The following lifecycle hooks are exposed by the api and can be accessed as such:

api.hooks.someHook.tap("MyPlugin", (...params) => {
  // Do something
});

插件长什么样

给 saber 写插件,需要知道一个插件哪些东西是必需的。这个部分在文档 Plugin API - SaberPlugin Interface 有说明,可以看到 name 和 apply 字段是必需的。

同时可以到 npm 上下一个 saber-plugin-seo 包参考一下。

exports.name = 'plugin-name';

exports.apply = (api, options = {}) => {
    ...
//  在 browserApi 中添加 saber-browser.js 中的配置
//  api.browserApi.add(path.join(__dirname, 'saber-browser.js'));

//  在 node api 中使用生命周期
    api.hooks.onCreatePages.tap(ID, () => {
        ...
    }
};

NPM 包开发过程

创建

首先创建一个 npm 模块,创建文件夹并 npm init

因为是开源的所以添加一个项目 license

这里使用 mit-license - npm 包来快速创建 MIT License,直接输入命令

$ npx mit-license --name 'Your Name'

开发的环境准备

创建了包之后要怎么引入项目中调试呢?因为此时不是官方包,直接 npm install 并不会识别。

这里 npm 提供了一个 link 命令,将自己开发的包链接到项目中去。

$ # 例:假设项目是 my-project, 需要用到一个独立的 my-utils 模块
$ cd path/to/my-project
$ npm link path/to/my-utils

如果这两种的目录不在一起,那还有一种方法:

$ # 先去到模块目录,把它 link 到全局
$ cd path/to/my-utils
$ npm link
$
$ # 再去项目目录通过包名来 link
$ cd path/to/my-project
$ npm link my-utils

windows 下可以看到 node_modules 中会创建一个开发包文件夹的快捷方式。

源码

到这里为止环境所需环境就全完成了。在开发文件夹下新建一个 index.js 入口文件,同时在 package.json 中加入 "main": "index.js" 字段,声明这个包的入口。然后将逻辑代码写到 index.js 中即完成了。

我写好的包源码在这里供参考:

发布

发布前要先注册一个 npm 账号并通过邮箱验证。

然后进入项目文件夹执行命令 npm publish 注意这里如果发布失败了,可能是 package.json 中 name 字段与登录名不符,需要改为一致。因为 npm 会验证这个包是不是本人在发布。

如果有修改或删除,命令为 npm unpublish

参考链接:

如何开发 npm 插件 - 简书

你所不知道的模块调试技巧 - npm link · Issue #17 · atian25/blog

【译】发布你自己的 npm 包

这是一个 npm package template. flexdinesh/npm-module-boilerplate

Node.js 模块风格指南

单元测试 - 为企业级框架和应用而生