让别人的小程序运行在自己的app中

2019-01-21  本文已影响0人  锐心凌志

概要

本文包括的内容:

介绍小程序原理的文章比较多,这篇讲的比较细:微信小程序架构分析。这篇文章的作者也成功的实现了wept,让小程序运行在自己的webapp里。

参考最多的是微店的Hera,完成度非常高的小程序框架,能够将小程序的demo代码在web/iOS/android运行起来,而且实现了很多工具。Hera的问题是开发于比较早期的版本,不兼容最新的版本了。Hera还有一个问题是他修改了小程序构建之后的目录结构,采用了service.html作为service部分的入口,跟小程序本身的实现尚有有一些区别。所以Hera只能够构建执行自己编写的小程序,不能执行别人编写的小程序。

我的目标是能够运行其它人开发的app,意味着我只能通过逆向的方式拿到wxapkg。但是因为拿不到源码,所以要尽可能在构建环节跟小程序保持一致。

经过数周的挣扎,目前已经实现了运行官方demo。已经达到"可行"的阶段,但是还远远谈不上“可用”,因为需要实现小程序大量的API,这是个体力活,依赖个人的力量难以完成。

构建

官方demo小程序原先的目录分为几类文件:

demo
├── app.js
├── app.json
├── app.wxss
├── config.js
├── image
│   ├── green_tri.png
│   ├── ...
├── page
│   ├── API
│   │   ├── index.js
│   │   ├── index.json
│   │   ├── index.wxml
│   │   ├── index.wxss
│   │   ├── pages
│   │   │   ├── action-sheet
│   │   │   │   ├── action-sheet.js
│   │   │   │   ├── action-sheet.json
│   │   │   │   ├── action-sheet.wxml
│   │   │   │   └── action-sheet.wxss
│   │   │   ├── ...
│   │   └── resources
│   │       └── ...
│   ├── ...
├── project.config.json
├── util
│   └── util.js
└── vendor
    └── qcloud-weapp-client-sdk
        ├── ...

经过小程序的开发环境构建后,生成了一个*.wxapkg文件。
这个文件可以通过从越狱的iPhone或者root的安卓手机上拿到。有部分人用charles通过https抓包拿到了下载链接,也拿到了包。
拿到后要进行解包。有大神已经通过反编译安卓apk的方式拿到了解包部分的代码,然后用python重写了一遍。源码见wechat-app-unpack

解包后得到的目录如下:

1.wxapkg_dir
├── app-config.json
├── app-service.js
├── app-service.js.map
├── image
│   ├── green_tri.png
│   ├── ...
├── page
│   ├── API
│   │   ├── index.html
│   │   ├── pages
│   │   │   ├── action-sheet
│   │   │   │   └── action-sheet.html
│   │   │   ├── ...
│   │   └── resources
│   │       └── kind
│   │           ├── api.png
│   │           ├── ...
│   ├── ...
└── page-frame.html

转换过程可以分为三部分:

openVendor命令可以在小程序中获取到构建脚本wcc和wcsc, 以及各个版本小程序的执行SDK ****.wxvpkg,这个SDK也可以用wechat-app-unpack解开,解开后里面就是WAService.js和WAWebView.js等代码。

wxml/wxss的构建原理

wxss 转换成了css,wxml转换成了inject_js,实际上就是virtual_dom。
是用什么工具转换的?小程序里是叫wcc和wcsc。在开源工具hera自己实现了一套wxss-transpiler和wxml-transpiler。而hera的前身wept是直接使用wcc和wcsc。
我们为了减少维护成本,直接采用wcc和wcsc。
因为我们没有wcc和wcsc的源码,所以只能借助wxss-transpiler和wxml-transpiler来帮助我们理解wxml/wxss的构建原理。

wxss-transpiler调用了一个PostCSS的插件,用来处理wxss。
PostCSS 提供了一种方式用 JavaScript 代码来处理 CSS。它负责把 CSS 代码解析成抽象语法树结构(Abstract Syntax Tree,AST),再交由插件来进行处理。插件基于 CSS 代码的 AST 所能进行的操作是多种多样的,比如可以支持变量和混入(mixin),增加浏览器相关的声明前缀,或是把使用将来的 CSS 规范的样式规则转译(transpile)成当前的 CSS 规范支持的格式。

wxml-transpiler:实现了一个转译器的工作,比如postcss也是转译器,包括解释器(parser),代码转换器(Transformer),代码生成器(Generator)。这个是闭源的。

更多实现原理见这篇文章

模块之前的通信

image

小程序在App中执行时的时候分为三个不同的模块,View/Service/Native,各司其职。

View和Service都在WKWebView中执行,互相无法调用。他们之间通过Native层通信。

Native和WebView之间通过webkit.messagehandler和evaluateJavascript互相调用。

如何执行

这里以iOS为例介绍Native执行过程。安卓类似。

通过解压微信的ipa可以拿到WAService.js和WAWebView.js两个基础库文件,文件内容与hera的service.js/view.js已经有了较大的区别。
我们采用小程序的架构和hera的两个webView的方案,尽可能模仿小程序的执行过程。

View部分

View部分是比较直观的,就是WKWebView加载web页。这里需要在app-config.json里读取到首页的路径,然后加载该页面。这个路径下的xxx/index.html是无法直接加载的,需要做一些处理。要引入本地执行SDK里的index.css和view.js, 然后把page-frame.html里的virtual-dom全部塞进该页面。 然后loadHTML即可。

View所有的WKWebView也是要注册WKUserContentController的,用于通信。
通过反汇编可以得知这个类在微信中叫YYWAWebView,调用js是直接调用-evaluateJavaScript:completionHandler:方法的。

view.js中包含的逻辑:

Service部分

Service部分的实现,Hera和微信小程序采取的了不同的架构。
Hera的实现较为简洁,跟View部分保持一致,采用了WKWebView,调用-evaluateJavaScript:completionHandler:方法执行js,js回调OC时使用WKScriptMessageHandler。
通过反汇编可以得知这个类在微信中叫WAJSCoreService,js和OC之间的调用是采用JavascriptCore互相调用。

JavascriptCore它首先要加载app-config.json并把这个配置赋给一个全局对象__wxConfig。然后他要加载service.js是SDK基础,再然后他要加载app-service.js,这里面包含了用户编写的js逻辑。最后它发出全局消息
WeixinJSBridge.publish('serviceReady',,);</script>唤起小程序app的初始化。

Service.js中包含的逻辑:

Native部分

Native执行的问题比较复杂,因为基本是黑盒,里面发生了什么并不知道。
hera的方案在构建过程就已经跟小程序实际的方案有所区别,会提高维护成本。所以我们只能靠猜测来实现Native的执行过程。

Native部分就是作为入口,运行环境,跳转,转发消息,实现扩展。包括网络模块/摄像头/tabbar实现的都是扩展。
我们可以得知的是消息传递的协议。然后只能通过safari来调试webView,根据协议的名称和出入参来猜测协议的内容。

主要的困难点

小程序的性能启发

小程序是颠覆我对Web的固有印象,最初还以为是类似weex或者rn的调用原生的方式,没想到几乎完全是运行在WKWebView之上的。

存在的问题:

当然已经比纯web页强很多了。目前来看还是只适合轻量化的应用。受制于架构以及微信的平台,个人认为是对Web的替代和改善。但是就算在可见的未来,还是很难跟native抗衡。

现代浏览器和操作系统之间的界限越来越模糊。App的"下载/安装"过程本身就是一种妥协。只要小程序的体验足够好,应该没有人会拒绝。

上一篇下一篇

猜你喜欢

热点阅读