移动化跨平台抖音小程序解决方案实战分享
1979 浏览2023年12月14日作者:抖音开放平台团队

作者:张振东,已获得作者授权转载。

一、项目背景

1.1 为什么要引入小程序?

业务希望通过消息通知下发的方式,及时通知用户优化部分环节的体验。

技术方案选型:

  • H5页面:无法使用微信、抖音等宿主APP的消息通知下发能力,主动由服务端通知用户 ❌
  • APP:支持消息通知下发功能,但是用户需要额外下载安装,提高用户使用成本 ❌
  • 小程序:支持消息通知下发功能,轻量 ✅

1.2 小程序的优势

从用户视角:

  • 触手可及,在常用APP内直接操作,不需要来回切换APP,提高操作频率和效率
  • 用完即走,无需下载安装,不需要花时间熟悉其他的APP,降低使用心智

从企业视角:

  • 基于用户基数非常大的APP(抖音、微信、支付宝、QQ),实现最小成本的用户挖掘
  • 借助小程序拉起小程序、小程序拉起APP的功能,实现用户引流
  • 相对于审批限制很多的应用市场(APP Store),小程序的使用更加简单方便,版本更新迭代的审核也更快

1.3 目标

  • 提高用户签到效率,减少排队时长
  • 完善应用生态,实现移动化跨平台小程序,支持一套代码编译发布到多个平台(抖音、微信、支付宝、QQ)
  • 沉淀相关物料和工具

二、产品设计

2.1 产品交互链路

三、技术方案

3.1 技术链路图

3.2 前置准备工作

3.2.1 抖音开放平台

线上环境 - 线上appId

沙盒环境(普通沙盒环境、继承测试环境)- 沙盒appId(用于boe和ppe测试)

  • 安装抖音开发者工具

点击链接,选择对应的设备版本进行下载即可安装


3.2.2 配置沙盒环境

开发、联调、测试阶段主要在沙盒环境进行(可以模拟支付场景),需要进行专门的配置

如果业务入驻审批时间过长影响到项目节奏,可以由开发人员注册账号后新建沙盒环境提前进入开发阶段

创建沙盒

点击“新增沙盒”按钮后会出现配置弹框

沙盒类型:小程序

沙盒应用名称

能力范围:沙盒通用能力(如果没有创建正式小程序的话,选择沙盒通用能力)

正式小程序能力映射(和正式环境的配置保持一致,如果已创建正式小程序建议选择这个配置)


配置服务端域名白名单

小程序对应的业务后端接口需要提前配置到白名单内,否则会访问受限

添加域名白名单时,域名类型选择“request合法域名”,域名url填写后端接口域名(不需要输入http前缀


服务端配置前端请求域名

考虑到接口安全性问题,后端需要配置前端网关到域名白名单,配置相关秘钥信息(用于和抖音后端服务交互)

沙盒环境的网关域名:open-sandbox.douyin.com


测试账号白名单

需要将登陆账号添加到“测试账号”白名单才能够在沙盒APP使用小程序

点击“绑定测试账号”,然后使用抖音沙盒APP扫码即可完成绑定,完成沙盒环境配置

3.3 项目搭建

3.3.1 框架选择-Taro

小程序跨平台框架

框架介绍

uni-app

使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序。

Chameleon

支持小程序、RN、Weex和H5等多种平台,采用与 Vue 一致的组件化方案、单文件组织方式、生命周期,同时数据响应能力对齐 Vue,数据管理能力对齐 Vuex。

Rax


支持小程序、Web、Node.js和快应用等多种平台,使用rax开发小程序,可以一次编码多端投放,使用 Rax DSL 配合 Web 应用的工程配置及各种基础库,Rax 是一个基于 React 写法的跨容器的 js 框架。

Taro


Taro是一款多端统一开发框架,不仅提供了React小程序开发的完整解决方案,同时也支持vue、angular和原生小程序的开发方式,支持在不同的小程序平台上运行。框架生态完善,公司内部有很多相关实践文档参考和沉淀的组件库auxo-taro。


小程序跨平台解决方案,支持使用 React/Vue/Nerv 等框架来开发各种APP小程序

3.3.2 项目初始化

  • 安装Taro脚手架工具(推荐使用yarn进行安装
1 # 使用 npm 安装 CLI
2 $ npm install -g @tarojs/cli
3
4 # OR 使用 yarn 安装 CLI
5 $ yarn global add @tarojs/cli
6
7 # OR 安装了 cnpm,使用 cnpm 安装 CLI
8 $ cnpm install -g @tarojs/cli
  • 使用taro init进行项目搭建,按照实际需要选择项目基础配置即可


3.3.3 选择组件库

选择组件库的两个重要参考维度:组件丰富度、高阶组件能力

组件丰富度:要求组件的种类多,可以覆盖大部分使用场景

高阶组件能力:复杂组件能否满足复杂场景的使用要求,比如表单组件、下拉加载组件、轮播组件等

序号

组件库名称

主要信息

示例截图

1

Taro Component


Taro 团队官方出品,数量少,功能不齐全,且文档不够丰富。

2

Taro UI

京东出品,包含49个组件,支持React。但表单组件API过于简单,无法实现表单校验,缺少高阶组件。

3

NutUi

京东出品,包含 50+组件,京东风格痕迹较重。并且对 react 的支持度较差。

4

Auxo-Taro

auxo推出的作为电商 C 端小程序组件库,基于Taro实现一套代码多端运行,但是组件数量少,高阶组件严重不足,没有表单组件、下拉加载组件


5

Taroify


基于Vant开发,包含 60+组件,支持React,组件数量足够多,且风格比较中立,高阶组件能力完善

临时选择的组件库是Taroify,满足业务开发需要,且方便根据UI样式二次封装组件库


3.3.4 项目配置

推荐几个非常实用的Taro项目配置,尽可能让大家像开发浏览器页面一样开发小程序,降低学习成本,提高开发效率


@tarojs/plugin-html插件

支持在Taro项目中使用HTML标签进行组件开发,可以保留开发浏览器页面的习惯,使用<div>来替代<view>。不过需要注意这个插件会把<span>标签也最终渲染成<view>,原因是小程序里的<Text>标签只能内部嵌套<Text>,如果把<span>标签替换成<Text><span>的内部就只能嵌套<span><i><b>这些行内元素,影响开发体验

1 {
2   plugins: [
3    '@tarojs/plugin-html'
4  ],
5 }


mini.postcss.cssModules.enable

该属性值默认是false,如果想使用css的module功能,则需要手动将值设置成true,然后css类的名字就会根据设置的generateScopedName自动生成,默认是[name]__[local]___[hash:base64:5],后面5位是基于base64生成的随机hash值

1 {
2  mini: {
3    postcss: {
4      cssModules: {
5        enable: true, // 默认为 false,如需使用 css modules 功能,则设为 true
6        config: {
7          namingPattern: 'module', // 转换模式,取值为 global/module
8          generateScopedName: '[name]__[local]___[hash:base64:5]'
9        }
10      }
11    }
12  }
13 }


designWidth

designWidth用来设置设计稿的尺寸,常见的值有750、640、375等,Taro默认会对所有单位进行转换(行内样式需要使用Taro.pxTransform()才能转换)。但是如果遇到比较复杂的情况,比如项目的设计稿是375px,而引入的组件库的标准尺寸是750px时就需要进行特殊配置,上面提到的“Taroify”组件库的设计稿尺寸就是750px

1 {
2  designWidth: (input) => {
3    // 第三方组件库的设计尺寸是750px
4    if (input.file?.replace(/\\+/g, '/').indexOf('@taroify') > -1) {
5      return 750;
6    }
7    // 项目设计稿的标准尺寸375px
8    return 375;
9  },
10  
11  // px->rpx的单位换算规则
12  deviceRatio: {
13    640: 2.34 / 2,
14    750: 1,
15    828: 1.81 / 2,
16    375: 2 / 1
17  },
18 }


@tarojs/plugin-http

小程序有一套自己的原生网络请求体系,可以通过Taro.request(option)进行使用,但是为了符合之前的开发习惯,可以通过@tarojs/plugin-http这个插件对axios实例进行封装,方便把之前在浏览器开发项目中封装好的axios配置直接拿过来用,配置请求拦截器、响应拦截器等等

1 {
2  plugins: ['@tarojs/plugin-http'],
3 }

不过由于真实的执行环境还是在小程序,就会受到部分限制:

  • 暂不支持上传,且插件默认会将全局 FormData、Blob对象替换成undefined(仅针对小程序环境)


另外由于这个插件比较新,对Taro的版本有要求

  • 需搭配 taro 主包 3.6.0 及其以上版本使用
  • webpack4 用户需升级插件版本为 3.6.6 及其以上


3.4 注意事项

3.4.1 数据安全

如何上送用户身份信息(利用抖音的openId去识别用户身份)

Token: 前端调用taro.login()获取的用户临时登陆凭证

OpenId: 后端根据前端上送的token调用抖音开发平台接口获取到的用户openId,该openId在小程序appId下保证唯一


3.4.2 引入lodash作为公共utils

现状:Taro项目中引入lodash后直接使用会报错

原因:

  Webpack5 处理node.global的实现:

1 /* webpack/runtime/global */
2 !function() {
3     __webpack_require__.g = (function() {
4         if (typeof globalThis === 'object') return globalThis;
5         try {
6             return this || new Function('return this')();
7         } catch (e) {
8             if (typeof window === 'object') return window;
9         }
10     })();
11 }();
    • 抖音小程序环境不支持globalThis变量
    • Webpack 5的webpack/runtime/global实现,相对于Webpack4的webpack/buildin/global,变成了严格模式,导致严格模式下此处的this是undefined
    • 小程序的JS环境里,new Function('return this')这种构造函数写法,return的this是空对象(在浏览器引擎或者正常Node环境,都正常return全局对象);微信小程序、字节小程序都存在这个问题


解决方案

  • 在Webpack5 配置里关闭默认的global实现,node.global = false

  • 使用ProvidePlugin注入自定义global兼容实现,参考webpack4内的实现即可:

代码实现:

1 // webpack4GlobalRuntime.js
2 // 来源是webpack@4/buildin/global.js
3 var g;
4
5 // This works in non-strict mode
6 g = (function() {
7     return this;
8 })();
9
10 try {
11     // This works if eval is allowed (see CSP)
12     g = g || new Function("return this")();
13 } catch (e) {
14     // This works if the window reference is available
15     if (typeof window === "object") g = window;
16 }
17
18 // g can still be undefined, but nothing to do about it...
19 // We return undefined, instead of nothing here, so it's
20// easier to handle this case. if(!global) { ...}
21 
22 module.exports = g;

四、价值收益

  • 定量效果
    • 通过引入抖音小程序解决方案,用户的提前预约率提升了 10%+,排队时长大幅下降。
  • 定性效果
    • 用户等待的负向反馈明显减少,近几周时间未收到此类投诉。
最后一次编辑于 2024 年 01 月 08 日
0 条评论

相关文章

专题推荐

热门文章

热门问答