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

需求背景

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

需求分析

公司一直有订阅阿里云验证码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
// 处理表单校验等业务

参考:

分包异步化

微信小程序原生语言接入

相关推荐
小小小小宇37 分钟前
前端Loader笔记
前端
烛阴2 小时前
从0到1掌握盒子模型:精准控制网页布局的秘诀
前端·javascript·css
前端工作日常5 小时前
我理解的`npm pack` 和 `npm install <local-path>`
前端
李剑一5 小时前
说个多年老前端都不知道的标签正确玩法——q标签
前端
嘉小华5 小时前
大白话讲解 Android屏幕适配相关概念(dp、px 和 dpi)
前端
姑苏洛言5 小时前
在开发跑腿小程序集成地图时,遇到的坑,MapContext.includePoints(Object object)接口无效在组件中使用无效?
前端
奇舞精选5 小时前
Prompt 工程实用技巧:掌握高效 AI 交互核心
前端·openai
Danny_FD5 小时前
React中可有可无的优化-对象类型的使用
前端·javascript
用户757582318555 小时前
混合应用开发:企业降本增效之道——面向2025年移动应用开发趋势的实践路径
前端