应用程序开发公司
软件开发

针对您的项目需求及预算规划量身制定方案

个体/中小企业/集团/政府机构/行业组织 了解详情 了解详情

微信小程序架构分析《二》:view 模块和 service 模块的构成

发布时间:2024-01-01 00:00 浏览次数:26

你可以在app.nw/app/dist/weapp/tpl/pageFrameTpl.js 和app.nw/app/dist/weapp/tpl/appserviceTpl.js 文件内找出页面的模板。


关上微信 web 开发者工具,然后输出 openVendor() 便可以关上 WeappVendor这个目录,这里涵盖了 view 模块和 service 模块采用的几个核心文件:


wcc 可执行程序,用作将 wxml 变为 view 模块采用的 js 代码,采用方式为wcc xxx.wxml


wcsc 可执行程序,用作将 wxss 变为 view 模块采用的 css 代码,采用方式为 wcsc xxx.wxss


WAService.js 提供更多 service 模块大部分功能,下面可以存有详尽了解


WAWebview.js 提供更多 view 模块大部分功能,下面可以存有详尽了解


view 页面揭秘


view 页面的 template 如下:



其中 可以在 dev 模式打开后被替代为一个时间锚点,比如:



可以被 WAWebview.js 内代码替代


之间暂时没被采用至


可以被 wcc 命令分解成后的 js 代码替代


除了上面这些,页面上还可以被填入页面和应用领域的 style 标签,例如:



这里的 wxss 文件涵盖的就是完整 wxss 文件切换后的 css


以及分解成 DOM 的启动脚本:



WAWebview.js 文件中的各个模块(行号为 jsbeautify 之后代码行号,开发者工具版本:092300):


1-77 行: WeixinJSBridge 对象相容层,这个大概只可以在调试时使用,因为研发时和运转时页面都会被后台以转化成的方式嵌入 WeixinJSBridge 这个对象。我们可以通过这段代码看见它曝露的方法: invoke invokeCallbackHandleron publish subscribe subscribe subscribeHandler。


78-235 行:Reporter 对象,它的促进作用就是传送错误和性能统计数据给后台


236-596 行:wx 对象,页面的核心之一,一方面PCB WeixinJSBridge 的 invokeMethod 方位为不易调用的形式(比如 redirectTo, navigateTo等),另一方面PCB WeixinJSBridge 反弹方法,调用者可以采用wx.onAppDataChange(callback) 嵌入数据更改的反弹函数,最后提供更多wx.publishPageEvent 传送页面事件至后台


607-1267 行:wxparser 对象,提供更多 dom 至 wx element 对象之间的态射操作方式,提供更多元素操作方式管理和事件管理功能


1268-1285 行:留言 window 上的 animation 和 transition 有关的动画事件至 exparser


1286-1313 行:下载并留言 WeixinJSBridge 提供更多的全局事件至 exparser


1324-1345 行:留言 window 上的 error 以及各种表单事件至 exparser


1347-3744 行:采用 exparser.registerBehavior 和exparser.registerElement 方法登记注册各种以 wx- 作为标签结尾的元素至 exparser


3744-4498 行:virtual dom 图形算法同时实现,提供更多 diff apply render 等方法,该模块接口基本与 virtual-dom 一致,这里特别的地方是它所 diff 和分解成的并不是原生 DOM,而是各种演示了 DOM USB的 wx element 对象


4599-4510 行:填入预设样式至页面


从页面 data 至 dom 的主要流程如下:


var vtree var rootNode document.addEventListener("generateFuncReady", function(e) { var generateFunc = e.detail.generateFunc; wx.onAppDataChange(function(obj) { // 分拆 data 至现有 data DataStore.setData(obj.data) // 分解成 virtual dom 的 javascript plain object var props = generateFunc(DataStore.getData()) // 第一次图形 if (obj.options.firstRender) { vtree = createVirtualTree(props, true) rootNode = vtree.render() rootNode.replaceDocumentElement(document.body) wx.initReady() } else { var other_vtree = createVirtualTree(props, false) var patches = vtree.diff(other_vtree) patches.apply(rootNode) vtree = other_vtree document.dispatchEvent(new CustomEvent("pageReRender", {})); } }) })


上面的 DataStore 对象提供更多分拆和以获取当前页面 data 对象的功能,其同时实现如下:


var DataStore = (function() { var data = {} return { getData: function() { return data }, setData: function(e) { for (var t in e) { for (var n = (0, parsePath)(t), o = data, a = void 0, s = void 0, c = 0; c < n.length; c++) Number(n[c]) === n[c] && Number(n[c]) % 1 === 0 ? Array.isArray(o) || (a[s] = [], o = a[s]) : "[object Object]" !== Object.prototype.toString.call(o) && (a[s] = {}, o = a[s]), s = n[c], a = o, o = o[n[c]]; a && (a[s] = e[t]) } } } })() // 解析 key 为 data 内对象的路径字符串 function parsePath(e) { for (var t = e.length, n = [], i = "", r = 0, o = !1, a = !1, s = 0; s < t; s++) { var c = e[s]; if ("\\" === c) s + 1 < t && ("." === e[s + 1] || "[" === e[s + 1] || "]" === e[s + 1]) ? (i += e[s + 1], s++) : i += "\\"; else if ("." === c) i && (n.push(i), i = ""); else if ("[" === c) { if (i && (n.push(i), i = ""), 0 === n.length) throw new Error("path can not start with []: " + e); a = !0, o = !1 } else if ("]" === c) { if (!o) throw new Error("must have number in []: " + e); a = !1, n.push(r), r = 0 } else if (a) { if (c < "0" || c > "9") throw new Error("only number 0-9 could inside []: " + e); o = !0, r = 10 * r + c.charCodeAt(0) - 48 } else i += c } if (i && n.push(i), 0 === n.length) throw new Error("path can not be empty"); return n }


可以看见,每次 data 变化之后,小程序就可以已经开始整个页面的 diff patch 过程。


对于原生同时实现的组件, exparser 可以在监控至数据变化后传送对应事件至 WeixinJSBridge。


service 页面揭秘


service 页面可以被被堆叠为以下的样子:



除了布局和开发者撰写的页面、app.js,页面还在读取了 asdebug.js 和 WAService.js 两个文件。


asdebug.js 文件坐落于 nwjs 项目目录下,路径为app/dist/weapp/appservice/asdebug.js。 它涵盖了两个部分,一个就是 WeixinJSBridge 针对 service 模块的同时实现,另一块就是一些便利命令采用的USB, 比如:help() 可以说你一些需用的函数:


该文件只可以在开发者工具内被导入,如果小程序在微信内运转,必须可以由微信底层提供更多 WeixinJSBridge。


WAService 负责管理 service 模块的一些核心逻辑,它涵盖以下部分 (行号为 jsbeautify 之后代码行号,开发者工具版本:092300):


1-78 行: 跟 WAWebview.js 一样的 WeixinJSBridge 相容模块


79-245 行: 跟 WAWebview.js 一样的 Reporter 模块


246-1664 行:比 WAWebview.js 中 wx 功能更为多样 wx USB模块


1665-2304 行:appServiceEngine 模块,提供更多 Page,App,GetApp USB


2305-2360 行: 为 window 对象嵌入 AMD USB require define


现在的 WAService 除了存有很多地方倚赖 window 对象,所以很有可能它在微信中和开发者工具内一样,依然运转于 webview 标签之内。

TAG标签:
阅读推荐