@12-apps/pwa

中文文档
2.6.2发布于 2026/09/05MITES Module构建来源已验证近 30 天下载 3.3万

使一个网络应用程序可以安装,并告诉人们: 安装前即时状态机器 + iOS 共享表检测 + 压倒性 pt-BR 复制 (.),安装邀请 (./反应), PER-HOST 显示的端点和被包的网络第一服务wor

中文使用文档
文档目录10 节
  1. 使用量
  2. 是什么使得一个应用程序可以安装(12-23)
  3. 重新装入
  4. 从自己的路径,而不是从枪管中导入手势
  5. reloadApp() 还不完全一样 location.reload()
  6. 手势不会这样
  7. 两个没有分享的平台
  8. IOS 指令是设计工作所在
  9. 诊断
  10. 测试

@12-apps/pwa

让一个网络应用程序可以安装 并告诉人们它.

捕获 beforeinstallprompt 永远不要发射它, 识别iOS 安装为手动共享表动作的浏览器,并发送邀请 这导致的原因 而不是指示。 主机不可知:每个 字符串来自一个压倒性pt-BR消息层.

使用量

import { InstallInvite } from "@12-apps/pwa/react";
import { reportWarning } from "@12-apps/observability-frontend";

<InstallInvite
  what={store.displayName}
  enabled={isStoreOwnDomain}
  onDiagnostic={reportWarning}
/>
条目这是什么
@12-apps/pwauseInstallPrompt, (中文(简体) ), isIosInstallable, (中文(简体) ), isStandalone, (中文(简体) ), isHandheld,信息层, registerServiceWorker 编号 : postToServiceWorker,则 重新装入 一半 - needsPullToRefresh, (中文(简体) ), isInstalledHandheld, (中文(简体) ), reloadApp, (中文(简体) ), createPullTracker
@12-apps/pwa/reactInstallInvite, (中文(简体) ), ShareIcon, (中文(简体) ), PullToRefresh
@12-apps/pwa/servercreateApiPwa({ resolveApp }) ——每个东道主 显示终点 和包装的服务人员 buildWebAppManifest 财务报告和审定财务报表 pwaServiceWorkerSource
@12-apps/pwa/honopwaRouter({ resolveApp }),安装在原生根上. hono 是可选对等点

根项是无框架的,所以一个只需要“这可以 安装的“不会通过它没有要求的枪管拉入反应.

采用.md 收养合同 - 配置表和 5个线圈规则 咬.

是什么使得一个应用程序可以安装(12-23)

以上邀请 询问有两个东西必须先存在 这里的两艘船:

  1. 一份清单,作为一份ENPOINT——从来不是静态文件. 一个PWA的身份是它的 原产地,而捆绑则有一个 index.html 以它所服务的每个佃户发誓, 如此静态 manifest.webmanifest 无法改变的商店 访问者是 看着. resolveApp 返回时 null 是一个404,404是整个 可安装门.
  2. 每一次访问都会有一位重新配置的服务员. registerServiceWorker() 属于 app 启动时, 而不是设置屏幕后: 源主机注册了它 仅来自 enableWebPush(),所以一个访客 谁从来没有打开通知 偏好没有工人——浏览器从未提出安装商店.
const pwa = pwaRouter({ resolveApp: ({ host }) => appForHost(host) });
app.route('/', pwa.router);           // the manifest, at the ORIGIN ROOT
registerServiceWorker();              // in the SPA's entry, once

包装工人是网络第一的文档,这不是 优先选择. 在捆绑的SPA中,每个散列文件名都会随着部署而死 产生了它,一个历史倒转 回答一个消失的块 index.html —— 说 在 MIME 类型上失败的, 到达 React.lazy,使页面变为空白。 A 类 天真的缓存第一工人把旧的外壳钉住,使空白页变得一成不变; 在已安装的应用程序上,“force-refresh”是用户无法遵循的建议.

重新装入

安装应用程序将地址栏取出,再装入按钮—— 在应用程序被焊接时,它就很好:一个旧的外壳 部署、 未注意到页面已过期的会话、 屏幕 获取失败 。 这套文件已经说明了成本,第5条 采用.md数字 : 在安装的应用程序上,“force-refresh”是建议 用户无法跟踪 . 工人修补了可以修补的那一半,没有 用户. PullToRefresh 这是另一半.

import { PullToRefresh } from "@12-apps/pwa/react";
import { PULL_TO_REFRESH_MESSAGES } from "@12-apps/pwa";

<PullToRefresh messages={PULL_TO_REFRESH_MESSAGES["pt-BR"]} onDiagnostic={reportWarning}>
  <App />
</PullToRefresh>

把整个应用包起来 不需要花多少钱因为那里 它什么也没有. needsPullToRefresh() 门是真实的 完全一个组合:

地点有重装吗?为什么
任何浏览器标签对地址栏,加上浏览器本身的超滚动刷新
独立铬(Android)对安装时保持了过度滚动的新鲜度 除非应用程序本身选择退出 overscroll-behavior-y: contain | none
桌面独立对没有地址栏,但是 Ctrl+R 和上下文菜单
iOS 主屏幕没有没有铬,在Safari中重新装入的拉动手势不会重新装入一个独立的网络应用程序. 野外的劳动是 删除图标并再次添加

因此,在默认情况下,手势船 iOS 和其他地方 为: 不安全 但因为一个已经起作用的平台姿态 原生的感觉和杂乱无章,不能被 JavaScript 失败所丢失 .

也用在Android上,通过 platform={isInstalledHandheld}。 。 。 . 这是 支持选择,而不是绕行,移交是干净的而不是 倍数: 正在安装的套件 overscroll-behavior-y: contain,而这正是 将Chromium的过度卷轴刷新。 一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一一 这是你的——两个平台上相同的指标和门槛. 它在安全方向上也失败了: 如果捆绑从未运行, 财产就是 从来没有设定,克洛米姆的姿态仍然在那里.

当你想用一个手势来设计和支持每一个电话时, 或用于Android浏览器,其已安装的应用程序确实 没有 留着那个本地的. 注意你放弃了什么 在Android上 你正在替换一个手势 保持一个你维护.

isInstalledHandheld 故意排除已安装的 DESKTOP 应用程序—— 无地址 栏,但 Ctrl+R,一个上下文菜单,没有触摸屏可以拉起。 端对端 测试驱动桌面浏览器通过 () => true。 。 。 .

从自己的路径,而不是从枪管中导入手势

主机挂载 PullToRefresh 所以无论进口到哪里 它正走着关键的道路. @12-apps/pwa/react 再出口 InstallInvite,以及 @12-apps/pwa 重新导出邀请信件包和 beforeinstallprompt 状态机器,所以从其中之一导入手势 桶将邀请函放入条目的模块图中,然后由捆绑器折叠 进来吧.

这是衡量,而不是理论。 {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}在一个能摆出姿态的东道主 根,安装邀请器从懒惰的块中移出 输入条目块数字 : +9.3 KiB 生 / + 2.4 KiB brotli 首绘代码,只运行于一个上 离职确认屏幕 .

// on the critical path — reaches the gesture and nothing else
import { PullToRefresh } from "@12-apps/pwa/react/pull-to-refresh";
import { PULL_TO_REFRESH_MESSAGES } from "@12-apps/pwa/pull-to-refresh-locales";
import { isInstalledHandheld } from "@12-apps/pwa/reload";

进口邀请的机主机还是正确的,或者说一个 门没有捆绑大小。 三分两分就能走窄路 他们中没有人会改名: platform.ts 持有三个上游 没有反应, pull-to-refresh.{pt-BR,en-US}.ts 拿着手势的复制件 从邀请, 和每一个原 模块再出口什么移动.

reloadApp() 还不完全一样 location.reload()

打开的文档由加载时活跃的工人控制, 而浏览器本身的更新检查比对导航 因此,一旦部署的土地仍能由 即将离任的工人,把用户试图逃跑的外壳还给我. reloadApp() 首先要求更新并等待, 以 2 为边框 (缺省),因为刚刚拉倒的人通常是其 网络今天很不顺 每个失败路径仍然重新装入: 重新装入用户 要求的绝不是应用程序拒绝做的事情.

手势不会这样

3件事情是不能打破的 每件事情都是建筑所阻止的 检查一下有没有人记得:

  • 卷行相传. 头12px旅行是 观看和不消耗 —— 说 preventDefault() 只有追踪者要求手势时才叫它 这对手指向上移动或侧向移动来说 从来都不是.
  • 任何在门户. 听者在组件自己的树下, 所以一个MUI Drawer 或者说 Dialog - 变成 document.body,一个兄弟 内部的一切——无法到达它们.
  • 内作卷轴. 已经向下滚动的列表保持自己的拉力 。 A 类 在标记中 data-pull-refresh="off"。 。 。 .

包装是 display: contents,所以它不会改变布局:孩子会留下来 父公司自己的弹性或网格项目. offsetTop 财务报告和审定财务报表 zIndex 设置指标 在主机固定的铬上方——曝光而不是硬码,因为应用 使用安装邀请器的 联合国 固定放置方式 !important。 。 。 .

两个没有分享的平台

铬 火灾 beforeinstallprompt,它被俘获和 举行 从来没有 自动发射。 一个浏览器让一个页面询问一次,第一个询问一次 访问,在访客知道应用程序是什么之前, 花一个机会在一个 近乎肯定的"否",浏览器随后会长期记忆. 按钮是 访客的.

注意点火 桌面 就像在Android上一样 复制品由 (pointer: coarse) 而不是假设一个电话.

iOS 完全没有 API在任意浏览器中。 非暂时性:没有 beforeinstallprompt 在Safari 26.0-26.6或27β, MDN的相容数据记录 safari: false 与 safari_ios 财务报告和审定财务报表 webview_ios 反映——和 webview_ios 每个iOS浏览器是什么, Chrome 包含 —— WebKit 的 在网络安装 API 上的标准位置(navigator.install)为 反对。 。 。 . 共享工作表的设计.

isIosInstallable() 故意不检查 哪个 浏览器. 不包括 CriOS编号 :FxiOS编号 :EdgiOS 2023年3月之前就已经是了 并且从iOS 16.4开始就有了错误 将“ 添加到家屏幕” 打开至任何带有此功能的浏览器 com.apple.developer.web-browser 权利,所以排除 他们告诉大 iPhone的用户份额完全没有.

IOS 指令是设计工作所在

单塔按钮自行转换. 书面指示必须生存 阅读,理解,然后采取行动 违反控制的人从来没有 刻意地看着——在两秒钟里,他们用闪闪发光的旗帜. 接下来是三件事,每件事物的替换 显而易见的版本出了问题:

  1. 其由由相导. 第一个版本以“ 添加到您的家” 打开 屏幕,并将报酬降为灰色字幕文本. 没有人增加一个网站 因为他们想在家庭屏幕上添加一个网站。 打开 iOS 支付额也是被封门的 —— 网络推力不存在于一个外部 已安装的应用软件——所以“准备好就被告知”是 无 直到他们知道 这个 这是头条.
  2. 取出格来,不是字来. "Tap Share"要求从一个单词翻译 到一个形状. ShareIcon 和浏览器中的染色体相同 所以 没有什么可翻译的。 画入: SF 符号是 Apple 的,并且是 an 图标字体将是一个网络回合,其全部工作是 立即被理解.
  3. 它指出来. Safari的股权控制在 下边 栏和横幅 在页面的顶端 一点也没有. placement="anchored" (单位:千美元) 默认)将卡片修正到控制上方,并瞄准它. placement="inline" 当主机已经放低时选择退出 .

老实说天花板. 这些都没有使iOS安装 不错 苹果公司 不需要API, 转基因在任何地方都很差。 这是一个发现支付, 不是漏斗,值得衡量 而不是假设.

诊断

拒绝出现的邀请失败 安静: 没有扔,所以 破碎的一页看起来很健康. onDiagnostic 被告诉一次每 载荷,载荷为决定表:

字段什麽 false 表示
earlyScriptPresent文档先于内置抓取——部署
earlyEventHeld浏览器从未判断可安装的页面
earlyEventFiredAt 设定但 hasDeferred 虚假藏品未被采纳
installed 编号 : dismissed 真实工作如设计,不是错

测试

pnpm --filter @12-apps/pwa test

版本与发布记录

@12-apps/pwa 共发布 19 个版本,首次发布于 2026/08/08;过去 12 个月发布了 19 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.6.2latest2026/09/052 个月前
2.6.12026/09/042 个月前
2.6.02026/09/042 个月前
2.5.02026/09/042 个月前
2.4.02026/08/252 个月前
2.3.02026/08/252 个月前

关于 @12-apps/pwa 的常见问题

@12-apps/pwa 是什么?

使一个网络应用程序可以安装,并告诉人们: 安装前即时状态机器 + iOS 共享表检测 + 压倒性 pt-BR 复制 (.),安装邀请 (./反应), PER-HOST 显示的端点和被包的网络第一服务wor

如何安装 @12-apps/pwa?

在项目目录运行 npm install @12-apps/pwa,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(>=19.0.0)、react-dom(>=19.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@12-apps/pwa 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/12-apps__pwa 是否存在。

@12-apps/pwa 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@12-apps/pwa 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@12-apps/pwa 可以商用吗?

@12-apps/pwa 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@12-apps/pwa 的下载量有多少?

根据 npm 官方下载统计,@12-apps/pwa 在 2026/10/04 – 2026/11/02 这 30 天内被下载 32,584 次,日均约 1,086 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@12-apps/pwa 还在维护吗?

最新版本 2.6.2 发布于 2026/09/05(2 个月前);至今共发布 19 个版本,其中过去 12 个月发布了 19 个;首次发布于 2026/08/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。