首页
/ Puppeteer Browser.uninstallPWA 详解:PWA 卸载 API 的签名、参数与 CDP 实现剖析

Puppeteer Browser.uninstallPWA 详解:PWA 卸载 API 的签名、参数与 CDP 实现剖析

2026-09-07 17:37:15作者:苗圣禹Peter

Puppeteer 为 Chromium 提供了完整的 PWA(Progressive Web App)生命周期管理 API,其中 Browser.uninstallPWA() 用于卸载此前通过 Browser.installPWA() 安装的 PWA。本文基于当前仓库的 API 文档与源码,完整讲解该方法的签名、UninstallPWAOptions 参数、pipe 连接限制与网络限制等前提条件,并深入 CDP 实现层剖析 PWA.uninstall 的调用链,帮助你在自动化测试中可靠地完成 PWA 的“安装—启动—校验—卸载”闭环。

API 签名与用途

Browser.uninstallPWA()Browser 类的抽象方法(abstract method),用于卸载一个之前已安装的 Progressive Web App。其 TypeScript 签名定义如下(见 docs/api/puppeteer.browser.uninstallpwa.md):

class Browser {
  abstract uninstallPWA(options: UninstallPWAOptions): Promise<void>;
}
  • 返回类型Promise<void>。Promise resolve 表示卸载命令已发送到浏览器端并执行完成,没有任何回传数据。
  • 对应源码声明:抽象声明位于 packages/puppeteer-core/src/api/Browser.ts,其 TSDoc 注释明确标注了限制条件——“Only available over a pipe connection. See Browser.installPWA”,这与 API 文档中的 Remarks 一节完全一致。

参数说明:UninstallPWAOptions

该方法接收唯一参数 options,类型为 UninstallPWAOptions 接口(文档见 docs/api/puppeteer.uninstallpwaoptions.md)。该接口在当前仓库中的源码定义为:

// packages/puppeteer-core/src/api/Browser.ts
/**
 * Options for {@link Browser.uninstallPWA}.
 *
 * @public
 */
export interface UninstallPWAOptions {
  /**
   * The id from the web app's manifest file.
   */
  manifestId: string;
}
参数 类型 说明
options UninstallPWAOptions 卸载选项,目前仅含一个字段
options.manifestId string(必填) 来自 Web App manifest 文件的 id,通常就是安装该 Web App 时传入的站点 URL

manifestId 是整个 PWA 系列 API 的统一标识键。Puppeteer 的 installPWAlaunchPWAgetPWAStateuninstallPWA 都以它定位目标应用。因此实践中最常见的取法有两种:

  1. 直接复用 Browser.installPWA(options) 的返回值——该方法会回传 InstallPWAOptions.manifestId(从 packages/puppeteer-core/src/cdp/Browser.ts 的实现可见,其最后一行即为 return options.manifestId);
  2. 调用 Browser.getPWAState() 查询已安装应用的 id 字段。

使用前提与限制条件

API 文档 Remarks 部分只写了一句话,但结合源码可以把它展开为三条具体的硬性约束:

  1. 仅支持 pipe 连接(Chromium/CDP 专属) 文档 Remarks 原文为:“Only available over a pipe connection. See Browser.installPWA()。”从源码结构看,uninstallPWA 的 CDP 实现走的是浏览器级 CDP 会话,而 BiDi 实现类 packages/puppeteer-core/src/bidi/Browser.ts 中同样 override 了 installPWA/uninstallPWA(结合 CDP 侧可用的完整实现推断,BiDi 侧并不具备等价的 PWA 域命令)。因此该方法主要面向通过 puppeteer.launch() 本地启动(默认 pipe 传输)的 Chromium 浏览器;通过 browserWSEndpoint 建立的 WebSocket 远程连接不满足 pipe 条件。

  2. 不支持配置了网络限制的浏览器实例 packages/puppeteer-core/src/cdp/Browser.tsuninstallPWA 的实现开头有一个前置检查:

    override async uninstallPWA(options: UninstallPWAOptions): Promise<void> {
      if (this.#hasNetworkRestrictions) {
        throw new Error(
          'PWA APIs are not supported when network restrictions are configured.',
        );
      }
      await this.#connection.send('PWA.uninstall', {
        manifestId: options.manifestId,
      });
    }
    

    即如果 Browser 实例上配置了 network restrictions,调用 PWA 系列 API(包括 uninstallPWA)会直接抛出 PWA APIs are not supported when network restrictions are configured. 错误。同一文件中的 installPWAlaunchPWA 也有完全相同的守卫逻辑。

  3. 仅限 Chromium 从测试布局看,PWA 相关用例全部位于 CDP 专属目录 test/src/cdp/pwa.test.ts 中(Puppeteer 的测试按 CDP 与 BiDi 两大协议分目录组织),Firefox/BiDi 侧没有对应测试,说明这是一项 Chromium 独有能力。

源码实现剖析:uninstallPWA 到底做了什么

CDP 后端实现的完整逻辑非常简洁(packages/puppeteer-core/src/cdp/Browser.ts):

override async uninstallPWA(options: UninstallPWAOptions): Promise<void> {
  if (this.#hasNetworkRestrictions) {
    throw new Error(
      'PWA APIs are not supported when network restrictions are configured.',
    );
  }
  await this.#connection.send('PWA.uninstall', {
    manifestId: options.manifestId,
  });
}

要点解析:

  • 单命令调用链:整个方法只做一件事——通过 #connection(浏览器级 CDP 连接)发送一条 PWA.uninstall 命令,参数仅含 manifestId。没有重试、没有本地状态维护,卸载的副作用完全由 Chromium 端的 PWA 域完成。
  • 与 installPWA 的不对称性:对比同文件的 installPWAL542-L559),后者发送 PWA.install 之后,如果调用方指定了 displayMode,还会追加一条 PWA.changeAppUserSettings 命令来覆盖 Chromium 的默认 display mode(browser)。而 uninstallPWA 没有任何附加命令,Promise<void> 的返回也印证了它是纯“命令式”操作。
  • manifestId 的回显设计installPWA 的 TSDoc(packages/puppeteer-core/src/api/Browser.ts)说明返回的 manifest id 会原样回显 InstallPWAOptions.manifestId,可继续用于 getPWAStateuninstallPWA——这为“先装后卸”的测试脚本提供了确定的关联键。

实战示例:PWA 生命周期完整闭环

下面是一个典型的端到端示例,展示 installPWAlaunchPWAuninstallPWA 的完整用法(puppeteer.launch() 默认使用 pipe 连接,满足前提条件):

import puppeteer from 'puppeteer';

// pipe 连接(launch 的默认传输方式)
const browser = await puppeteer.launch();

const manifestId = 'https://example.com';

// 1. 安装 PWA(可指定 displayMode,安装后以独立窗口打开)
const installedId = await browser.installPWA({
  manifestId,
  installUrlOrBundleUrl: 'https://example.com/',
  displayMode: 'standalone',
});
// installedId 会回显 manifestId

// 2. 启动已安装的 PWA,拿到 Page 实例做断言
const page = await browser.launchPWA({manifestId: installedId});
await page.bringToFront();
// ... 在此执行功能验证 ...
await page.close();

// 3. 验证 PWA 状态(getPWAState 同为 pipe 连接专属 API)
// 4. 卸载 PWA
await browser.uninstallPWA({manifestId: installedId});

await browser.close();

配套的 API 文档还包括:

在测试侧,Puppeteer 为整套 PWA API 提供了专门的 CDP 测试套件 test/src/cdp/pwa.test.ts,覆盖了安装、启动、状态查询与卸载的组合场景;另有 test/src/cdp/network_restrictions.test.ts 验证了“配置网络限制时 PWA API 抛错”这一守卫行为,与上文源码分析互相印证。

小结

  • Browser.uninstallPWA(options) 是卸载已安装 PWA 的唯一入口,参数仅一个必填的 manifestId,返回 Promise<void>
  • 三项前提必须同时满足:Chromium + pipe 连接(如 puppeteer.launch() 本地启动)+ 未配置网络限制的浏览器实例。
  • 实现层面它就是一条 PWA.uninstall CDP 命令的薄封装,行为简单、可预测,适合作为 PWA 自动化测试夹具(fixture)中的清理步骤,与 installPWAlaunchPWAgetPWAState 配合构成完整的 PWA 生命周期管理。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388