# 开发插件

开发插件前,请发邮件至 qq-miniprogram@tencent.com 申请插件开发权限,邮件内容包括:

【标题】QQ小程序插件开发申请
【内容】
插件名称:
Appid:
插件用途:
1
2
3
4
5

# 创建插件项目

开发小程序插件需要一个appid,申请步骤同小程序一致,添加项目的步骤也与小程序一致。

小程序插件目录一般包括以下三个:

  • miniprogram 目录: 放置一个小程序项目,用于调试插件

  • plugin 目录: 插件源码

  • doc 目录: 用于放置插件开发文档

miniprogram 目录内容可以当成普通小程序来编写,用于小程序插件调试和预览。

# 插件目录结构

一个插件可以包含若干个自定义组件、页面,和一组 js 接口。插件的目录内容如下:

plugin
├── components
│   ├── hello-component.js   // 插件提供的自定义组件(可以有多个)
│   ├── hello-component.json
│   ├── hello-component.wxml
│   └── hello-component.wxss
├── pages
│   ├── hello-page.js        // 插件提供的页面(可以有多个)
│   ├── hello-page.json
│   ├── hello-page.wxml
│   └── hello-page.wxss
├── index.js                 // 插件的 js 接口
└── plugin.json              // 插件配置文件
插件配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 插件配置文件

向第三方小程序开放的所有自定义组件、页面和 js 接口都必须在插件配置文件 plugin.json 列出,格式如下:

{
  "publicComponents": {
    "hello-component": "components/hello-component"
  },
  "pages": {
    "hello-page": "pages/hello-page"
  },
  "main": "index.js"
}
1
2
3
4
5
6
7
8
9

这个配置文件将向第三方小程序开放一个自定义组件 hello-component,一个页面 hello-pageindex.js 下导出的所有 js 接口。

# 进行插件开发

请注意:在插件开发中,只有部分接口可以直接调用。

# 自定义组件

插件可以定义若干个自定义组件,这些自定义组件都可以在插件内相互引用。但提供给第三方小程序使用的自定义组件必须在配置文件的 publicComponents 段中列出(参考上文)。

除去接口限制以外,自定义组件的编写和组织方式与一般的自定义组件相同,每个自定义组件由 wxml, wxss, js 和 json 四个文件组成。具体可以参考自定义组件的文档。

# 页面

插件可以定义若干个插件页面,可以从本插件的自定义组件、其他页面中跳转,或从第三方小程序中跳转。所有页面必须在配置文件的 pages 段中列出(参考上文)。

除去接口限制以外,插件的页面编写和组织方式与一般的页面相同,每个页面由 wxml, wxss, jsjson 四个文件组成。具体可以参考其他关于页面的文档。

插件执行页面跳转的时候,可以使用 navigator 组件。当插件跳转到自身页面时, url 应设置为这样的形式:plugin-private://PLUGIN_APPID/PATH/TO/PAGE。需要跳转到其他插件时,也可以这样设置 url

<navigator url="plugin-private://qqidxxxxxxxxxxxxxx/pages/hello-page">
  Go to pages/hello-page!
</navigator>
1
2
3

在插件自身的页面中,插件还可以调用 qq.navigateTo 来进行页面跳转, url 格式与使用 navigator 组件时相仿。

# 接口

插件可以在接口文件(在配置文件中指定,详情见上文)中 export 一些 js 接口,供插件的使用者调用,如:

module.exports = {
  hello: function() {
    console.log('Hello plugin!')
  }
}
1
2
3
4
5

# 预览、上传和发布

插件可以像小程序一样预览和上传,但插件没有体验版。

插件会同时有多个线上版本,由使用插件的小程序决定具体使用的版本号。

手机预览和提审插件时,会使用一个特殊的小程序来套用项目中 miniprogram 文件夹下的小程序,从而预览插件。

# 插件开发文档

在第三方小程序使用插件时,插件代码并不可见。因此,除了插件代码,我们还支持插件开发者上传一份插件开发文档。这份开发文档将展示在插件详情页,供其他开发者在浏览插件和使用插件时进行阅读和参考。插件开发者应在插件开发文档中对插件提供的自定义组件、页面、接口等进行必要的描述和解释,方便第三方小程序正确使用插件。

插件开发文档必须放置在插件项目根目录中的 doc 目录下,目录结构如下

doc
├── README.md   // 插件文档,应为 markdown 格式
1
2

编辑 README.md 之后,可以使用开发者工具打开 README.md,并在编辑器的右下角预览插件文档和单独上传插件文档。上传文档后,立刻发布。

# 其他注意事项

# 插件间互相调用

插件不能直接引用其他插件。但如果小程序引用了多个插件,插件之间是可以互相调用的。

一个插件调用另一个插件的方法,与插件调用自身的方法类似。可以使用 plugin-private://APPID 访问插件的自定义组件、页面(暂不能使用 plugin:// )。对于 js 接口,可使用 requirePlugin

# 插件请求签名

插件在使用 qq.requestAPI 发送网络请求时,将会额外携带一个签名 HostSign ,用于验证请求来源于小程序插件。这个签名位于请求头中,形如:

X-WECHAT-HOSTSIGN: {"noncestr":"NONCESTR", "timestamp":"TIMESTAMP", "signature":"SIGNATURE"}

其中,NONCESTR 是一个随机字符串,TIMESTAMP 是生成这个随机字符串和 SIGNATUREUNIX 时间戳。它们是用于计算签名 SIGNATRUE 的参数,签名算法为:

SIGNATURE = sha1([APPID, NONCESTR, TIMESTAMP, TOKEN].sort().join(''))

其中,APPID 是 所在小程序 的 AppId(可以从请求头的 referrer 中获得);TOKEN 是插件 Token,可以在小程序插件基本设置中找到。

网络请求的 referer 格式固定为 https://appservice.qq.com/{appid}/{version}/page-frame.html,其中 {appid} 为小程序的 appid,{version} 为小程序的版本号,版本号为 0 表示为开发版、体验版以及审核版本,版本号为 devtools 表示为开发者工具,其余为正式版本。

插件开发者可以在服务器上按以下步骤校验签名:

  1. sortAPPID NONCESTR TIMESTAMP TOKEN 四个值表示成字符串形式,按照字典序排序(同 JavaScript 数组的 sort 方法);

2.join 将排好序的四个字符串直接连接在一起;

3.对连接结果使用 sha1 算法,其结果即 SIGNATURE

在小程序运行期间,若网络状况正常, NONCESTRTIMESTAMP 会每 10 分钟变更一次。如有必要,可以通过判断 TIMESTAMP 来确定当前签名是否依旧有效。