写点什么

实现微信小程序最新运行环境系列 (初始篇)

  • 2020-04-30
  • 本文字数:3104 字

    阅读完需:约 10 分钟

实现微信小程序最新运行环境系列(初始篇)

前言

最近一段时间在研究实现微信小程序和小游戏编译打包和运行环境平台开发。


目前基本可以支持微信基础库 2.8.2 功能迭代了。


所以想通过记录分享一下自己的认知过程中遇到的一些问题和解决方案来更好的理解小程序设计上的优点和一些不足的地方。


在此之前网上有存在开源的一些基于微信基础库版本 1.0 的一些参考。核心作者是由开源大牛启明兄wept项目基础上构建的(目前有幸和启明兄成为同事对这个小程序整体的架构理解帮助了我很多)。


由于 wept 的运行环境是基于微信基础库 1.0 的版本上实现之后也不维护了,时间上是 2016 的在后续的更新的版本中新加的一些特性如自定义组件 npm 包很多 api 等开发实现都不支持,最主要是的微信在后续架构中更换底层的通信方式采用了 webstock 的方式等一些其他变化。

正文

后面我会通过几篇文章来整体描述一下从工具到破解到源码解析和原理到实现的处理流程


最开始的时候也在网上找了很多的资料,看了有一些人写的解析微信小程序架构的文章,从中学习了解了很多,


但如果想模拟实现出来这么个东西还是有蛮迷糊的,所以我想通过我们所实现的过程来一点点从现象 看本质来解析下微信小程序编译和运行原理。


凡事对自己多点信心,多坚持下,多学习下,想想我们遇到的问题,当时感觉我,搞不定了,弄不了,最后随着时间的推移和认知的迭代问题总会慢慢消灭掉。


本文将先通过全面解析微信开发者工具来知道那些基本的文件和内容组成一一讲述(从现象 看本质)。

在此之前我们通过官方文档可以了解一些内容

  • 整个小程序框架系统分为两部分:逻辑层(App Service)和 视图层(View);

  • 小程序提供了自己的视图层描述语言 WXML 和 WXSS;

  • 基于 JavaScript 的逻辑层框架,并在视图层与逻辑层间提供了数据传输和事件系统他们两个线程里运行;

  • 视图层使用 WebView 渲染,逻辑层使用 JSCore 运行, 视图层和逻辑层通过系统层的 JSBridage 进行通信,逻辑层把数据变化通知到视图层,触发视图层页面更新,

  • 视图层把触发的事件通知到逻辑层进行业务处理。


从上述说明中我们可以得知一些重要信息逻辑层(App Service)和 视图层(View) 以及两者之间的通信协调。


下面通过微信开发工具来展示说明,小程序逻辑层的 javascript 代码是运行在 NW.js 中,视图层是由 Chromium 60 Webview 来渲染的


他们之间是通过 webstock 协议来通信的。


以下我们主要是以 mac 环境为主


我们先打开 微信开发工具官方 demo 如图:



从上图和我们的一些理解我们知道微信小程序的文件格式主要组成:


  • .js 主要页面逻辑;

  • .wxml 页面结构,框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构;

  • .wxss 是一套样式语言,用于描述 WXML 的组件样式;

  • .json 页面配置按照『约定优于配置』的原则。


接下来我们先找到本机微信开发者工具应用包里面如图



我们后面分析的主要代码都在 package.nw 里面和 core.wxvpkg。


这些文件在后面实现过程中都会使用说明用途的。


  • js 文件里面的内容主要是在页面和逻辑层的渲染用,后面将会看到;

  • core.wxvpkg 是这个里面的核心文件破解这个包可以知道很多逻辑可以先给大家看下解压后包的结构:




core.wxvpkg 解压代码上传在unwxvpkg大家有兴趣可以自己先试试。


接下来我们回到开发者工具中打开:


微信开发者工具–》调试–》调试微信开发者工具


打开调试后我们可以看到的界面如下:

从上面的现象我们可以看出他的两层渲染层和逻辑层结构是包含在两个 webview 里面

第一个对应的 webview 是渲染层的每个页面都对应一个地址

但逻辑层 appservice 只有一个不变的

下来我们可以看看这个 webview 里面是个什么东

如果我们直接把 view 层的 webview 标签改成 iframe 的话

可以看到微信就直接不在里面展示给你页面白屏了


如果你更改 appservice 的 webview 的话微信还会给你各种 alert 弹框,反正应该就是不想让你分析他的代码




点击确定消都消不了只能重新重启编译了 有点小恶心啊


居然不让我们正大光明的看,那我们只能搞一些旁门左道来破坏了


我们第一步还是打开:微信开发者工具–》调试–》调试微信开发者工具


在控制台输入


document.getElementsByTagName('webview')
复制代码


可以看到对应的有 4 个 webview,我们先要关注的是第一个 webview 因为你点开可以发现第一个对应的就是渲染层的 webview


后面的几个可以先不关注,后续我们会详解


然后我们执行命令打开第一个 webview:


document.getElementsByTagName('webview')[0].showDevTools(true,null)
复制代码


可以看到如图



现在我们就可以看到微信页面渲染层的页面结构了


(这里说明下本篇文章中文件里面的内容每一个文件的来源和用途,我都会在后续章节中讲解出来 因为里面涉及的内容过多 我怕放在一篇文章里会太长大家看了会厌烦,所以我会分为几篇来说明,后面的 appservice 和 一些基础包和 WAWebview.js WAService.js 以及使用的同步 api 和请求在页面的 appservice.js 等等,在本篇中只会简单描述出来 不做过多讲解,后续会逐步更新)


上面的 webview 可以找到对应的页面层的结构,那么 appservice 要怎么找到呢?


其实最简单的我们直接在首页里面的控制台打 document 就可以直接看到展示的逻辑层代码


(我的做法是从写了微信的 alert 和基础库的一些文件都可以看到这个结构)



注意点在微信小游戏里面微信重写了 window 和 document 对象 所以不能直接按照我们平常操作页面那样使用


接下面我们看下微信小程序的基础库库文件


方法是我们在首页控制台里面输入 openVendor()


我们可以看到弹出的文件系统,这里面对应的就是你选择本地的


详情==》调试基础库==》选择基础库版本



  • .wxvpkg 文件就是每个基础库版本的包我们,解压这个包我们可以看到他的组成;

  • wcc 可执行程序,用于将 wxml 转为 view 模块使用的 js;

  • wcsc 可执行程序,用于将 wxss 转为 view 模块使用的 css。


.wxvpkg 包里面这个基础库文件的 WAWebview.js 和 WAService.js,对应这两个 webview 里面的 js 引用你可以仔细观察下.wxvpkg 文件解包后的格式:



解压.wxvpkg格式包的代码地址github


对于 wcc 和 wcsc 源码现在没必要去研究他,但我们可以通过脚本劫持方法可以看到他运行了什么命令操作


这里告诉大家一个方法劫持他的运行命令


找到微信开发者工具 wcc 和 wcsc 的地方然后新建两个同名的脚本,然后把原文件从命名,然后重启微信开发者工具一定要重启不然不生效


wcc wcsca劫持脚本代码地址github


然后我们到首页控制台还是输入 openVendor()可以看到输出的文件

从上面这个图就可以看出下面这个图里面我们可以认知到一些信息

  • 首次加载的时候 wcc 执行了-ds -d - xc…和-ds -d - cc…结构的命令可以看到微信首次把所有.wxml 都执行了

  • 可以看到参数里面有个数字其实他对应的有几种.wxml 文件形式向只存在.wxml 和自定义组件等一些格式他是没计算在内的

  • -xc -cc 其实对应就是下面图两个逻辑层和渲染层里面的 js 方式



  • 我发现当我们修改一个.wxml 里面一点改动的时候,微信又会全部从新编译执行这些命令很耗时这点其实可以改进的。

  • 另一个微信开发者工具感觉做的不友好的地方是大于 500KB 的 javascript 文件不做给你做 es6 转换和压缩,就算你设置了微信也不会给你转,可以在 source 里面的资源可以看出。


wcc 执行的命令最终生成的就是逻辑层和渲染层的 $gwxc()方法里面的 js 代码,大家可以自己手动测试下就会发现。


wxss 生成的主要是渲染层 eval()这一坨代码


本篇只是简单描述了一些关键文件的描述。


后面我会对关键文件进行一一分析描述下他具体做了什么,为什么用到它。


下一篇会给大家带来渲染层和逻辑层的具体页面文件内容结构解析,以及 webstock 通信架构在微信开发者工具里面的运用,可以先给大家看下。



其实他们之间的协调工作以及公开对外的 wx.对象上面的 api 都是通过 websocket 协议消息实现的。


2020-04-30 16:302436

评论

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

收集、处理并监控设备数据——Amazon IoT SiteWise Edge“一网打尽”

亚马逊云科技 (Amazon Web Services)

IoT

使用模版自动化 Amazon IoT 设备创建及证书注册过程

亚马逊云科技 (Amazon Web Services)

IoT

左手自研,右手开源,技术揭秘华为云如何领跑容器市场

华为云开发者联盟

Docker 开源 Kubernetes 容器 云原生

Linux 命令 less 全知全会

hedzr

Linux less

模块3作业

miliving

利用 Cognizant APEx 2.0 和 Amazon IoT SiteWise Edge 提高产品质量

亚马逊云科技 (Amazon Web Services)

IoT

圣诞节

Tiger

28天写作

PassJava 开源 (六) :整合Spring Cloud Alibaba Nacos组件

悟空聊架构

28天写作 passjava 悟空聊架构 12月日更 naocs

设计千万级学生管理系统的考试试卷存储方案

drizzle

「架构实战营」

1个通用工具平台+多个热点场景工具套件,助力开发者快速构建应用

华为云开发者联盟

云计算 低代码 开发工具 devcloud 应用构建

构建安防视频云存,和传统安防视频业务的烦恼说再见!

亚马逊云科技 (Amazon Web Services)

IoT

Capgemini 如何利用 Amazon IoT 通过农业洞察监控农田

亚马逊云科技 (Amazon Web Services)

IoT

给弟弟的信第23封|如何写一篇文章?

大菠萝

28天写作

这一期总结

张老蔫

28天写作

【CSS 学习总结】第五篇 - CSS 变量 var

Brave

CSS 12月日更

2022年就要开始啦

搬砖的周狮傅

目标

Certificate Vending Machine – Amazon IoT 设备接入 Amazon IoT 平台解决方案

亚马逊云科技 (Amazon Web Services)

IoT

Servlet基础知识与新手常遇到的错及解决方法(01)

海拥(haiyong.site)

服务器 28天写作 12月日更

华为云GaussDB新产品特性亮相DTC2021,重磅新品开源预告

华为云开发者联盟

数据库 华为云 GaussDB 同城双集群 内存引擎

前端CI/CD上如何保证依赖安装速度达到优解?

梁龙先森

前端 构建脚本

【CSS 学习总结】第四篇 - CSS 选择器-伪类和伪元素

Brave

CSS 12月日更

23《重学JAVA》--泛型

杨鹏Geek

Java25周年 28天写作 12月日更

HDZ城市行深圳站 | AIoT时代,如何抓住智联生活的战略机会点?

华为云开发者联盟

AIOT HarmonyOS 华为云IoT 智联生活 PLC-IoT

JavaScript 中对象和映射之间的 6 个区别

devpoint

JavaScript map Object 12月日更

Amazon IoT Core 服务成本优化

亚马逊云科技 (Amazon Web Services)

IoT

Amazon ES现更名为Amazon OpenSearch Service并支持OpenSearch 1.0

亚马逊云科技 (Amazon Web Services)

IoT

利用Amazon Lambda实现Amazon IoT设备证书的即时注册

亚马逊云科技 (Amazon Web Services)

IoT

物联网场景中灵活实施对设备的控制管理

亚马逊云科技 (Amazon Web Services)

IoT

🍃【Spring专题】「原理系列」SpringMVC的运行工作原理(补充修订)

码界西柚

spring springmvc 12月日更 流程解析

如何根据不同业务场景调节 HPA 扩缩容灵敏度

xcbeyond

Kubernetes 28天写作 12月日更

深圳买房记

hackstoic

房地产

实现微信小程序最新运行环境系列(初始篇)_语言 & 开发_风逝_InfoQ精选文章