速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

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

  • 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:19977

评论

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

Cisco ISR 1000 IOS XE 17.15.1a 发布下载,新增功能概览

sysin

Cisco 路由器 思科 ISR IOS XE

专业数据库管理工具Navicat Premium for Mac

Mac相关知识分享

数据库管理工具

VSD Viewer v6.16.1 mac Visio绘图文件阅读器

理理

设备管理问题不断,你是否也在为此头疼?

天津汇柏科技有限公司

低代码开发 设备管理 AI人工智能

安装adobe 系列应用出现Error无法继续安装,文件已损坏,无法打开解决方法

理理

KubeCon China 回顾|快手的 100% 资源利用率提升:从裸机迁移大规模 Redis 到 Kubernetes

小猿姐

数据库 redis Kubernetes 云原生

KubeCon China 回顾|在没有专用 Operator 的情况下管理数据库集群

小猿姐

数据库 Kubernetes 云原生

小间距LED屏的特点及发展趋势

Dylan

信息 LED显示屏 全彩LED显示屏 led显示屏厂家 户内led显示屏

广西北海市等保测评机构有哪些?在哪里?

行云管家

网络安全 北海

行云管家应邀参加2024腾讯全球数字生态大会, 共创数字生态美好未来

行云管家

云计算 腾讯数字生态大会 数字生态

昇思多维混合分布式并行技术,助力伙伴快速复现Llama 3.1-405B大模型

Geek_2d6073

PHP 程序员学会了 Go 语言就能唬住面试官吗?

EquatorCoco

php Go

Visio 绘图文件阅读器VSD Viewer for mac

Mac相关知识分享

Mac软件 绘图文件

Photoshop 2024 for mac中文激活版

Mac相关知识分享

ps 图像处理软件

专访北极星资本:比特币矿业基金背后的努力

TechubNews

通过 Python 轻松获取 QQ 游戏排行榜数据:实时查看热门游戏排名

幂简集成

游戏 API

XLD无损音频转码 X Lossless Decoder for mac 支持M1/M2

理理

FTP 客户端软件Transmit for Mac

Mac相关知识分享

ftp

百度MEG数据开发治理平台-TDS

百度Geek说

数据治理 数据开发 任务调度 #大数据

Teams电话 中国语音解决方案

cts喜友科技

通信 通讯 云通讯 通信通讯

国产游戏蓄力,火山引擎ByteHouse助力游戏厂商造爆款

字节跳动数据平台

数据库 大数据 云原生 Clickhouse 数仓

Transmit Mac版FTP客户端提升你在远程服务器上管理文件的效率

理理

深入浅出智能体工作流(Agentic workflow)

Botnow

大模型 AIGC 多智能体 企业 AI 应用 AI 智能体

【HDFS】集群出现大量的Under Replicated Blocks

扬_帆_起_航

交互式原型设计Axure RP 10 for Mac中文激活版

Mac相关知识分享

设计软件

苹果电脑专业的SVN管理工具 Cornerstone for Mac永久激活版

理理

KubeBlocks 如何降低管理多种数据库的学习门槛

小猿姐

数据库 云原生 operator kubernete

如何在扫码填写信息后,将数据实时推送给指定成员?

草料二维码

Nexpose 6.6.268 发布下载,新增功能概览

sysin

漏洞扫描 安全审计 漏洞管理 Nexpose

ETL数据集成丨MySQL到MySQL的数据迁移实践

RestCloud

MySQL 数据库 数据同步 数据迁移 ETL

云手机能否全面替代传统手机?深入探讨云手机的优缺点

Ogcloud

云手机 海外云手机 云手机海外版 云手机群控 手机群控

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