简介:本文将简单介绍下 DevTools-Pro 的使用,重点介绍下实现原理和如何打造一个属于自己的移动端
本文将简单介绍下 DevTools-Pro 的使用,重点介绍下实现原理和如何打造一个属于自己的移动端调试神器,以及如何利用 DevTools-Pro 实现页面的自动化测试。
在移动开发中,对于 Webview 的 H5 页面调试是很麻烦的,即使有了 vconsole 这类工具,也不过是在移动的 Webview 页面中进行调试,而且功能比较单一。而移动端的远程调试,在配置的时候又比较麻烦,而且安卓和 iOS 还不一样,需要单独调试,对于 APP 还需要内核支持,比如微信、百度 APP 这类需要安装对应的 inspector 工具,一顿操作下来,一步没配置好,说不定还不能用。
对于习惯了 Chrome DevTools 的朋友,还是喜欢 Chrome DevTools 的强大功能和体验。
有没有一个工具,可以在移动的 webview 上不受限于系统和 APP,直接实现 Webview 的远程调试,而且体验上跟 Chrome DevTools 一样呢?
DevTools-Pro 就是这么一个移动端 Webview 调试神器!DevTools-Pro 是基于 Chrome DevTools 项目进行开发的,利用 WebSocket 实现远程通信连接,支持自编写插件和面板,实现更加强大的功能。
我们可以通过下面的方式进行安装:
npm i -g devtools-pro
# OR
yarn global add devtools-pro
基本的使用方法是:
devtools-pro -h
# or
dp -h
Options:
-h, --help Show help [boolean]
--plugins Add plugins [array]
--config Provide path to a devtools configuration file e.g.
./devtools.config.js [string] [default: "devtools.config"]
-o, --open Open browser when server start [boolean] [default: true]
--https Use HTTPS protocol. [boolean]
-p, --port Port to use [8899] [number]
--verbose Displays verbose logging [boolean] [default: false]
--hostname Address to use [0.0.0.0] [string]
-v, --version Show version number [boolean]
配置文件 devtools.config.js
为了方便项目统一配置,DevTools-Pro 支持配置文件,可以在项目中创建一个名为 devtools.config.js 的文件,支持的配置项如下:
logLevel:日志级别,支持 silent verbose
port:server 端口号,默认 8899
hostname:默认 0.0.0.0
plugins:配置插件,下面介绍
https:server 默认是 http 的,如果要启用 https,可以设置 https=true,或者按照 nodejs/https 模块相关配置来配置 https,例如:
https:{
key: fs.readFileSync('/path/to/server.key'),
cert: fs.readFileSync('/path/to/server.crt'),
ca: fs.readFileSync('/path/to/ca.pem'),
}
DevTools-Pro 是基于 chrome-devtools-frontend[1] 进行开发的,通过自建 WebSocket 通道实现 Frontend 和 Backend 的通信。
DevTools 主要由四部分组成:
Frontend:调试器前端,默认由 Chromium 内核层集成,DevTools Frontend 是一个 Web 应用程序;
Backend:调试器后端,Chromium、V8 或 Node.js;在这里我们主要是引入的 backend.js
Protocol:调试协议,调试器前端和后端使用此协议通信。它分为代表被检查实体的语义方面的域。每个域定义类型、命令(从前端发送到后端的消息)和事件(从后端发送到前端的消息)。该协议基于 json rpc 2.0 运行;
Message Channels:消息通道,消息通道是在后端和前端之间发送协议消息的一种方式。包括:Embedder Channel、WebSocket Channel、Chrome Extensions Channel、USB/ADB Channel。
这四部分的交互逻辑如下图所示:
简单来说:被调试页面引入 Backend 后,会跟 Frontend 建立连接;在 backend 中,对于一些 JavaScript API 或者 DOM 操作等进行了监听和 mock,从而页面执行对应操作时,会发送消息到 Frontend。同时 Backend 也会监听来自于 Frontend 的消息,收到消息后进行对应处理。
DevTools-Pro 在设计开始我们就设计了插件机制,通过提供的 API 可以添加自己的功能和面板,比如下面的功能可以来实现:
增加 devtools 面板,例如集成 san-devtools、vue-devtools、react-devtools 等到 devtools-Pro 中
主动在页面触发 Chrome DevTools Protocol(后面简称 CDP)[2],接收 / 发送数据,例如将一些特殊的请求或者信息通过 CDP 发送到 devtools frontend 中展示
其他脑洞大开的想法
插件可以发布一个 NPM 包,然后在项目下的 devtools.config.js 中通过 plugins 进行添加,一个 plugins 是一个 NPM 包,由以下三部分组成:
frontend:调试器前端,即 Chrome DevTools 的 module,按照 Chrome-Devtools-Frontend 写法进行定义,也可以使用 iframe 进行嵌入
backend:调试器后端,即被调试页面的引入的 js 实现
middleware:即 Koa 的中间件,用于增强 server 实现
这三部分根据自己插件的实际功能进行开发,并非都包含。三部分的定义是在 NPM 包的 package.json 中 devtools 字段,类似:
{
name: 'js-native-monitor',
version: '1.0.0',
main: 'index.js',
// ....
devtools: {
// frontend
frontend: {
name: 'jsna_monitor',
type: '', // remote/autostart
dir: 'frontend'
},
// backend字段,该文件内容会被merge到backend.js中
backend: 'index.js',
// middleware
middleware: 'middleware.js'
}
}
下面来详细介绍下 frontend、backend 和 middleware 具体实现。
Frontend
Frontend 是完全符合的 chrome-devtools-frontend 的模块,package.json 中的 devtools.frontend 包含配置有:
name:名字,访问 hostname:port/devtools/${name}/** 则自动转发到这里,优先级高于内置和 chrome-devtools-frontend/front_end 文件,如果 name 是 chrome-devtools-frontend/front_end 已经存在的则优先级高于 chrome-devtools-frontend;
type:可选值:autostart 和 remote,含义参考 Chrome DevTools 具体实现;
dir:指定文件夹目录
dir 文件夹中的重要文件是模块描述文件 module.json,通过文件夹下的 module.json 配置文件进行定义,配置文件有以下几个属性:
{
"extensions": [
{
"type": "setting",
"settingName": "interdimensionalWarpEnabled",
"settingType": "boolean",
"defaultValue": false,
"storageType": "session",
"title": "Show web pages from other dimensions"
},
...
]
}
DevTools Frontend 通过 Module 和 Extension 机制为 Application 增加了 “插件化” 的能力,然后通过配置进行灵活的组装。应用举例
我们应用做多的可能是添加一个面板,例如我要添加一个 js-native 的面板,则 module.json 内容如下:
{
extensions: [
{
// 类型
type: 'view',
// 位置
location: 'panel',
id: 'jsna_monitor',
// 面板显示文字
title: 'jsNative monitor',
order: 110,
// 启动className
className: 'JSNAMonitor.JSNAMonitor'
}
],
// 依赖
dependencies: ['platform', 'ui', 'host', 'components', 'data_grid', 'source_frame', 'sdk'],
scripts: [],
// 资源
modules: ['jsna_monitor.js', 'jsna_monitor-legacy.js', 'JSNAMonitor.js'],
resources: ['jsna.css']
}
此部分可以参考 @ksky521/js-native-monitor[3] 实现。
下面是我们团队自己实现的端能力调试面板,在这个面板可以看到端能力的调用记录和通信事件,同时支持 js-native 描述表的导入导出,以及端能力的 Mock 和拦截:
Backend
当被调试的页面引入 hostname:port/backend.js 时,backend 的文件会被合并到 backend.js 中输出。这里提供了全局命名空间 $devtools,它的定义在./src/runtime.js 中。下面通信部分会详细介绍。
在原来的 CDP 基础上,为了方便插件开发,DevTools-Pro 提供了两种 Backend 和 Frontend 插件的通信方式:CDP 事件和自建 WebSocket。