# 微信小程序实现原理 微信小程序采用`wxml`、`wxss`、`javascript`进行开发,本质是一个单页应用,所有的页面渲染和事件处理,都在一个页面内进行,但又可以通过微信客户端调用原生的各种接口。微信的架构,是数据驱动视图的`MVVM`模式,其视图`UI`和数据是分离的,所有的页面更新,都需要通过对数据的变更来实现。小程序分为两个部分`Webview`和`AppService`,`Webview`主要用来展现渲染界面,`AppService`用来处理业务逻辑、数据及接口调用,通过系统层`JSBridge`实现通信,实现`UI`的渲染与事件的处理。 ## 目录结构 ### 打包前 ``` Project ├── pages │ ├── index │ │ ├── index.js // index 逻辑 │ │ ├── index.json // index 配置 │ │ ├── index.wxml // index 结构 │ │ └── index.wxss // index 样式表 │ └── logs │ ├── logs.js // logs 逻辑 │ ├── logs.json // logs 配置 │ ├── logs.wxml // logs 结构 │ └── logs.wxss // logs 样式表 ├── app.js // 逻辑 ├── app.json // 公共配置 ├── app.wxss // 公共样式表 ├── project.config.json // 项目配置 └── sitemap.json // 页面收录配置 ``` ### 打包后 ``` Project ├── app-config.json // 小程序工程全部json配置信息 ├── app-service.js // JS业务逻辑打包到此处 ├── page-frame.html // 视图的模板文件 └── pages ├── index.html // index 页面 └── logs.html // logs 页面 ``` ## 架构方案 微信小程序的框架包含两部分`View`视图层与`AppService`逻辑层,`View`层用来渲染页面结构,`AppService`层用来逻辑处理、数据请求、接口调用,它们在两个进程里运行,具体实现是在两个`Webview`中运行。 视图层和逻辑层通过系统层的`JSBridge`进行通信,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务处理。 ``` ----------------------- ----------------------- | View | | AppService | | | | | | Page1 Page2 Page3 | | Manager Api | ----------------------- ----------------------- | ↑ | ↑ | Event | Data | Data | Event ↓ | ↓ | ------------------------------------------------------------------------- | JSBridge | | | | Native Storage Network ... | ------------------------------------------------------------------------- ``` 微信将所有的视图都将加载到一个`Webview`中,称之为`View`层。将所有进行逻辑处理的`JS`代码全部加载到另一个`WebView`中,称之为`AppService`层,每个小程序只有一个并且整个生命周期常驻内存。在`JSBridge`中封装了消息通信以及通过`App`访问`OS`能力的实现,对于消息通信通过在不同平台调用相应的方法进行通信,开发环境为`window.postMessage`, `IOS`下为`WKWebview`的`window.webkit.messageHandlers.invokeHandler.postMessage`,`Android`下为`WeixinJSCore.invokeHandler`。在`Js`引擎方面,`Android`中使用`X5`内核,`IOS`中使用`JavaScriptCore`引擎,开发工具中使用`nwjs Chrome`内核。 通过使用`View`视图层与`AppService`逻辑层就实现了双线程的小程序运行方案,通过两个线程,可以做到将代码放入沙箱执行,从而做到对于代码执行的安全与管控,当然对于双线程只是一个小程序的解决方案,倘若要在一个`App`上运行多个小程序,就应该采用多线程方案去执行,不仅是对于性能方面的考虑,也是为了防止小程序之间相互影响。 ## 底层支持 微信小程序开发工具中拥有一些编译支持模板以及小程序底层支持文件。 * `transWxmlToJs`: `wxml`转`js` * `transWxssToCss`: `wxss`转`css` * `transConfigToPf`: 模板页配置 * `transWxmlToHtml`: `wxml`转`html` * `transManager`: 管理器 * `WAConsole.js`: 框架`JS`库,控制台能力 * `WAWebview.js`: 框架`JS`库,提供视图层基础的`API`能力,主要功能有将消息通信封装为`JSBridge`消息,日志组件`Reporter`封装,`wx`对象下部分渲染视图方面的`Api`,小程序组件实现和注册,`VirtualDOM`与`diff`和`Render UI`的实现,页面事件触发处理 * `WAService.js`: 框架`JS`库,提供逻辑层基础的`API`能力,主要功能有消息通信封装为`JSBridge`消息,日志组件`Reporter`封装,`wx`对象下面的大部分`Api`方法,`App()`小程序入口,`Page()`页面的入口,`getApp`等全局方法,数据绑定,事件分发,生命周期管理,路由管理,模块化能力等 ## 每日一题 ``` https://github.com/WindrunnerMax/EveryDay ``` ## 参考 ``` https://www.zhihu.com/question/50920642 https://kangzubin.com/wxapp-decompile-1/ https://github.com/berwin/Blog/issues/49 https://segmentfault.com/a/1190000018631528 http://eux.baidu.com/blog/fe/微信小程序架构原理 https://juejin.im/post/5da444ab6fb9a04e054d93d8 https://cloud.tencent.com/developer/article/1029663 ```