logo

移动 Webview 调试神器 DevTools-Pro

作者:沙与沫2021.07.14 19:30浏览量:1083

简介:本文将简单介绍下 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。
这四部分的交互逻辑如下图所示:
1626088826636.jpg
简单来说:被调试页面引入 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 配置文件进行定义,配置文件有以下几个属性:

  • scripts:模块中包含的 JavaScript 文件数组,这里的路径名称是相对于 module.json 的位置;
  • skip_compilation:类似于脚本,但是 Closure Compiler 不会对这些文件进行类型检查;
  • resources:模块使用的非 JavaScript 文件数组;
  • dependencies:模块使用的其他模块的数组;
  • extensions:具有 type 属性的对象数组。扩展可以通过运行时系统查询,并可以通过任何模块中的代码进行访问。类型包括 “setting”、”view”,”context-menu-item”。例如可以按如下方式注册出现在设置屏幕中的设置:
    {
    "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 和拦截:
1626262009097.jpg

Backend
当被调试的页面引入 hostname:port/backend.js 时,backend 的文件会被合并到 backend.js 中输出。这里提供了全局命名空间 $devtools,它的定义在./src/runtime.js 中。下面通信部分会详细介绍。

通信

在原来的 CDP 基础上,为了方便插件开发,DevTools-Pro 提供了两种 Backend 和 Frontend 插件的通信方式:CDP 事件和自建 WebSocket。

相关文章推荐

发表评论