AICon 北京站 Keynote 亮点揭秘,想了解 Agent 智能体来就对了! 了解详情
写点什么

从源码看微信小程序启动过程

  • 2020-03-11
  • 本文字数:3672 字

    阅读完需:约 12 分钟

从源码看微信小程序启动过程

一、写作背景

接触小程序一年多,真实体验就是小程序开发门槛相对而言确实比较低。不过小程序的开发方式,一直是开发者吐槽的,如习惯了 Vue,React 开发的开发者经常会吐槽小程序一个 Page 必须由多个文件组成,组件化支持不完善或者说不能非常愉快的开发组件。在以前小项目中没太大感觉,从加入有赞,参与有赞微商城小程序的开发,是真切的体会到对于大型小程序项目开发的复杂性。


有赞从微信小程序内测就开始开发小程序,在不支持自定义组件的时代,只能通过 import 的形式拆分模块或实现组件。在业务复杂的页面,可能会 import 非常多的模块,而相应的 wxss 也需要 import 样式,除了操作繁琐,有时候也难免遗漏。


作为开发者,我们当然希望可以让工作更简单,更愉快,也希望改善我们的开发方式。所以希望能够更了解微信小程序框架,减少不必要的试错,于是有了一次对小程序框架的 debug 之旅。(基础库 1.9.93)


通过三周空余时间的 debug,也算对小程序框架有了一些浅显的认识,达到了最初的目的;对小程序启动,实例,运行等有了真切的体会。这篇文章记录了小程序框架的基本代码结构,启动流程,以及程序实例化过程。


本文的目的是希望把我看到的分享给对小程序感兴趣或者正在开发小程序的读者,主要解答“框架对传入的对象等到底做了什么”。

二、从启动流程一窥小程序框架细节

在开发者工具中使用 help() 方法,可以查看一些指令和方法。使用其中的 openVendor 方法可以打开微信开发者工具在小程序框架所在目录。其中以包括以基础库命名的目录和其他帮助文件,如其中有两个工具 wcc,wcsc。wcc 可把 wxml 转换为对应的 JS 函数 —— $gwx(path, global),wcsc 可将 wxss 转换为 css。而基础库目录包括 WAService.js 和 WAWebview.js 文件。小程序框架在开发者工具中以 WAService.js 命名(WAWebview.js 不知其作用,听说在真机环境使用该文件)。


在开发中工具命令行使用 document.head 可以查看到小程序的启动流程大致如下:



以小节的方式分别介绍这些流程,小程序是如何处理的(小节编号与图中编号相同)。

1、初始化全局变量

下图是小程序启动是初始化的一些全局的变量:



那些使用“__”开头,未在文档中提及可使用变量是不建议使用的,__wxAppCode__ 在开发者工具中分为两类值,json 类型和 wxml 类型。以 .json 结尾的,其 key 值为开发者代码中对应的 json 文件的内容,.wxml 结尾的,其 key 值为通过调用 $gwx(’./pages/example/index.wxml’) 将得到一个可执行函数,通过调用这个函数可得到一个标识节点关系的 JSON 树。


2、加载框架(WAService.js)

使用工具对 WAService.js 进行格式化后进行 debug。可以发现小程序框架大致由: WeixinJSBridgeNativeBufferwxConsoleWeixinWorkerJavaScript兼容(这部分为猜测)、 Reporterwxexparser__virtualDOM____appServiceEngine__ 几部分组成。


其中除了 wxWeixinJSBridge 这两个基础 API 集合, exparser, __virtualDOM__, __appServiceEngine__ 这三部分作为框架的核心, __appServiceEngine__ 提供了框架最基本的接口如 App,Page,Component; exparser 提供了框架底层的能力,如实例化组件,数据变化监听,view 层与逻辑层的交互等;而 __virtualDOM__ 则起着链接 __appServiceEngine__exparser 的作用,如对开发者传入 Page 方法的对象进行格式化再传入 exparser 的对应方法处理。


框架对外暴露了以下 API:Behavior,App,Page,Component,getApp,getCurrentPages,definePlugin,requirePlugin,wx。

3、业务代码的加载

在小程序中,开发者的 JavaScript 代码会被打包为


define('xxx.js', function(require, module, exports, window, document, frames, self, location, navigator, localStorage, history, Caches, screen, alert, confirm, prompt, fetch, XMLHttpRequest, WebSocket, webkit, WeixinJSCore, Reporter, print, WeixinJSBridge) {  'use strict';
// your code})
复制代码


这里的 define 是在框架中定义的方法,在框架中提供了两个方法:require 和 define 用来定义和使用业务代码。其方式有些像 AMD 规范接口,通过 define 定义一个模块,使用 require 来应用一个模块。但是也有很大区别,首先 define 限制了模块可使用的其他模块,如 window,document;其次 require 在使用模块时只会传入 require 和 module,也就是说参数中的其他模块在定义的模块中都是 undefined,这也是不能在开发者工具中获取一些浏览器环境对象的原因。


在小程序中,JavaScript 代码的加载方式和在浏览器中也有些不同,其加载顺序是首先加载项目中其他 js 文件(非注册程序和注册页面的 js 文件),其次是注册程序的 app.js,然后是自定义组件 js 文件,最后才是注册页面的 js 代码。而且小程序对于在 app.js 以及注册页面的 js 代码都会加载完成后立即使用 require 方法执行模块中的程序。其他的代码则需要在程序中使用 require 方法才会被执行。


下面详细介绍了 app.js,自定义组件,页面 js 代码的处理流程。

4、加载 app.js 与注册程序

在 app.js 加载完成后,小程序会使用 require(‘app.js’) 注册程序,即对 App 方法进行调用,App 方法是对 __appServiceEngine__.App 方法的引用。


下图是框架对于 App 方法调用时的处理流程:



App 方法根据传入的对象实例化一个 app 实例,其生命周期函数 onLaunch 和 onShow 因为使用不同的方式获取 options 的参数。在有些需要根据场景值来实现需求的,或许使用 onShow 中的场景值更合适。


在实际开发过程中发现,在微信顶部唤起小程序和在小程序列表唤起的 options 也是不一样的。在该案例中通过点击分享的小程序进入后,关闭小程序,再通过不同方式进入小程序,通过顶部唤起的还是 options 的 path 属性还是分享出来的 path,但是通过列表中打开直接回到了首页,这里 App 中的 onShow 就会获取到不同的 options。

5、加载自定义组件代码以及注册自定义组件

自定义组件在 app.js 之后被加载,小程序会在这个过程中加载完所有的自定义组件(分包中自定义组件没有有测试过),并且是加载完成后自动注册,只有注册完成后才会加载下一个自定义组件的代码。


下图是框架对于 Component 方法处理流程:



图中介绍了框架如何对传入 Component 方法的对象的处理,其后面还有很多深入的对于组件实例化的步骤没有在图中表示出来,具体可以在文章最后的附件中查看。


自定义组件在小程序中越来越完善,其拥有的能力也比 Page 更强大,而后面会提到在使用自定义组件的 Page 中,Page 实例也会使用和自定义组件一样的实例化方式,也就是说,他拥有和自定义组件一样的能力。

6、加载页面代码和注册页面

加载页面代码的处理流程和加载自定义组件一样,都是加载完成后先注册页面,然后才会加载下一个页面。


下图是注册一个页面时框架对于 Page 方法的处理流程:



Page 方法会根据是否使用自定义组件做不同的处理。使用自定义组件的 page 对象会被处理为和自定义组件的结构,并在页面实例化时使用不同的处理流程进行实例化。当然对于开发而言没任何不同。


从图中可以发现 Page 传入的(生命周期)代码并不会在这里被执行,可以通过下面小节了解 Page 实例化的详细过程。

7、等待页面 Ready 和 Page 实例化

还记得上面介绍的启动流程中最后一步等待页面 Ready?严格来讲是等待浏览器 Ready,小程序虽然有部分原生的组件,不过本质上还是一个 web 程序。


在小程序中切换页面或打开页面时会触发 onAppRoute 事件,小程序框架通过 wx.onAppRoute 注册页面切换的处理程序,在所有程序就绪后,以 entryPagePath 作为入口使用 appLaunch 的方式进入页面。


下图是处理导航的程序流程:



从图中可以看出页面的实例化是在进入页面时进行,下图是具体的实例化过程:



下图是最终可得到 Page 实例:



可以发现其中多了 onRouteEnd API,实际该接口不会被调用。其中以 component 标记的表示只有在使用了自定义组件时才会有的方法和属性。在前面第 5 小节提到了对于使用自定义组件的页面会按照自定义组件方式解析,这些属性和方法与自定义组件表现一致。

8、关于 setData

小程序框架是一个以数据驱动的框架,当然不能少了对他如何实现数据绑定的探索,下图是 Page 实例的 setData 执行流程:



其中 component:setData 表示使用自定义组件的 Page 实例的 setData 方法。

三、写在最后

这是一次不完全的小程序框架探索,是在微信开发工具中 debug 的结果。虽然对于实际开发没有什么太大的帮助,但是对框架如何对开发的 js 代码进行处理有了一个很明确的认识,在使用一些 js 特性时可以有明确的感知。如果你还疑惑“小程序框架对传入的对象等到底做了什么”那一定是我表达能力太差,说声对不起。


通过这一次 debug ,也给我引入了新的问题,还希望能够有更多的讨论:


  • 自定义组件太多启动时会耗时处理自定义组件

  • 文件太多会耗时读文件

  • 合理的设计分包很重要


一份在调试过程中的笔记 小程序框架不完全分析.xmind,如果看官有兴趣可以下载看看。当然最后对于框架中已有的能力,还是非常希望微信可以开放更多稳定的接口,并在文档中告知开发者,让开发变得简单一些。


2020-03-11 22:191124

评论

发布
暂无评论
发现更多内容

三大「价值流」搞定技术型管理

蔡建斌

管理 技术管理 精益 引航计划 内容合集

世界的尽头是铁岭,互联网的尽头是它

艾小仙

全球国家简码信息表

入门小站

工具

网络攻防学习笔记 Day132

穿过生命散发芬芳

网络模型 9月日更

简单五步:给你的 Golang 应用加一个 GUI ( Electron 驱动)

baiyutang

UI 跨平台 Go 语言 GUI 9月日更

MySQL + Keepalived 双主热备搭建

Se7en

测试模型中理解压力测试和负载测试

FunTester

性能测试 接口测试 压力测试 FunTester 负载测试

循环神经网络LSTM RNN回归:sin曲线预测

华为云开发者联盟

RNN 循环神经网络 LSTM LSTM RNN回归

手撸二叉树之二叉搜索树的最小绝对差

HelloWorld杰少

数据结构与算法 9月日更

KVM虚拟机常用管理命令

玏佾

kvm 虚拟主机

计算机工业的生态链(三)

姬翔

9月日更

linux之chattr命令

入门小站

Linux

如何PWA构建现代离线应用程序

devpoint

Service Worker 9月日更

什么是Spring-Cloud、需要掌握哪些知识点,Java面试常问的算法题

Java 程序员 后端

什么是事务数据库?,Java程序员面试题集大全

Java 程序员 后端

一文说清BIO、NIO、AIO不同IO模型演进之路

慕枫技术笔记

后端 引航计划

性能测试中标记请求参数实践

FunTester

性能测试 接口测试 压力测试 FunTester 标记参数

如何从零搭建起一支技术团队

石云升

团队管理 管理 引航计划 内容合集 9月日更

三面滴滴Java岗,Java程序员校招蚂蚁金服

Java 程序员 后端

架构训练营 模块7 - 王者荣耀商城异地多活架构设计

sophiahuxh

网卡修改网速和buffer

耳东@Erdong

9月日更 网卡

HTML进阶(二)

Augus

html 9月日更

编程基础:CPU资源监控

正向成长

CPU调度

设计模式类型

一个大红包

9月日更

用IoT放羊养牛,不出门也能知道它们的动向

华为云开发者联盟

物联网 华为云 iotda 畜牧业 华为云物联网平台

如何选择收银机主板?

双赞工控

安卓主板

三面美团、四面阿里成功斩下offer,下血本买的

Java 程序员 后端

快速上手Apache POI

卢卡多多

POI Apache POI 9月日更

带你读AI论文丨用于细粒度分类的Transformer结构—TransFG

华为云开发者联盟

细粒度 映射 Transformer TransFG 差异性图片

三面蚂蚁惨败,面试官要求手写算法,从外包公司到今日头条offer

Java 后端

使用Git分布式控制系统,怒斩腾讯和阿里的Offer

Java 程序员 后端

从源码看微信小程序启动过程_文化 & 方法_有赞技术_InfoQ精选文章