San DevTools 技术解析(上)
2021.01.05 00:18浏览量:312简介:这是《San DevTools 技术解析》第一篇文章,重点介绍下 San DevTools 的主要功能、整体架构和重要的模块概念。
前言
今天我们带来《San DevTools 技术解析》上、中、下三篇系列话题,带大家深入理解 DevTools 底层原理,通过关键技术的讲解,理解 DevTools 底层设计原理,理解 San 与 DevTools 如何通信?Standalone 版本如何调试多种场景?WebSocket 通信如何实现?Chrome 插件应用到哪些技术?远程调试如何实现?调试协议有哪些有意思的应用场景等等。
San DevTools
整体涉及的技术点较多,希望通过本文大家能够理解掌握关键技术与设计。
这是《San DevTools 技术解析》第一篇文章,重点介绍下 San DevTools 的主要功能、整体架构和重要的模块概念。
PS:在 San DevTools 中我们集成了 Chrome DevTools,可以实现远程调试 Webview 页面,即使不是 San 用户,也可以使用该工具远程调试手机 / 模拟器中的页面,并且不需要安装 inspect 内核。是时候替换 vconsole 之类的调试工具了,来试试我们的 Chrome DevTools 远程调试吧!
整体介绍
功能简介
San DevTools
以两种方式存在:
-
通过 Chrome 插件商店 获取插件版本,具体参考使用文档;
-
通过 Npm 安装独立的 Standalone 版本,增强远程调试功能, 集成 Chrome Devtools 的远程调试功能,方便的调试移动端页面,一般推荐使用;
Standalone 版本支持两种调试模式,如下视频演示:
-
针对 San 应用的远程调试模式;
-
适用任何环境的 Chrome 远程调试模式,支持移动端 H5、IE、Safari 等环境;
核心概念
San DevTools
是支持 San 应用开发的调试工具。
为了方便大家理解其中的概念,我们先思考如下的问题:
如何从零设计 & 实现一款远程调试工具?实现查看组件树功能。
首先,我们应该能想到需要有两个模块,一个是调试的工具,一个是被调试的目标页面。按照远程调试工具的传统,站在开发工具的角度,把工具页面叫做 Frontend
,被调试的目标页面叫做 Backend
,和传统前后端开发概念有点类似。
其次,前后端的通信问题要先考虑,如何设计方便前后端模块发送事件呢?参考前端与 NA 端桥接 Bridge
的概念,设计了 Bridge 实例,各模块内部通过实例方便地发送事件。
// Server
import WebSocket from 'ws';
const wss = new WebSocket.Server({port: 8080});
wss.on('connection', ws => {
const bridge = new Bridge({
listen(fn) {
ws.on('message', fn);
},
send(data: any) {
ws.send(data);
}
});
});
io.listen(8080);
// Backend/Frontend Bridge
const wss = new WebSocket('wss://localhost:8080');
const bridge = new Bridge({
listen(fn) {
wss.onmessage = fn;
},
send(data: any) {
wss.send(data);
}
});
再次我们思考几个问题:
-
前后端可不可以直接通信?
-
收集、计算 Backend 页面数据的模块如何设计?
-
格式要不要规范(类似 RESTFul 格式)?
对这几个问题分别进行分析:
-
通信协议大家直观能想到要用 WebSocket 技术,前后端其实都是跑在浏览器里的页面,显然不能直接通信,需要服务端做中间联接;
-
收集数据的模块需要监听、操作页面的 JS/Dom 等,这里用了非常形象的
Hook
概念与模块;计算处理数据的工作会比较多,比如组件树数据的计算生成,组件路径数据等等,这部分主要工作是代理Frontend
与Backend
之间数据的交互处理,所以有了Agent
模块; -
传统前后端开发会有 RestFul 风格接口、接口规范文档等,我们的
Backend
与Frontend
同样需要一定的规范,这就是Remote Debugging Protocol
协议规范,为了实现交互的标准规范; -
在服务端需要建立对应的前后端消息联接,叫做
Message Channle
消息通道,或更形象点叫房间
,消息不可以在不同房间内『串门』,保证消息的准确性;
![](https://developer-forum-online.cdn.bcebos.com/e719ed1f-21e8-480b-8c2b-2a5e01be5a81.png)
总结:通过本节的介绍我们明白了远程开发调试必备的四大核心模块:
-
Frontend:调试工具前端,在
Chrome DevTools
里包括我们经常看到的 Elements、Console、Network、Source 等面板;在San DevTools
我们实现了 Component、History、Store、Event、Message 等面板; -
Backend:调试器后端,注入到运行中的页面,从调试工具的角度看属于
Backend
(稍注意下概念,和传统前端理解不太一致); -
Protocol:调试协议,连接 Frontend 与 Backend 的交互协议,通过定义方法和事件提供双方的交互,包括相应的 JSON 数据格式;
-
Message Channel:消息通道,为实现 Frontend 与 Backend 的通信设计,包括 WebSocket Channel,Chrome Embedder Channel,Chrome Extensions Channel;
除四大核心概念外,为实现相应的功能引入三个概念与模块:
-
Bridge
:类似于前端与 NA 端建立的桥接,方便前后端发送消息通信; -
Hook
:目标页面勾子,与调试的页面深入结合,可操作目标页面的 JS/DOM,并监听发出来的事件比如组件生命周期事件,主要功能是收集页面数据; -
Agent
:目标页面的数据处理模块,数据来源为 HOOK 收集的数据或者通过 Bridge 接收到的数据,处理之后的数据会通过 Bridge 发送出去抑或存储在目标页面。
架构 & 流程
下面是 San DevTools 的整体架构图
整体流程如下图所示
Frontend & Backend
Frontend
与 Backend
有较多的交互流程,我们把这两个模块放在一起来说。
在不同的流程阶段,有不同的关键技术实现,我们分两个阶段进行说明。
初使化阶段
-
Chrome 插件与 Standalone 版本,入口方面不同,Chrome 插件通过配置
manifest.json
实现入口,技术详情请参考本文的后续章节; -
Standalone 版本会启动一个 Node 服务,提供 JS 文件,需要注入 JS 到调试的页面,实现页面数据的收集计算;
-
Hook
注入并劫持全局变量__san_devtool__
,所有和 San 框架相关的交互都是通过这个变量,比如 San 版本号等;具体可以直接通过控制台打印变量;
联接的建立:
-
两次握手协议事件的发送,最终确认联接建立成功;
-
核心是建立两个 Bridge 桥接实例;
-
前后端的联接建立使用的是 WebSocket 或 Chrome Runtime 的长联接;
Standalone 功能更强大,支持任意页面的远程调试能力,与业界同类工具相比更优,比如 VConsole、Weinre 等:
-
基于 Chrome DevTools Frontend 作为前端的调试面板,更符合前端同学的调试习惯,功能也更强大;
-
适用于各种浏览器环境,比如移动端 H5 页面、IE、Safari、Native 等等;
其他节点阶段
-
DevTools 需要加载开发版 San (san.dev.js),才能支持调试工具;
-
San 通过 DevTools 注入的全局变量发送生命周期数据(其他数据也一样);
-
组件树数据的生成是通过组件 attach 事件,在 Backend 页面记录并生成;同理大部分的数据收集与计算是在 Backend 实现的。
发表评论
登录后可评论,请前往 登录 或 注册