开工福利|免费学 2200+ 精品线上课,企业成员人人可得! 了解详情
写点什么

实现微信小程序编译和运行环境系列 (核心篇三)

  • 2020-06-22
  • 本文字数:3690 字

    阅读完需:约 12 分钟

实现微信小程序编译和运行环境系列(核心篇三)

本章节就带大家通过微信官方的创建项目部分代码来讲解一下这些对外 api 如何通过我们自己方式来实现和微信相同的功能操作,我们通过微信开发者工具来自动创建一个默认的小程序项目 一个首页和日志页。



这个项目大家应该都比较熟悉吧,应该第一次接触小程序开始时引入眼前的场景,具体的其他内容我们就不在这里啰嗦了,直接看下它的 app.js 文件,编辑器打开后可以看到里面写了这些.


 //app.jsApp({  onLaunch: function () {    // 展示本地存储能力    var logs = wx.getStorageSync('logs') || []    logs.unshift(Date.now())    wx.setStorageSync('logs', logs)
// 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, unionId } }) // 获取用户信息 wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 wx.getUserInfo({ success: res => { } }) } } }) }, globalData: { userInfo: null }})
复制代码


先给大家把接下来部分要说明的消息事件整理出来让大家可以看的清楚一些,后面的内容主要是围绕这个消息事件和代码来说明



上面这个图就是从微信开发者工具里面打开页面时候出现的事件和消息类型以及有关数据,分析一下可以看出:


1、首先调用了同步 api getSystemInfo,我们可以看到在我们的项目代码里面没有存在这个 api,但是开发者工具第一步就调用了,所以在项目编译初始化的时候就触发了,至于 Receive 的数据返回的就是工具界面左上角的一些配置数据,大家可以打开自己的开发者工具看看,一些参数是你可以直接从上面观察到的,如手机型号 屏幕占比 网络类型等,这个同步 api 是系统自动调用的不用我们做写什么操作,而且它会比较频繁的调用。(这点我也没理解,当我打开控制台的时候他会调用很多次)


  • 在前面的文章中讲到同步的 api 都是通过走 http 协议’/apihelper/assdk’链接过来的,里面携带了 api 名和一些参数,所以我们可以直接拦截’/apihelper/assdk’请求进行处理


实例代码展示


     router.post('/apihelper/assdk', async (ctx, next) => {    const { api, args } = JSON.parse(ctx.request.body);    if (api === 'getSystemInfo') {      ctx.body = {        'errMsg': 'getSystemInfo:ok',        'model': 'iPhone 7 Plus',        'pixelRatio': 3,        'windowWidth': 414,        'windowHeight': 624,        'system': 'iOS 10.0.1',        'language': 'en',        'version': '7.0.4',        'screenWidth': 414,        'screenHeight': 736,        'SDKVersion': '2.7.1',        'brand': 'devtools',        'fontSizeSetting': 16,        'benchmarkLevel': 1,        'batteryLevel': 100,        'statusBarHeight': 20,        'safeArea': { 'right': 414, 'bottom': 736, 'left': 0, 'top': 20, 'width': 414, 'height': 716 }      };    }    })
复制代码


ctx.body 的结果集可以直接复制开发者工具中的数据就可以,如果要实际使用的话需要把部分参数改成动态获取的。


2、当代码执行 wx.getStorageSync(‘logs’) wx.setStorageSync(‘logs’, logs)的时候(标签二)通过前面的日志描述可以知道它们都是 appservice sdk 调用的同步的 api,就是我们普通使用的 Storage 它们包装做了一层转换,因为这个页面是初始化的时候调用的所以这里面的数据都是空的。当点击 log 页面的时候,就可以看到调用了 APPSERVICE_PUBLISH 事件类型,此类型是 view 层发给 service 层的我们看到它的 webviewID 存在值。



看出 data 里面的数据就是 Storage 存储的 Date.now()时间, wx.setStorageSync wx.getStorageSync 在源码对应的地方。




var r = re.IS_IOS ? "setStorage" : "setStorageSync"var r = re.IS_IOS ? "getStorage" : "getStorageSync"
复制代码


看出如果是 ios 的话就只能调用 setStorage getStorage 方式。


模拟代码展示:


const storage = new Map();
const getStorage = function (key) { return storage.get(key);};const setStorage = function (key, value) { storage.set(key, value);};const removeStorage = function (key) { storage.delete(key);};
module.exports = { getStorage, setStorage, removeStorage};
复制代码


如果想模拟全局的存储简单的可以直接使用 map 进行操作,然后在调用的时候获取对应的 api 进行获取和设置操作,完善的话存储可以采用浏览器的 LocalStorage,SessionStorage 或者一些 npm 包进行处理。


3、我们比较常用的一个 api 通过 wx.login 换取 code 可以看出(标签三)中,是通过逻辑层 service 自发自收的,发起一个请求通过 service 逻辑层处理后在回调回去,通过微信 api 源码可以看到调用的地方



这一块要想要弄的很好不是很容易,涉及到用户体系就要和服务端彻底打通,好在登录授权这块微信也是采用 OAuth2 协议实现的


如果有朋友对 OAuth2 还不是很了解明白的话,建议看下这个文档比市面上 90%的相关内容讲的更彻底通透。


4、当在小程序中打开页面时触发了 onAppRoute 事件,通过日志看出发送了 APPSERVICE_ON_EVENT 事件,path 表示当前页面,openType 表示操作类型,openType 如果不是很明显的话我们试着点击一下,从日志页面返回首页的后退操作。



看到"openType":"navigateBack"这个应该比较好理解解释了。


到这里我们会有一些不一样的地方了,因为这里的操作的是事件处理不是简单的 api 处理就 ok 了,所有前端页面操作的控制器都是一个整体,首先我们要先搭建这个载体容器存放各个部分。


模拟代码实例:


构建一个总管理处理的信息


constructor(wxConfig = {}, socketPort) {    super();    this.wxConfig = wxConfig;    this.systemManager = new SystemManager(this, wxConfig);    this.navigatorManager = new NavigatorManager(this, wxConfig);    this.pageManager = new PageManager(wxConfig, socketPort);    this.tabbarManager = new TabbarManager(this, wxConfig);    this._render();    this._launch();    window.socketClient.setEmitter(this);  }
复制代码


然后 render 页面信息,结合 node 后台服务渲染前端展示


    this.domElement = document.createElement('div');    this.domElement.id = 'container';    this.domElement.style = ` height: ${global.simulator.height}px; width: ${global.simulator.width}px;`    // system    this.domElement.appendChild(this.systemManager.domElement);    // navigator    this.domElement.appendChild(this.navigatorManager.domElement);    // pages    this.domElement.appendChild(this.pageManager.domElement);    // tabbar    this.domElement.appendChild(this.tabbarManager.domElement);
复制代码


后面就是监听各个事件控制和各种业务处理,核心还是要按照开发者工具的消息顺序和内容来实现。


例如上面我们提到的 navigateBack 我们自己这边实现按照平常的业务写法就 ok。


  navigateBack (path, query) {    let currentWebview = this.domElement.children.item(0);    let currentIndex = currentWebview.style['z-index'];    this.domElement.removeChild(currentWebview);
let targetPage = null; for (let i = 0; i < this.domElement.children.length; i++) { let webview = this.domElement.children.item(i); if (webview.style['z-index'] === `${currentIndex - 1}`) {
let viewId = +webview.getAttribute('data-view-id'); let path = webview.getAttribute('data-view-path'); let query = JSON.parse(webview.getAttribute('data-view-query')); window.socketClient.send(WebsocketMessage.onAppRoute(viewId, path, query, 'navigateBack')); window.socketClient.send(WebsocketMessage.onAppRouteDone(viewId, path, query, 'navigateBack')); targetPage = path; break; } } return targetPage; }
复制代码


重要的还是 socketClient.send 消息的正确传递才可以和基础库正确的交互


其他的很多对外的 api 实现方式都是大同小异,主要是在接收到消息后怎么处理设计


我们知道了核心的流程,下面要做的就是模仿设计,模仿它的消息格式和返回结构,设计自己的各系统模块的关联


对于小游戏而言大致是一样的,主要有几个点不同:


  1. 小游戏是通过根目录下的 game.json 来对小游戏进行全局配置,决定相关界面渲染和属性设置等;

  2. 在小游戏的运行环境里面不存在 BOM 和 DOM API,只有 wx API 对它们进行了包装,所以无法直接使用;

  3. 小游戏的运行层只有一层在 view 里面跑;

  4. 小游戏的大部分 api 主要都是对文件系统和网络的处理。


上面的一些总结主要是根据一些 api 的实现来描述扩展了一些,看完后希望大家对此有所了解,后面我打算从全局来讲下怎么从代码设计方面来设计整个浏览器运行环境实现方案。


2020-06-22 11:081926

评论

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

打字大师3-盲打实践Mac破解版下载 快速提高您的打字速度!

Rose

盲打练习 Mac软件 打字大师 Master of Typing 3 打字训练

C# 布尔值和条件语句:入门指南和实用示例

小万哥

C# 程序人生 编程语言 软件工程 后端开发

2024年数字安全呈现九大趋势,AI大模型正在重构安全

Geek_2d6073

《Java核心技术·卷 II(原书第11版):高级特性》PDF

程序员李木子

WorkPlus Meet私有化视频会议软件-构建安全高效的内网会议体验

BeeWorks

WorkPlus AI助理私有化部署,助力企业降本增效

BeeWorks

sqlpro studio mac破解版-苹果电脑可视化数据库管理工具下载

Rose

数据库管理软件 Mac破解软件 SQLPro Studio

在本机累积指标的思路

WorkPlus:构建高效协作的企业即时通讯解决方案

BeeWorks

超好用的终端SSH连接工具Termius mac破解版(含Termius使用教程)

Rose

SSH Mac软件 Termius Termius for Mac破解 SFTP客户端

MG运动图形动画脚本Motion中文汉化版 AE插件资源

Rose

AE插件 Motion 3下载 Motion中文版

苹果电脑WiFi信号质量检测工具:WiFi Signal Strength Explorer for Mac

Rose

无线网络 Mac软件 苹果电脑 WiFi Signal Strength WiFi信号强度

数据库管理:Navicat Premium 16 安装教程附激活工具(亲测可用)

Rose

数据库管理 Navicat Premium激活版 Navicat Premium 16 Navicat Premium 中文版

【线上问题】CompletableFuture与线程池使用不当导致服务整个挂掉

Disaster

WorkPlus打造高效沟通的局域网聊天工具,助力企业内部协作

BeeWorks

Beyond Compare 4的其他文件格式如何导入?

Rose

一文详解 Berachain 测试网:全面介绍与教程,bitget wallet教程

股市老人

【深入浅出JVM原理及调优】「搭建理论知识框架」全方位带你深度剖析Java线程转储分析的开发指南

洛神灬殇

Java JVM 虚拟机 jni 2024年第十七篇文章

《图解设计模式》PDF

程序员李木子

通过 DBeaver 连接 CnosDB

CnosDB

开源 时序数据库 tsdb CnosDB

WorkPlus即时通信IM工具,助力企业高效沟通与协作

BeeWorks

WorkPlus内网通信软件的首选,助力企业实现高效内部沟通与协同

BeeWorks

Mac版思维导图:XMind设置快捷键教程

Rose

思维导图 Mac软件 XMind教程 XMind下载

苹果电脑软件:mac上您不能错过的音频处理工具大合集~

Rose

音乐制作 Mac软件 苹果电脑 音频处理工具

独家好书丨《智算时代的容器技术演进与实践》免费下载

阿里巴巴云原生

阿里云 容器 云原生

实现微信小程序编译和运行环境系列(核心篇三)_语言 & 开发_风逝_InfoQ精选文章