## 微信小程序技术解读 自今年初微信正式发布小程序,已有大半年时间。这期间,行业对微信小程序的关注经历了三个阶段。 - 第一个阶段是刚发布时的火热,大家都盼望这是“又一个公众号”,尝试从各个不同角度解读、预测小程序的价值所在,担心像几年前公众号刚上线时那样再次作出“误判”、错过“流量红利”。 - 第二个阶段是发布一两个星期后的失望和舆论冷却,大家对小程序的新鲜劲儿过了以后,发现跟想象中的流量红利很不一样,反而是有着这样那样的限制和不足。 - 第三个阶段是从三月底开始,随着微信持续不断地改善小程序体验和开放新能力,以及一些小程序初食螃蟹者传回的正面消息,对小程序的讨论逐渐回暖,大家开始更理性、更现实地思考微信小程序的商业、产品和技术价值。 本文并不会过多地在商业层面对小程序进行分析,而是主要从技术开发层面对其进行解读。文章分为四部分,涵盖对小程序技术原理的介绍、对小程序开发全流程的介绍、开发过程中的常见问题,以及对小程序第三方平台的简介。微信小程序开发是个很大的话题,一方面因为小程序技术框架本身值得讲的内容非常多,另一方面因为小程序所依附的微信生态有其复杂性。本文将对小程序开发的一些细节内容点到为止,留给读者自己通过官方文档、社区讨论、亲身开发等途径进行探索。 ### 小程序原理简介 摘自微信文档:“小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 App 体验的服务。” 在微信内部,小程序技术框架的代号是 MINA(据说其全称是“MINA IS NOT APP”)。从开发者的角度看,该框架包含两部分,见图1所示。 ![enter image description here](http://images.gitbook.cn/85a285d0-fc55-11e7-92e2-59b46d27f76f) 图1 小程序开发框架示意图 - 视图层:接收逻辑层传过来的数据并渲染页面;当用户与页面产生交互时,视图层将事件发送给逻辑层。 - 逻辑层:处理数据并发送给视图层,触发视图层页面渲染;接收并处理视图层发来的用户事件。 小程序的视图层可以简单地理解成 Web 开发中的 HTML 和 CSS,而逻辑层则可理解成 Web 开发中的 JavaScript。事实上,由于小程序框架在开发语言层面与 Web 开发高度接近,如果你已经有一定的 Web 开发经验,学习小程序开发将会十分轻松。 #### 视图层(View) 小程序框架在视图层提供了自己的描述语言 WXML 和 WXSS,并提供了一系列基础组件(Component)供我们快速构建视图。 WXML(WeiXin Markup Language)是框架提供的标签语言,在其中我们只能使用小程序框架所提供的Component。我们通过 WXML 能做到的最重要的两个事情是:通过类似 Mustache 的双括号语法实现单向数据绑定(逻辑层→视图层),比如`{{msg}}`;通过在标签上绑定事件处理函数实现事件反馈(视图层→逻辑层),比如`……`。 WXSS(WeiXin Style Sheets)是框架提供的样式语言,支持大部分的 CSS 特性,并且基于小程序特点进行了一些扩展。其中一个很重要的扩展是引入了 rpx 这个尺寸单位,rpx 类似 CSS 中的 em 单位,能为我们进行自适应设计带来很大方便。 小程序框架为我们提供了一系列基础组件,这些基础组件通常都自带了一些与微信风格吻合的基础样式,我们能通过组合这些基础组件进行快速开发。目前我们只能使用微信提供的 Component,还不支持自定义组件。 微信小程序的视图层使用 WebView 进行实际渲染。我们所写的 WXML 里的 Component 最终会被转换为普通的 HTML 标签显示在 WebView 中,而 WXSS 经过转换后也会变成普通的 CSS 代码,为那些 HTML 标签赋予样式。所以,虽然感觉上小程序是个原生 App,但其实我们看到的只是个网页。部分特殊的 Component(比如视频和地图组件)会被转换成 Native 组件,这些 Native 组件会覆盖在 WebView 的对应位置之上,在用户角度看来,这些 Native 组件与 WebView 上的HTML组件在视觉上是融为一体的。 #### 逻辑层(AppService) 逻辑层,顾名思义,是控制小程序业务逻辑的地方。我们通过处理两个方向的数据流动来实现对业务逻辑的控制:在逻辑层处理数据并发送到视图层,触发视图层页面渲染;在视图层获取用户事件并发送给逻辑层,触发逻辑层的对应业务代码。 在逻辑层,我们主要通过小程序框架提供的这两个能力来实现业务控制。 - 注册事件处理函数:小程序里面主要存在两类事件,生命周期事件和视图层用户事件。前者由小程序框架负责触发,后者则是由视图层在用户与页面进行交互时触发。我们通过在所需的事件节点安插合适的业务代码,便能实现对小程序的完全控制。 - 丰富的 API:微信小程序之所以受到跟其它 Web/Hybrid 框架不一样的关注,很重要的一点就是因为其运行在微信之内,能调用微信提供的丰富的 API。这些 API 主要分两类,一类是系统功能,比如网络请求、数据存储、位置获取等;另一类是微信特有功能,比如获取微信用户信息、打开摄像头扫描二维码、发起微信支付、获取微信群信息等。 我们在逻辑层使用的开发语言是 JavaScript。我们写的所有 JavaScript 代码最终会被打包为一份,放入一个 JavaScript 运行环境(JSCore),在一个独立的线程里运行。这份 JavaScript 代码会在小程序启动的时候开始运行,一直到小程序退出时才会停止,类似 Web 开发里的 ServiceWorker,因此我们也把小程序逻辑层称为 AppService。 #### 系统层 在视图层和逻辑层之外,小程序框架其实还有一个系统层。对开发者来说,平常开发小程序时不会直接接触到系统层,但实际上系统层在整个小程序框架中是一个关键的组成部分。 小程序的视图层和逻辑层分别运行在两个独立的线程里,当两层之间需要发生数据流动时,数据都是先从出发层流动到系统层,在系统层经过一定处理以后再转发给目标层。另外,系统层也负责提供逻辑层用到的各种原生 API。如果你有过 Android 或 iOS 的 WebView 开发经验的话,小程序系统层的概念就类似 WebView 里的 JSBridge。 ### 小程序开发简介 #### 开发流程 开发小程序,必须下载并安装微信官方提供的“开发者工具”。这是微信提供的 IDE(见图2),其地位就如 AndroidStudio 之于 Android 开发、Xcode 之于 iOS 开发,通过该 IDE 我们能完成代码编辑、调试预览、代码上传等工作。 ![enter image description here](http://images.gitbook.cn/11893080-fc56-11e7-92e2-59b46d27f76f) 图2 小程序 IDE 小程序 IDE 自带简单的代码编辑器,提供了语法高亮、自动补全等功能,能满足一般的代码编辑需求。对一些开发者来说自带编辑器可能略显简陋,可以选择使用自己喜爱的其它编辑器来编写代码。无论代码改动来自自带编辑器还是第三方编辑器,小程序 IDE 都会自动监听到代码文件改动并触发页面刷新。 小程序的调试预览,与 Web/Hybrid 开发有相同点也有不同点。相同点在于两者的开发语言都很接近,编译运行的过程也很类似;不同点在于微信小程序的“微信”二字,小程序需要调用一些微信原生功能。在开发小程序的过程中,我们大部分时间都可以使用 IDE 自带的网页调试窗口,该调试窗口通过类似小程序真实运行环境的 JSCore 和 Chrome WebView 实现,我们在其中看到的运行效果会跟真机运行效果很接近(当然我们还是需要真机测试确保一致)。在调试一些特殊功能时(比如支付、分享),我们需要通过 IDE 生成开发版二维码,用微信扫码打开进行真机调试。 #### 小程序发布 当我们的小程序开发到一定阶段,决定对外发布时,需要通过 IDE 将代码上传微信服务器,然后去微信管理后台进行后续的发布操作。发布时我们可以选择两种模式,一种是发布体验版,该版本只能被指定的体验用户打开,通常用于正式上线前的测试;另一种是发布正式版,即最终给普通用户使用的版本。发布正式版需要将小程序提交给微信审核,审核通常需要1到3天(微信官方说法是7天内完成审核),审核通过以后小程序将对普通用户可见。后续升级新版本时也需要走同样的审核发布流程。 ### 一些常见问题 #### 用户信息获取 在微信小程序里面,用户信息获取分为两个环节:login 和 getUserInfo。login 能让我们得到用户的 OpenID(一个微信用户的唯一ID),而 getUserInfo 能让我们进一步得到该用户的个人信息,比如昵称、头像。 当我们设计小程序的登录流程时,应该特别注意一个关键点:login 是静默的,而 getUserInfo 会弹出一个确认框要求用户授权。与一般移动 App 社交登录的做法不同,在微信小程序里面,我们通常只需要做 login 这一步,只要通过 login 获取到用户的 OpenID,我们就能建立自身业务的用户体系了。只有当我们的业务真正需要用到用户的昵称、头像等信息时,才应该去做 getUserInfo 这一步。用户信息属于个人隐私,所以微信不会直接交给我们,而是弹出授权确认框让用户做决定;而弹框有时候会影响用户体验,甚至对用户造成骚扰。微信小程序在框架层面这样设计,一方面是为了引导开发者做出真正考虑用户体验的产品设计,另一方面也与其“用完即走”的产品理念相吻合。 另外值得一提的是,小程序的运行环境跟浏览器不一样,没有 Cookie 机制,所以我们在验证用户身份后给用户赋予的 Token 标识无法像 Web 一样放到 Cookie 里,而应该另外找地方存放,比如放到 HTTP Header 或作为一个 HTTP 请求参数。 #### 网络请求 虽然我们在小程序里面写的是 JavaScript,但和 Web 开发不同的是,微信只允许我们使用其提供的 wx.request()方法进行网络请求,不能使用其它网络请求库。微信对我们的网络请求有这几个限制: - 域名限制:所请求的域名必须先在微信管理后台进行设置,且要求已进行备案,不允许使用 IP 和指定端口(开发时除外)。 - HTTPS 要求:所有网络请求都必须是 HTTPS 协议。 - 并发限制:同时进行的网络请求最多10个。 #### 页面路由 小程序的页面路由机制与常见的 Web 单页应用类似,我们可以通过微信提供的 JS API 进行页面切换,新打开的页面会堆砌在当前页面之上,形成页面栈。需要注意是,微信为了控制小程序复杂度,限制页面栈中最多存在5个页面,一旦达到该限制,我们将无法打开新的页面,除非关闭一些已有页面。这个限制要求我们在设计产品的时候要注意两点。第一是用户流程设计应该尽量简洁,避免一些没必要的页面步骤;第二是对一些关键的业务点,要考虑“万一当前页面栈已经满了”这种情况。比如说,在一个电商小程序里,订单支付页如果已经是第5个页面的话,用户将无法跳到新页面去选择地址,此时我们需要做一些特殊处理,比如将地址选择页面变为一个页内浮层,或者是进入订单支付页时关闭前一个页面。 #### 跨平台兼容 在 IDE 调试窗口、iOS 微信、Android 微信三个环境里,小程序的 JS API 和 WXSS 的表现都比较一致,通常我们无需太过关注兼容性问题,而是将主要精力集中在产品业务逻辑上。但偶尔也会遇到一些表现不一致的情况,比如某些 JS API 在 Android 和 iOS 上的返回参数不一致、某些 UI 组件在不同平台上有不同的 padding。我们在开发过程中,正式上线前都应该时不时进行不同平台的真机测试,确保表现一致。 #### 小程序码 为了让小程序形成更好的产品辨识度和视觉冲击力,微信小程序的主要入口不是普通的二维码,而是通过微信自有算法生成的“小程序码”。小程序码与二维码在编码算法层面类似,但在产品层面有很大不同。二维码是行业通用格式,任何 App 只要实现二维码算法就可以进行解析;小程序码使用微信自有算法,只能通过微信提供的 API 进行生成,也只能通过微信 App 进行扫码读取。 #### 官方文档 我们评价一个新技术的时候,很重要的一个标准就是其文档质量,因为通过观察其文档我们能判断出其技术特点、学习难度,以及其维护者对该技术的投入程度。在这方面微信小程序文档做得很不错,对学习者非常友好。小程序在年初刚发布的时候存在不少问题,但我们能看到微信技术团队保持持续不断的迭代优化,在修复 Bug、添加新功能的同时,文档也在不停地保持更新同步。 ### 小程序第三方平台 在微信小程序技术生态里,第三方平台是一个重要但大部分开发者不一定会经常遇到的话题。简单地说,通过第三方平台,客户能将自己的小程序账号一键授权给第三方,然后第三方就能为客户提供对应的小程序技术服务。换个说法,第三方平台其实就是微信生态里的 SaaS 模式。 举个例子,假设我们做了一个卖东西的电商小程序,现在我们想将这个小程序卖给好几个客户。如果用传统的外包模式,我们可能会分别索取这几个客户的小程序后台账号密码,然后为他们上传并发布代码;或者我们可能会直接将小程序代码交给客户,教客户怎样去上传和发布。这里面有几个问题:客户不一定(也不应该)愿意给出账号密码;我们给客户讲解小程序发布流程会耗费大量精力;我们不愿意公开产品的技术代码;对每个客户我们都需要人工操作,客户越多则人工工作量越大,业务容易遇到瓶颈。 而如果通过第三方平台来实现,上面的几个问题都能得到解决。客户来到我们的电商第三方平台,一键将自己的小程序账号授权给我们,然后就什么都不用关心了。我们得到客户的授权,通过微信 API 自动为客户将小程序发布出去,无需人工干预。在这个过程中,客户没有泄漏账号密码,也不需要了解不必要的技术知识;我们没有泄漏代码,而且整个流程都是自动化的,客户扩展的边际成本非常低。 搭建一个小程序第三方平台,在普通小程序开发技术的基础上,我们还需要考虑这两个环节。 - 客户授权:接收客户授权请求,并从微信服务器获取授权凭证。 - 代客户实现业务:获取到客户的授权凭证以后,我们便能拿着这个凭证为客户进行业务操作了,比如自动发布小程序、发送客服消息。 相比普通小程序开发,第三方平台开发有一定复杂性。难点一方面在于开发并运行一个平台所涉及的技术难度,另一方面在于代客户进行小程序操作所涉及的业务难度。 ### 结语 小程序发布至今虽然还不到一年时间,但其目前的用户体验、开发者体验都已经达到比较优秀的水平,而且微信团队对小程序长期保持着积极推进的态度,我们可以预见小程序生态在未来会越来越蓬勃。无论是从商业角度考量,还是从技术角度来看,小程序都值得大家去了解、学习和尝试。 感谢“造程序”(微信ID:zaochengxucom)对内容的建议和审校。 >
陈兴艺
>广州帅为网络联合创始人& CTO。曾任职多盟移动广告,深度参与多盟一键推广工具、积分墙广告平台等项目;在帅为主导了 apphao123 小程序商店、“拼一点商城”小 程序 SaaS 平台等项目的研发。科幻、滑雪爱好者。