美文网首页web前端
小程序底层框架实现原理解析

小程序底层框架实现原理解析

作者: 275cafb52764 | 来源:发表于2017-04-07 14:57 被阅读706次

    2017-04-06coding学院王跃腾讯课堂

    导语:作为一名前端开发,如果你还停留在应用开发层面,那你就OUT了,快来跟我一起探讨下小程序框架本身底层实现的一些技术细节吧,既能帮助我们理解整个小程序的运行机制,方便应用开发疑难杂症处理,也可以作为装逼神技~

    一、概述

    小程序就是基于当前的WEB规范实现的一种程序,运行在微信里面,既然是基于WEB规范,那自然离不开HTML,CSS和JS,虽然微信官方给出了不一样的名称:WXML,WXSS,但本质上还是在整个WEB体系之下构建的。

    WXML vs HTML,大家想到了什么?XML有没有,HTML和WXML都是XML的一套子集,只是HTML有完整和通用的文档类型定义(DTD),WXML相对简单,仅仅是微信自定义的少量标签。

    WXSS vs CSS,大家可以理解为就是CSS,只是自动做了缩减和兼容处理,比如长度单位使用rpx,支持import导入。

    实现逻辑部分的JS还是通用的ES规范,并没有什么不同,并且runtime还是Webview(IOS WKWEBVIEW, ANDROID X5)

    开发工具

    微信web开发者工具(集成编辑,调试,预览和发布)

    编辑功能比较弱,大家可以自行使用熟练的编辑器,我个人不太习惯,我还是使用webstorm开发,但是调试必须在微信的编辑器,这个编辑器自动监听了文件的修改,每次修改后保存会自动刷新,进入指定的首页。

    建议大家使用双显示器模式开发,一般是编辑,一般用于调试,效率会提高不少。

    大家猜下这个编辑器是用什么实现的?

    项目结构

    官方demo目录结构和实际道聚城小程序的目录结构如下:

    规定项目结构

    一个入口文件:app.js

    一个全局样式:app.wxss

    一个全局配置:app.json

    页面:pages下,每个页面再按文件夹划分,每个页面4个文件

    视图:wxml,wxss

    逻辑:js,json(页面配置,不是必须)

    注:pages里面还可以再根据模块划分子目录,孙子目录,只需要在app.json里注册时填写路径就行

    以上是必须的文件和目录,而实际中我们会增加别的目录,如lib,comm和utils等等目录,如道聚城小程序的目录结构

    打包发布

    开发完成后,我们就可以通过这里可视化的按钮,点击直接打包上传发布,审核通过后用户就可以搜索到了。

    我们看到下面有几个关于打包的选项,怎么实现的呢?

    这就涉及到这个编辑器的实现原理和方式了,它本身也是基于WEB技术体系实现的,nwjs+react,nwjs是什么:简单是说就是node+webkit,node提供给我们本地api能力,而webkit提供给我们web能力,两者结合就能让我们使用JS+HTML实现本地应用程序。

    既然有nodejs,那上面的打包选项里的功能就好实现了。

    ES6转ES5:引入babel-core的node包

    CSS补全:引入postcss和autoprefixer的node包(postcss和autoprefixer的原理看这里

    代码压缩:引入uglifyjs的node包

    坑:前期写的时候,使用了大量ES6的语法,在开发工具和IOS里都没发现问题,提交审核,提示有bug,特意提示是android机器,结果拿android机测试,果然有问题,最后定位问题,就是ES6语法导致的,在android上使用的x5内核,对ES6的支持不好,要兼容的话,要么使用ES5的语法或者引入babel-polyfill兼容库。

    打包后的结构

    小程序打包后的结构如下,开发模式下的很多文件都被打包了,具体怎么拿到上线后的正式包和怎么解压。

    所有的小程序基本都最后都被打成上面的结构

    1、WAService.js  框架JS库,提供逻辑层基础的API能力

    2、WAWebview.js 框架JS库,提供视图层基础的API能力

    3、WAConsole.js 框架JS库,控制台

    4、app-config.js 小程序完整的配置,包含我们通过app.json里的所有配置,综合了默认配置型

    5、app-service.js 我们自己的JS代码,全部打包到这个文件

    6、page-frame.html 小程序视图的模板文件,所有的页面都使用此加载渲染,且所有的WXML都拆解为JS实现打包到这里

    7、pages 所有的页面,这个不是我们之前的wxml文件了,主要是处理WXSS转换,使用js插入到header区域

    二、小程序架构

    微信小程序的框架包含两部分View视图层、App Service逻辑层,View层用来渲染页面结构,AppService层用来逻辑处理、数据请求、接口调用,它们在两个进程(两个Webview)里运行。

    视图层和逻辑层通过系统层的JSBridage进行通信,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务处理。

    小程序启动时会从CDN下载小程序的完整包,一般是数字命名的,如:_-2082693788_4.wxapkg

    三、技术实现

    小程序的UI视图和逻辑处理是用多个webview实现的,逻辑处理的JS代码全部加载到一个Webview里面,称之为AppService,整个小程序只有一个,并且整个生命周期常驻内存,而所有的视图(wxml和wxss)都是单独的Webview来承载,称之为AppView。所以一个小程序打开至少就会有2个webview进程,正式因为每个视图都是一个独立的webview进程,考虑到性能消耗,小程序不允许打开超过5个层级的页面,当然同是也是为了体验更好。

    AppService

    可以理解为也是一个页面,只是主要功能是负责逻辑处理部分的执行,底层提供一个WAService.js的文件来提供各种api接口,主要是以下几个部分:

    消息通信封装为WeixinJSBridge(开发环境为window.postMessage, IOS下为WKWebview的window.webkit.messageHandlers.invokeHandler.postMessage,android下用WeixinJSCore.invokeHandler)

    1、日志组件Reporter封装

    2、wx对象下面的api方法

    3、全局的App,Page,getApp,getCurrentPages等全局方法

    4、还有就是对AMD模块规范的实现

    然后整个页面就是加载一堆JS文件,包括小程序配置config,上面的WAService.js(调试模式下有asdebug.js),剩下就是我们自己写的全部的js文件,一次性都加载(这里跟单页应用一样,一次加载,保证视图切换的流程性)只是实现方式在开发模式和微信环境下不太一样。

    在开发环境下

    1、页面模板:app.nw/app/dist/weapp/tpl/appserviceTpl.js

    2、配置信息,是直接写入一个js变量,__wxConfig,如下图:

    3、 其它文件,如下图:

    线上环境

    而在上线后是应用部分会打包为2个文件,名称app-config.json和app-service.js,然后微信会打开webview去加载。线上部分应该是微信自身提供了相应的模板文件,在压缩包里没有找到。

    1、WAService.js(底层支持)

    2、app-config.json(应用配置)

    3、app-service.js(应用逻辑)

    大家可能在想微信官方放出来的文档里说的是运行在JavaScriptCore里面的,不是webview,这个后面再分析!

    AppView

    这里可以理解为h5的页面,提供UI渲染,底层提供一个WAWebview.js来提供底层的功能,具体如下:

    线上环境:

    模板文件:根目录page-frame.html

    WAWebview.js :根目录  WAWebview.js

    每次都是直接加载page-frame.html,然后把指定的page merge到这个模板文件里实现页面渲染。

    实际上,这里的View不像html一样,就是纯粹的标签渲染UI,这里还是有相应的JS处理逻辑的,只是主要是UI部分的逻辑,比如:小程序的组件就是有template和js组合而成的,像我们使用navigator标签,实际在跳转的时候,还是使用wx.redirectTo实现的。

    Service和View通信

    使用消息publish和subscribe机制实现两个Webview之间的通信,实现方式就是统一封装一个WeixinJSBridge对象,而不同的环境封装的接口不一样,具体实现的技术如下:

    windows(开发环境)

    通过window.postMessage实现(使用chrome扩展的接口注入一个contentScript.js,它封装了postMessage方法,实现webview之间的通信,并且也它通过chrome.runtime.connect方式,也提供了直接操作chrome native原生方法的接口)

    发送消息:window.postMessage(data, ‘*’);,// data里指定 webviewID

    接收消息:window.addEventListener(‘message’, messageHandler); // 消息处理并分发,同样支持调用nwjs的原生能力

    在contentScript里面看到一句话,证实了appservice也是通过一个webview实现的,实现原理上跟view一样,只是处理的业务逻辑不一样

    'webframe' === b ? postMessageToWebPage(a) : 'appservice' === b && postMessageToWebPage(a)

    IOS

    通过 WKWebview的window.webkit.messageHandlers.NAME.postMessage实现

    微信navite代码里实现了两个handler消息处理器

    invokeHandler: 调用原生能力

    publishHandler:消息分发

    android

    通过WeixinJSCore.invokeHanlder实现,这个WeixinJSCore是微信提供给JS调用的接口(native实现)

    invokeHandler: 调用原生能力

    publishHandler: 消息分发

    四、组件实现

    在WAWebview.js里有个对象叫exparser,它完整的实现小程序里的组件,看具体的实现方式,思路上跟w3c的web components规范神似,但是具体实现上是不一样的,我们使用的所有组件,都会被提前注册好,在Webview里渲染的时候进行替换组装。

    exparser有个核心方法:

    regiisterBehavior: 注册组件的一些基础行为,供组件继承

    registerElement:注册组件,跟我们交互接口主要是属性和事件

    组件触发事件(带上webviewID),调用WeixinJSBridge的接口,publish到native,然后native再分发到AppService层指定webviewID的Page注册事件处理方法

    五、总结

    技术原理:小程序底层还是基于Webview来实现的,并没有发明创造新技术,但它提供了桌面端集成工具还是比较有创意和诚意的,毕竟PC和移动端实现还不太一样。大大提升了开发效率

    基础框架:整个框架体系,比较清晰和简单,基于Web规范,保证现有技能价值的最大化,只需了解框架规范即可使用已有Web技术进行开发,

    MSSM:对逻辑和UI进行了完全隔离,这个跟当前流行的react,agular,vue有本质的区别,小程序逻辑和UI完全运行在2个独立的Webview里面,而后面这几个框架还是运行在一个webview里面的,如果你想,还是可以直接操作dom对象,进行ui渲染的

    组件机制:引入组件化机制,但是不完全基于组件开发,跟vue一样大部分UI还是模板化渲染,这也是vue相对react更容易上手的原因,前端天生就更适合用模板机制渲染UI(效率最高),而引入组件机制能更好的规范开发模式,也更方便升级,但是目前还不能自定义组件。

    多种节制:不能同时打开超过5个窗口,打包文件不能大于1M,dom对象不能大于16000个等,这些都是为了保证更好的体验。

    只要去做,

    总有可能。

    先转发,再点二维码,

    就是对我们最好的支持!

    业界最顶尖的技术大咖

    最权威的实战分享

    最前沿的行业咨询

    一切尽在腾讯课堂coding学院

    温馨提醒:

    1、微信端搜索课程

    在“腾讯课堂”官方微信里,回复你想学习的内容,即可快速找到你期待的课程哦!

    2、学习方式

    【电脑端】

    *可通过登录ke.qq.com进入学习;

    *可通过windows PC版QQ客户端面板上的课堂入口进入学习。

    【移动端】

    *下载APP “腾讯课堂”即可进入学习;

    *关注微信公众号或者手Q公众号“腾讯课堂”,进入学习。

    (注:微信和QQ的课程报名信息独立,登录时请选择对应的登录方式)

    扫描二维码

    关注更多精彩

    内容转载自公众号

    腾讯课堂Coding学院

    相关文章

      网友评论

      • 自由人是工程师:技术原理:小程序底层还是基于Webview来实现的,并没有发明创造新技术,但它提供了桌面端集成工具还是比较有创意和诚意的,毕竟PC和移动端实现还不太一样。大大提升了开发效率
        ---- 小程序是native和webview混合的, 普通组件确实是webview负责渲染,但是map, canvas这些是原生组件渲染的

      本文标题:小程序底层框架实现原理解析

      本文链接:https://www.haomeiwen.com/subject/pbehattx.html