记一次微信小程序分包经历

需求背景

这天,主管找到我:"有个微信小程序的验证码接口被恶意调用,一天刷了几百条,你看能不能加一个验证码限制一下"。我一听,终于来活了,直接开搞。

需求分析

公司一直有订阅阿里云验证码2.0服务,看文档微信小程序刚好能用,就直接用它,先登录验证码2.0控制台新建验证场景、填写配置,然后登录微信小程序后台添加插件,等申请通过就能用了。

开始接入

app.json中声明插件

json 复制代码
"plugins": {
      "AliyunCaptcha": {
      "version": "2.1.1",
      "provider": "wxbe275ff84246f1a4"
    }
}

引入验证码小程序组件

json 复制代码
{
  "usingComponents": {
    "aliyun-captcha": "plugin://AliyunCaptcha/captcha"
  }
}

模板插入

html 复制代码
<aliyun-captcha id="captcha-element" wx:if="{{loadCaptcha}}" props="{{pluginProps}}" />

插件初始化

js 复制代码
// ali-captcha.js
import { postCode } from '../../service/api';

const AliyunCaptchaPluginInterface = requirePlugin('AliyunCaptcha');
const INTERVAL = 100;

// 业务请求(带验证码校验)回调函数
export const captchaVerifyCallback = async function (captchaVerifyParam) {
    try {
      const result = await postCode({ ali_captcha_verify_param: captchaVerifyParam, phone: this.data.phone });
      return {
        captchaResult: result.data.ali_verify_captcha,
        bizResult: result.data.ali_verify_captcha,
      };
    } catch (error) {
      AliyunCaptchaPluginInterface.refresh();
    }
  };

  // 业务请求验证结果回调函数
export const onBizResultCallback = function (bizResult) {
    if (bizResult === true) {
      let time = setInterval(() => {
        let {
            countInterval
        } = this.data;
        if (countInterval <= 1) {
            clearInterval(time);
            this.setData({
                countInterval: INTERVAL,
                codeBtnText: '重新获取'
            });
            return;
        }
        countInterval--
        this.setData({
            countInterval,
            codeBtnText: `${countInterval}s`
        })
    }, 1000)
    } else {
      wx.showToast({
        title: '业务验证不通过!',
        duration: 2000,
        icon: 'error',
      });
    }
  };
js 复制代码
// 主要代码
import { captchaVerifyCallback, onBizResultCallback } from 'ali-captcha.js';

const AliyunCaptchaPluginInterface = requirePlugin('AliyunCaptcha');

onLoad() {
    const pluginProps = {
        SceneId: '',
        mode: 'popup',
        captchaVerifyCallback: captchaVerifyCallback.bind(this),
        onBizResultCallback: onBizResultCallback.bind(this),
        slideStyle: {
          width: 540,
          height: 60,
        },
        language: 'cn',
        region: 'cn',
      };
      getCaptchaConfig().then((res) => {
        pluginProps.SceneId = res.data.scene_id;
        this.setData({
          loadCaptcha: true,
          pluginProps,
        });
      }).catch(err=>{
        wx.showToast({
            title: '获取验证码配置失败',
            icon: 'none',
            duration: 3000
        })
      })
},
getCodeHandle() {
    // 表单校验
    AliyunCaptchaPluginInterface.show();
}

开始分包

写好,测试,没问题,提CR,结果

居然把插件放在主包了,马上改,使用分包异步化+占位组件

文档:在小程序中,不同的分包对应不同的下载单元;因此,除了非独立分包可以依赖主包外,分包之间不能互相使用自定义组件或进行 require。「分包异步化」特性将允许通过一些配置和新的接口,使部分跨分包的内容可以等待下载后异步使用,从而一定程度上解决这个限制。

将插件封装为一个单独的组件

json 复制代码
{
    "component": true,
    "usingComponents": {
        "aliyun-captcha": "plugin://AliyunCaptcha/captcha"
    }
}
js 复制代码
import { getCaptchaConfig, postCode } from '../../service/api';

const AliyunCaptchaPluginInterface = requirePlugin('AliyunCaptcha');

// 业务请求(带验证码校验)回调函数
const captchaVerifyCallback = async function (captchaVerifyParam) {
    try {
      const result = await postCode({ ali_captcha_verify_param: captchaVerifyParam, phone: this.data.phone });
      return {
        captchaResult: result.data.ali_verify_captcha,
        bizResult: result.data.ali_verify_captcha,
      };
    } catch (error) {
        AliyunCaptchaPluginInterface.refresh();
    }
  };

// 业务请求验证结果回调函数
const onBizResultCallback = function (bizResult) {
    if (bizResult === true) {
        this.triggerEvent('changeCodeBtnState');
    } else {
        wx.showToast({
        title: '业务验证不通过!',
        duration: 2000,
        icon: 'error',
        });
    }
};

Component({
    lifetimes: {
        attached: function () {
            const pluginProps = {
                SceneId: '',
                mode: 'popup',
                captchaVerifyCallback: captchaVerifyCallback.bind(this),
                onBizResultCallback: onBizResultCallback.bind(this),
                slideStyle: {
                  width: 540,
                  height: 60,
                },
                language: 'cn',
                region: 'cn',
              }
            getCaptchaConfig().then((res) => {
                pluginProps.SceneId = res.data.scene_id;
                this.setData({
                  loadCaptcha: true,
                  pluginProps,
                });
              }).catch(()=>{
                wx.showToast({
                    title: '获取验证码配置失败',
                    icon: 'none',
                    duration: 3000
                })
              })
        }
    },
    properties: {
        phone: {
          type: String,
          value: ''
        }
    },
    data: {
    },
    methods: {
      show() {
        AliyunCaptchaPluginInterface.show();
      }
    }
})
html 复制代码
<aliyun-captcha id="captcha-element" wx:if="{{loadCaptcha}}" props="{{pluginProps}}" />

将其设置为一个单独的分包:

json 复制代码
// app.json
{
  "root": "pkg-plugin",
  "pages": [
    "ali-captcha/ali-captcha"
  ],
  "plugins": {
      "AliyunCaptcha": {
      "version": "2.1.1",
      "provider": "wxbe275ff84246f1a4"
    }
  }
}

分包完成,在需要用到的页面中使用

json 复制代码
// login.json
{
    "navigationBarTitleText": "登录",
    "usingComponents": {
      "captcha": "/pkg-plugin/ali-captcha/ali-captcha"
    },
    "componentPlaceholder": {
      "captcha": "view"
    }
}
html 复制代码
<-- login.wxml -->
<captcha class="aliCaptcha" phone="{{ phone }}" bind:changeCodeBtnState="changeCodeBtnState" />
js 复制代码
// login.js
// 处理表单校验等业务

参考:

分包异步化

微信小程序原生语言接入

相关推荐
GoldKey2 小时前
gcc 源码阅读---语法树
linux·前端·windows
Xf3n1an4 小时前
html语法
前端·html
张拭心4 小时前
亚马逊 AI IDE Kiro “狙击”Cursor?实测心得
前端·ai编程
烛阴4 小时前
为什么你的Python项目总是混乱?层级包构建全解析
前端·python
@大迁世界4 小时前
React 及其生态新闻 — 2025年6月
前端·javascript·react.js·前端框架·ecmascript
红尘散仙5 小时前
Rust 终端 UI 开发新玩法:用 Ratatui Kit 轻松打造高颜值 CLI
前端·后端·rust
新酱爱学习5 小时前
前端海报生成的几种方式:从 Canvas 到 Skyline
前端·javascript·微信小程序
袁煦丞5 小时前
把纸堆变数据流!Paperless-ngx让文件管理像打游戏一样爽:cpolar内网穿透实验室第539个成功挑战
前端·程序员·远程工作
慧慧吖@6 小时前
关于两种网络攻击方式XSS和CSRF
前端·xss·csrf
徐小夕6 小时前
失业半年,写了一款多维表格编辑器pxcharts
前端·react.js·架构