公司要把一套业务能力打包给合作方的小程序用,第一反应是发个 npm 包,结果发现小程序这边根本不是这个玩法,代码不能给对方看,得走插件。真开始做才知道坑不少,个人号开不了,类目不对提交不了,插件里连 wx.login 都调不了。
这篇把从申请到发布走一遍的完整流程记下来,包括插件项目长什么样、使用方怎么引、插件里哪些 API 用不了、以及绕过限制的功能页机制。如果你正在评估「这个需求能不能做成插件」,看完这篇应该能给出判断。
在本篇文章中,我们将从浅入深,和大家一起学习以下知识:
- 插件是什么,跟自定义组件和 npm 包的区别在哪
- 开放范围和服务类目,哪些账号根本申请不了
- 插件项目的目录结构,
plugin、miniprogram、doc各管什么 - 预览、上传、发布的流程,以及开发版插件怎么在真实小程序里调试
- 使用方引入插件的两种方式,主包和分包各有什么限制
- 插件和使用方之间怎么互相传东西,
export和抽象节点 - 插件里不能用的那批 API 和组件,完整清单
- 功能页机制,登录、支付、收货地址这三件事怎么绕
# 一、插件到底是什么
先把定位说清楚。插件是对一组 js 接口、自定义组件或页面的封装,用于嵌入到别人的小程序里。它不能独立运行,必须嵌在宿主小程序中才能被用户使用。开发和使用插件需要小程序基础库版本 1.9.6 以上。
它跟自定义组件最大的区别是代码可见性。第三方小程序在使用插件时看不到插件的代码,所以插件适合把自己的功能或服务打包给别人用,同时又不把实现暴露出去。这也是我们当初选它的唯一理由,业务逻辑不想开源给合作方。
代价是限制。插件里一些 API 无法调用,一些组件不能用。还有几个特殊接口虽然不能直接调,但可以通过功能页间接实现,这块第五节专门讲。另外框架会对小程序和它用的每个插件做数据安全保护,双方都不能偷看对方的数据,除非数据被主动传过去。
拿几个真实场景理解会更快。查快递、查天气这种通用服务,做成插件比每家自己写一遍划算。打车场景可以直接嵌滴滴提供的组件。外卖是最典型的,每个餐厅想要的小程序风格都不一样,但外卖这块功能是通用的,那就给餐厅各定制一个小程序,外卖部分直接用美团的插件。
这里有个当时让我很意外的发现:插件里居然不能直接调微信支付。做交易类插件之前一定要先确认这一点,绕法在第五节。
能做的事很多,但插件限制了开放范围和服务类目,具体清单看官方的开放类目说明。
开放范围只给企业、媒体、政府及其他组织主体,个人号不行。这条建议放在所有技术评估前面,账号主体不对,后面写得再好也发不出去。
服务类目上,开发者只能从当前小程序账号已选类目里挑一个作为插件的服务类目。下面是当时已开放的类目,官方说会逐步开放更多。
| 一级类目 | 二级类目 | 特殊说明 |
|---|---|---|
| 快递业与邮政 | 所有二级类目 | |
| 医疗 | 就医服务、互联网医院 | 仅医疗类小程序可使用 |
| 政务民生 | 所有二级类目 | |
| 金融业 | 征信业务 | |
| 出行与交通 | 所有二级类目 | |
| 生活服务 | 票务、生活缴费 | |
| IT科技 | 所有二级类目 | |
| 餐饮 | 点评与推荐、菜谱、餐厅排队、点餐平台、外卖平台 | |
| 旅游 | 所有二级类目 | |
| 文娱 | 视频、FM/电台、音乐、有声读物、动漫 | |
| 工具 | 记账、投票、日历、天气、备忘录、办公、字典、计算类、报价/比价、发票查询、企业管理 | |
| 电商平台 | 电商平台 | |
| 商业服务 | 招聘/求职 | |
| 汽车 | 所有二级类目 |
# 1.1 开发一个插件要走哪几步
整个流程是固定的四步,卡点也都在这四步里。
Step 1,去 小程序管理后台 的 小程序插件 里找开通入口。
Step 2,开通插件功能。条件前面说过,必须是企业、媒体、政府及其他组织主体,个人小程序不行。还有一条容易被忽略,一个小程序只能开通一个插件,想做两个不同的插件就得准备两个小程序账号。
Step 3,填写开发信息并开发。这里有个不可逆的操作,插件的基本信息和头像一旦填写就不能修改,动手前先跟产品和设计确认好文案与图,别像我一样填完才发现名字不对。
Step 4,提交审核、发布。只有在开发类目内才能提交。另外有个跟文档不符的地方,官方文档说「插件发布后才可以被其他小程序搜索并添加」,但当时实测没发布的也能被搜到和添加。这条对调试期是好事,对保密是坏事,插件名字别起得太敏感。
# 二、创建插件项目
用小程序的 AppID 就能创建插件项目。插件独立于小程序之外,但 AppID 是公用的,所以有一条铁律:不要在原有的小程序项目里做插件开发。两者的编译方式不一样,混在一起会互相干扰。
在开发者工具的创建项目页面,选一个空文件夹作为项目路径,勾上创建小程序插件快速启动模板。没有插件 AppID 的话要先去申请一个,专门用来开发插件。

模板建出来是三个目录加一份配置,各管各的事。
plugin 目录是插件本体,你的代码都写在这里。
miniprogram 目录放的是一个普通小程序项目,用来调试插件,同时它也是插件使用 Demo。上传插件代码时这个 Demo 会一起上传,并作为发布的审核依据。所以别把它当草稿箱,审核员是照着它看你的插件能干什么的,Demo 写得潦草是会被驳回的。
project.config.json 里要关注 compileType 字段,只有 compileType 等于 plugin 时才能正常使用插件项目。这个字段错了的表现是编译出来的东西完全不对,找半天找不到原因。
doc 目录放插件文档,而且必须放在插件项目根目录下的 doc 里。入口文件是 doc/README.md,里面引用的图片不能是网络图片,必须放在这个目录下面。
文档里的链接也有白名单,只能链到这三个域名:
- 微信开发者社区(developers.weixin.qq.com)
- 微信公众平台(mp.weixin.qq.com)
- GitHub(github.com)
写完 README.md 之后,在开发者工具左侧资源管理器里右键点它,选上传文档。要注意上传不等于发布,传完还得用账号密码登录管理后台,在 小程序插件 > 基本设置 里预览、发布插件文档。
还有个大小限制,插件文档总大小不能大于 2M,超了上传会返回错误码 80051。图多的话记得先压一遍,这个错误码提示不明显,第一次遇到很容易以为是网络问题。

# 2.1 插件目录结构
一个插件可以包含若干个自定义组件、页面,和一组 js 接口。这三样正好对应插件对外提供能力的三种方式,需要 UI 的给组件,需要整页跳转的给页面,纯逻辑的给 js 接口。目录长这样:
plugin
├── components
│ ├── hello-component.js // 插件提供的自定义组件文件夹, 中自定义组件可以有多个
│ ├── hello-component.json
│ ├── hello-component.wxml
│ └── hello-component.wxss
├── pages
│ ├── hello-page.js // 插件提供的页面(可以有多个,自小程序基础库版本 2.1.0 开始支持)
│ ├── hello-page.json
│ ├── hello-page.wxml
│ └── hello-page.wxss
├── index.js // 插件入口文件,可以在这里 export 一些 js 接口,供插件使用者使用
└── plugin.json // 插件的配置文件,主要说明有哪些自定义组件可以供插件外部调用,并标识哪个js文件是插件的js接口文件,默认的配置形式如下:
{
"publicComponents": {
"list": "components/list/list"
},
"main": "index.js"
}
这棵树里 plugin.json 是最关键的一份文件,它决定了插件对外露出哪些东西。没写进去的组件和页面,使用方是引不到的,哪怕文件就躺在目录里。
# 2.2 插件配置文件
提供给使用者小程序的自定义组件必须在 publicComponents 段里列出,这是插件的对外门面:
{
"publicComponents": {
"hello-component": "components/hello-component"
},
"pages": {
"hello-page": "pages/hello-page"
},
"main": "index.js"
}
这份配置向使用者小程序开放了一个自定义组件 hello-component、一个页面 hello-page,以及 index.js 下导出的所有 js 接口。
把它理解成 npm 包的 exports 字段会比较容易接受。没列出来的属于内部实现,你可以随便改;列出来的就是公开 API,改了会破坏所有使用方,所以哪些组件对外开放这件事一开始就要想清楚。
# 2.3 预览、上传和发布
插件可以像小程序一样预览和上传,但它没有体验版。这一点跟小程序开发习惯差别很大,想给产品经理发个二维码扫一扫是做不到的。
插件会同时存在多个线上版本,具体用哪个版本由使用插件的小程序自己决定。这套设计对插件方友好,发新版不会强制所有使用方跟着升。反过来说,老版本你也得继续维护,不能说改就改。
手机预览和提审插件时,微信会用一个特殊的小程序来套用你项目里 miniprogram 文件夹下的那个 Demo,从而把插件跑起来。这也是前面说 Demo 要认真写的原因。
在真实小程序里调试开发版插件
平时把 miniprogram 下的代码当成使用方来调试就够了。但有时候你需要把插件放在真实运行的业务小程序里测,比如要验证和宿主的数据交互。这时候可以让开发版小程序直接引用开发版插件:
Step 1,在开发者工具的插件项目里上传插件,上传成功的通知信息里会带上这次上传得到的插件开发版 ID,是一串英文数字组成的随机字符串。
Step 2,点开发者工具右下角的通知按钮打开通知栏,就能看到新生成的 ID。
Step 3,在要使用开发版插件的小程序项目里,把插件 version 写成 dev- 加上那个 ID,比如 "version": "dev-abcdef0123456789abcdef0123456789"。
有个硬约束要记牢,开发版小程序引用了开发版插件之后,这个小程序就不能上传发布了。必须把插件版本改回正式版本号,小程序才能正常上传。发版前忘了改这一行,你会在发布环节卡住。
关于开发版 ID 还有几条容易踩的规则:
- 每次上传插件生成的 ID 不一定相同,同一个插件、同一个开发者,多次上传也可能变
- 每个开发者在每个插件里只会同时存在一个有效的开发版,只有最新上传的那个 ID 有效,用旧的会提示失效
- 不同开发者上传的开发版互不影响,可以同时有效,多人协作时各调各的不会打架
- 开发版插件没有时间限制,长期有效
第一条和第二条合起来看,意味着你每改一次插件重新上传,宿主小程序里那行 version 就得跟着换。团队里把这个 ID 写死在公共配置里是很痛苦的,建议放到本地不提交的配置项里。
# 三、使用插件
换个身份,现在你是要用别人插件的那一方。这一节讲怎么把插件接进来。
# 3.1 先在后台添加插件
在写任何代码之前,得先去小程序管理后台的「设置 - 第三方服务 - 插件管理」里添加插件,通过 appid 查找并添加。如果这个插件无需申请,添加完就能直接用;否则要提交申请,等插件开发者通过之后才能在小程序里使用。

需要申请的插件,等待时间完全取决于对方,排期时最好把这段留出来。我们当时因为对面审批慢,白白空了两天。
# 3.2 在 app.json 里声明
后台加完之后,使用者要在 app.json 中声明需要使用的插件。放在主包里是这样:
{
"plugins": {
"myPlugin": {
"version": "1.0.0",
"provider": "wxidxxxxxxxxxxxxxxxx"
}
}
}