news 2026/10/12 3:37:10

PageSpy 远程调试平台快速上手:从工作原理到 Node.js / Docker 一键部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PageSpy 远程调试平台快速上手:从工作原理到 Node.js / Docker 一键部署
  • 前端
  • 开发工具
  • 调试器

【免费下载链接】page-spy-web

A remote debugging platform you'll definitely find useful. Lightweight, cross-platform, out-of-box debugging tool

项目地址:https://gitcode.com/gh_mirrors/pa/page-spy-web
点击查看免费下载

本文基于当前仓库中的 README_JA.md(与 README_ZH.md 同源)编写,面向 Web、React Native、小程序、HarmonyOS 等多端项目的开发者,帮助你理解 PageSpy 的远程调试原理、典型适用场景,并掌握 Node.js 与 Docker 两种开箱即用的自托管部署方式。读完本文,你将能够独立完成 PageSpy 服务端的安装、启动、配置与常见问题排查。

PageSpy 是什么:为"本地控制台无能为力"的场景而生

PageSpy是一款用于调试 Web、React Native、小程序、HarmonyOS 应用等跨平台项目的开源远程调试工具。它的核心设计是:对客户端原生 API 做一层封装——当页面调用console、网络请求、本地存储等方法时,SDK 会在方法实际执行前对入参进行过滤与转换,再按统一格式序列化,通过 WebSocket 发送给调试端;调试端收到数据后,以接近本地开发者工具(DevTools)控制台的界面直观呈现出来。

这一"封装原生 API → 序列化 → 实时传输 → 调试端可视化"的链路,正是 PageSpy 与普通日志上报类工具的本质区别:它不是事后看日志,而是把"本地调试的体验"搬到远程。

调试端具备哪些面板能力

从仓库中的官方文档 introduction.zh.mdx 可以看到,PageSpy 在提供调试功能的基础上,扩展出在线实时调试与离线日志回放两大场景,其中在线实时调试包含五个核心面板:

  • Console 面板:显示console.<log | info | warn | error | debug>输出的日志信息,并支持向客户端发送代码、远程执行;
  • Network 面板:显示客户端发出的网络请求信息;
  • Element(Page)面板:显示客户端当前界面,可查看 HTML 节点树;
  • Storage 面板:查看客户端本地的缓存数据(Cookie、LocalStorage 等);
  • System 面板:显示客户端系统信息,辅助排查兼容性问题。

当有新数据产生或数据发生变化时,调试端会实时收到通知。此外,配合 DataHarborPlugin 与 RRWebPlugin 两个插件,还可以实现离线日志回放:像看录像一样重现用户操作轨迹与当时的运行数据(详见 offline-log.zh.mdx)。

源码侧的支撑

从仓库结构看,page-spy-web 同时承载"调试端前端"与"服务端"两个角色:

  • 前端调试界面位于 src/pages/Devtools(Console、Network、Element、Storage、System 各面板),路由定义见 src/routes/config.tsx;
  • 服务端入口位于 backend/main.go:通过embed.FS将构建产物dist内嵌进 Go 二进制,然后调用serve.Run()启动 HTTP 与 WebSocket 服务;
  • 服务端依赖 backend/go.mod 中声明的github.com/HuolalaTech/page-spy-api v1.11.0作为核心运行库。

何时使用 PageSpy:三类典型场景

凡是无法在本地使用控制台调试的场景,都是 PageSpy 可以大显身手的时候。原文档列举了三类典型场景:

  • 本地调试 H5、WebView 应用:移动端屏幕太小,传统调试面板操作不便、显示不友好,且日志容易出现截断;
  • 远程办公、跨地区协同:邮件、电话、视频会议等传统沟通方式效率低,故障信息不完整,容易产生误解或误判;
  • 用户终端白屏等问题排查:数据监控、日志分析等传统手段依赖排障人员对业务和技术的深入理解,在用户设备上收窄问题原因通常很慢。

PageSpy 正是面向存在上述问题的团队而打造,其目标是把调试能力"下沉"到任何一台能打开浏览器的终端上。

快速开始(一):使用 Node.js 部署

为了让数据掌握在自己手中,并降低自建部署门槛,PageSpy 提供了多种开箱即用的部署方式。第一种是全局安装 NPM 包@huolala-tech/page-spy-api:

# 使用 yarn yarn global add @huolala-tech/page-spy-api@latest # 使用 npm npm install -g @huolala-tech/page-spy-api@latest

安装完成后,在终端执行page-spy-api启动服务。服务就绪后,在浏览器中打开http://localhost:6752即可访问调试端。本地验证通过后,可将同一套部署推送到你的服务器。

仓库内的官方安装文档 deploy-with-node.zh.mdx 给出了等价的写法:yarn global add @huolala-tech/page-spy-api@latest && page-spy-api。

从源码看 NPM 包的二进制分发机制

@huolala-tech/page-spy-api并非一个普通的 JS 包,它通过optionalDependencies按平台分发编译好的原生可执行文件。这一点在 package.json 中可见一斑:@huolala-tech/page-spy-api被声明在optionalDependencies中(版本与仓库版本同步为2.4.9)。

具体机制体现在 backend/publish/install.js:

  • 根据process.platform + os.arch() + os.endianness()匹配当前平台,支持win32-arm、win32-arm64、win32-x64(amd64)、darwin-arm64、darwin-x64、linux-arm、linux-arm64、linux-x64等平台组合,分别对应page-spy-api-win32-arm、page-spy-api-linux-amd64等独立子包;
  • 如果用户以--no-optional安装导致平台二进制缺失,安装脚本会先尝试用 npm 安装对应平台包,失败后再直接从 npm registry 下载.tgz并解压出二进制(downloadDirectlyFromNPM);
  • 脚本还针对中文环境做了优化:当LANG以zh_CN开头时,会优先从https://registry.npmmirror.com源安装,失败后自动回退到官方源。

而 backend/publish/page-spy-api.js 则是一个 shim 启动器:它定位到当前平台的二进制路径,然后用execFileSync以继承 stdio 的方式执行真正的二进制,把命令行参数原样透传——这就是全局安装后page-spy-api命令能直接工作的原因。

快速开始(二):使用 Docker 部署

如果你更倾向容器化部署,可以直接拉取官方镜像:

docker run -d --restart=always -v ./log:/app/log -v ./data:/app/data -p 6752:6752 --name="pageSpy" ghcr.io/huolalatech/page-spy-web:latest

逐项拆解这条命令的参数含义:

参数作用
-d后台运行容器
--restart=always容器异常退出后自动重启
-v ./log:/app/log将宿主机./log目录映射到容器的/app/log,持久化日志数据
-v ./data:/app/data将宿主机./data目录映射到容器的/app/data,持久化数据库等数据
-p 6752:6752将容器 6752 端口映射到宿主机 6752 端口
--name="pageSpy"指定容器名称

容器运行后,在浏览器中打开http://localhost:6752。注意:如果容器被销毁,未映射到宿主机的数据也会一并丢失,因此务必保留-v的目录映射(详见 faq.zh.mdx 中关于离线日志持久化的说明)。

从 Dockerfile 看镜像结构

仓库根目录的 Dockerfile 采用两阶段构建:

  1. 构建阶段:基于golang:1.23,先下载backend/go.mod、backend/go.sum声明的依赖,再以CGO_ENABLED=0 GOOS=linux交叉编译出静态二进制main(静态编译意味着镜像无需携带动态库,体积更小、更易分发);
  2. 运行阶段:基于alpine:latest,仅将编译好的/app/main拷入并以/app/main作为启动命令——这与 backend/main.go 中"内嵌 dist 前端产物、单一二进制启动"的设计完全吻合。

因此,Docker 镜像本质上就是"Go 服务端二进制 + 内嵌前端页面"的合体,一个镜像即可提供完整的调试平台。

部署后的服务端配置:config.json

PageSpy 服务端在运行时自动读取当前运行目录下的config.json配置文件。该文件在初次运行时并不存在,你可以根据需要创建或修改它来自定义服务端行为,可配置内容包括:运行端口、多实例部署、跨域配置、日志数据配置、数据库配置等。完整字段说明见 server-configuration.zh.mdx,这里给出带注释的完整示例:

{ // 服务端口 "port": "6752", // 日志回放文件最大大小(MB) "maxLogFileSizeOfMB": 10240, // 日志回放文件最长保存时间(小时) "maxLogLifeTimeOfHour": 720, // 是否允许用户在界面上删除日志 "notAllowedDeleteLog": false, // 最大允许房间数量 "maxRoomNumber": 500, // 跨域配置 "corsConfig": { // 允许的域名 "allowOrigins": ["*"], // 允许的请求头 "allowHeaders": [ "Origin", "Authorization", "Content-Length", "X-Request-Id", "Content-Type", "Referer", "User-Agent", "Host" ], // 允许的请求方法 "allowMethods": [ "HEAD", "POST", "GET", "OPTIONS", "PUT", "DELETE", "UPDATE" ], // 暴露的请求头 "exposeHeaders": ["X-Request-Id"] }, // 符合 S3 协议的存储配置 "storageConfig": { "baseDir": "", "keyId": "", "secret": "", "bucket": "", "region": "", "endpoint": "", // s3ForcePathStyle=false 表示 virtual-hosted-style API(默认情况) // s3ForcePathStyle=true 表示 path-style API "s3ForcePathStyle": false }, // 认证配置 "authConfig": { // 认证密码 "password": "", // JWT 密钥 "jwtSecret": "", // 令牌过期时间(小时) "tokenExpiration": 720 }, // 多实例部署时配置为当前机器 IP 或容器中的 DNS name "selfRpcAddress": { "ip": "", "port": "" }, // 多实例部署配置 "rpcAddress": [ { "ip": "", "port": "" }, { "ip": "", "port": "" } ], // 配置 MySQL 数据库地址,默认使用 SQLite "databaseConfig": { "mysqlUrl": "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" } }

几个值得注意的要点:

  • 存储与数据库:默认使用 SQLite 本地存储(对应依赖见 backend/go.mod 中的modernc.org/sqlite、glebarez/sqlite);配置databaseConfig.mysqlUrl后可切换为 MySQL(对应gorm.io/driver/mysql)。离线日志文件默认保存在运行目录的log目录下。
  • 认证保护:从 2.3.0 版本起,PageSpy 支持通过环境变量为调试端设置访问密码,与authConfig对应的环境变量为AUTH_PASSWORD、JWT_SECRET、JWT_EXPIRATION_HOURS(Token 过期时间,默认 24 小时)。设置密码后,开发者访问调试面板必须输入正确密码。启动方式为:
# Docker 方式 docker run -d --restart=always -v ./log:/app/log -v ./data:/app/data -p 6752:6752 --name="pageSpy" \ -e AUTH_PASSWORD=<password> -e JWT_SECRET=<secret> -e JWT_EXPIRATION_HOURS=<hours> \ ghcr.io/huolalatech/page-spy-web:latest # Node 方式 AUTH_PASSWORD=<password> JWT_SECRET=<secret> JWT_EXPIRATION_HOURS=<hours> page-spy-api
  • 日志容量控制:默认"最多保存最新 10GB、最长 30 天"(即maxLogFileSizeOfMB: 10240与maxLogLifeTimeOfHour: 720),可通过修改配置自定义。

客户端如何接入:以浏览器为例

部署好服务端后,即可在客户端项目中接入 SDK。以浏览器为例(完整说明见 browser.zh.mdx),通过<script>引入时 SDK 会自动从引入路径分析服务端地址:

<!-- PageSpy SDK --> <script crossorigin="anonymous" src="{deployUrl}/page-spy/index.min.js"></script> <!-- 插件(非必须,但建议使用) --> <script crossorigin="anonymous" src="{deployUrl}/plugin/data-harbor/index.min.js"></script> <script crossorigin="anonymous" src="{deployUrl}/plugin/rrweb/index.min.js"></script> <script> window.$harbor = new DataHarborPlugin(); window.$rrweb = new RRWebPlugin(); [window.$harbor, window.$rrweb].forEach(p => { PageSpy.registerPlugin(p) }) window.$pageSpy = new PageSpy(); </script>

其中DataHarborPlugin用于缓存离线日志并提供上传/下载能力(离线回放的基础),RRWebPlugin基于 rrweb 记录用户操作轨迹,两者通常配合使用。小程序(WeChat / Alipay / UniApp / Taro)、React Native、HarmonyOS 也都有对应的 SDK 包与接入流程,分别见 miniprogram.zh.mdx、react-native.zh.mdx、harmony.zh.mdx。

关于实例化参数(如api、clientOrigin、enableSSL、useSecret、gesture、disabledPlugins等)的完整说明,可查阅 pagespy.zh.mdx 中的 PageSpy API 文档。

常见问题与运维要点

  • 服务器上 6752 端口访问不通:检查服务器防火墙或安全组规则是否放行了 6752 端口(参考 faq.zh.mdx)。
  • 调试按钮提示"当前连接不存在客户端":通常意味着 SDK 已创建房间但无法通过 WebSocket 加入,可打开客户端控制台查看是否出现WebSocket connect failed相关报错,据此检查服务端配置。
  • Nginx 反向代理:需要显式开启 WebSocket 升级支持:
location / { proxy_pass http://127.0.0.1:6752; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
  • 部署到子路径:1.5.4 版本起支持子路径部署,除调整 Nginx 的rewrite规则外,实例化时需要手动传参:
window.$pageSpy = new PageSpy({ api: '<host>/<sub-path>', // 例如 api: "example.com/pagespy" clientOrigin: '<scheme>://<host>/<sub-path>', // 例如 https://example.com/pagespy });
  • 升级到最新版本:Docker 方式先docker pull ghcr.io/huolalatech/page-spy-web:latest,再停止并删除旧容器后重新docker run;NPM 方式执行yarn global upgrade @huolala-tech/page-spy-api@latest(或npm install -g @huolala-tech/page-spy-api@latest)后重启进程。
  • 房间生命周期:从服务端实现看,房间在"创建后无 SDK 或调试端进入 1 分钟"、"SDK 与调试端均已断开 1 分钟"、"长时间无数据交互 5 分钟"以及"连接持续超过 1 小时"等条件下会被自动销毁。

参与贡献与延伸阅读

PageSpy 采用 MIT 协议开源(见 LICENSE)。如果你想参与贡献,可以阅读仓库的 CONTRIBUTING_ZH.md(英文版见 CONTRIBUTING.md)。进一步了解模块组成、兼容性、权限认证、插件机制等细节,推荐继续阅读仓库内的官方文档:

  • 常见问题(FAQ)
  • 服务端配置说明
  • 离线日志回放
  • 插件开发指南
  • PageSpy API 文档
  • 前端
  • 开发工具
  • 调试器

【免费下载链接】page-spy-web

A remote debugging platform you'll definitely find useful. Lightweight, cross-platform, out-of-box debugging tool

项目地址:https://gitcode.com/gh_mirrors/pa/page-spy-web
点击查看免费下载

相关推荐

上一篇:Windows安卓应用安装指南:告别笨重模拟器的终极解决方案
下一篇:FoundationDB 8.0 版本发布全解析:API 800、Native CDC 与备份体系重构

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/12 3:36:40

洛谷P2678、P2985、P7913、P9752、P9748五题的题解

这题&#xff01;&#xff01;&#xff01; 得先把题目看清。看清了吗&#xff1f;那我开写了。 首先得把数据处理成我们喜欢的样子&#xff0c;也就是俩石头间的距离。 然后我们可以确定最终答案的范围&#xff0c;也就是0到L。 有点感觉了吗&#xff1f;这就是经典的二分答案…

作者头像 李华
网站建设 2026/10/12 3:35:09

Redis内存淘汰机制深度解析:从近似LRU到生产调优

有一回凌晨两点&#xff0c;我正睡得迷糊&#xff0c;手机突然被项目群里的告警刷屏。Redis内存使用率顶到 100%&#xff0c;业务接口开始大面积报错&#xff0c;数据层的连接池被打满。等我把服务捞回来再看了一眼配置&#xff0c;maxmemory-policy赫然还是默认值noeviction。…

作者头像 李华
网站建设 2026/10/12 3:34:26

别再只记List和Set的区别,它们的共性才是重点

很多人在学习集合框架时&#xff0c;第一反应是“List是有序可重复的&#xff0c;Set是无序不可重复的”&#xff0c;然后就把这两大类集合当作完全对立的两种东西来记。但在实际项目里待久了&#xff0c;我越来越觉得&#xff0c;真正需要先搞清楚的反而是它们的相似性。因为日…

作者头像 李华