@broberg/pwa

中文文档
0.9.0发布于 2026/10/27MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 3729

Fleet PWA 原始:一个框架-不可知的服务-工人更新-检测控制器(新版-可用生命周期)+一个反应钩和无样式的横幅骨架+一个服务-工人跳等帮助. 零跑道口; 船-暗道口.

中文使用文档
文档目录19 节
  1. 0.9.0 — 一个已过时的页面重新装入自己新鲜的,一次: staleShellGuardScript() (F021…
  2. 0.8.0 — 同一SVG(F021.12)的本地图标集
  3. 0.7.0 — 舰队报告的四个修补(F021.11)
  4. 0.6.0 — 一个典型的服务工作者也可以使用: pwa-sw.global.js (F021.10) (法语)
  5. 0.5.0 — PNG 图标, 因此iPhone上的“ 添加到家用屏幕” 显示标志( F021. 9)
  6. 0.4.1 - “最新消息”现在总是更新(F054.9)
  7. 0.4.0 — READ, 不记得了(F054. 8)
  8. 如果你被开除了 升职不能自己解决
  9. 如果你需要30分钟以上的东西
  10. 更新生命周期
  11. 反应使用
  12. 预用
  13. 框架不可知核心
  14. createPwaUpdater(options)
  15. 服务-工人方面
  16. 安装设置 — 显示、 图标、 元( M) @broberg/pwa/manifest 页:1
  17. PNG图标—— pwa-icons 财务报告和审定财务报表 @broberg/pwa/raster (0.5.0,F0…
  18. 抓到他们了(放进这个包里 这样你就不会重新发现他们)
  19. 许可证

@broberg/pwa (英语)

舰队的 PWA 原始语言今天它把四号重装手卷 独立—— "有新版本可用,可以重新装入" 生命周期 - 作为一个小的、框架的和捆绑的不可知性包,而不是第五份.

npm i @broberg/pwa

0.9.0 — 一个已过时的页面重新装入自己新鲜的,一次: staleShellGuardScript() (F021.13) (法语)

部署后,一个已安装的应用程序可以在存储的页面副本上启动. 那个复制点在 /assets/ 保存已删除的部署, 404 个, 窗口将保留 白色。一个简单的重新装入可以让存储的页面返回。 该警卫为服务台(F047.5/F047.6,生产中),端口为:

import { staleShellGuardScript } from "@broberg/pwa/manifest";

// Vite: first thing in <head>, before your app script
transformIndexHtml: () => [{ tag: "script", children: staleShellGuardScript(), injectTo: "head-prepend" }],
// Next: <Script id="stale-shell" strategy="beforeInteractive">{staleShellGuardScript()}</Script>

当其中一页的 OWN 同源 /assets/ 脚本或样式表无法加载, 它导航到相同的 URL ?_v=<time> (浏览器商店从未见过的地址),最多每30 s一次,并删除 _v 从新页面上的地址栏。 图像、外国脚本和文件 /assets/ 从来没有触发它. staleShellGuardScript({ storageKey }) 设置自己的会话Storage密钥.

在飞行现场, @broberg/deploy-core ^ 0.8.2还服务于所保持部署(F033.20)的旧散货资产,因此,404型最初不会发生。 这个警卫掩护着其他的主人.

0.8.0 — 同一SVG(F021.12)的本地图标集

对于 Capacitor(iOS/Android)和Tauri apps,所以它们都没有保留自己的图标脚本:

pwa-icons --svg assets/icon.svg --native native-icons --background "#0B7A57"

写入

路径什麽
ios/AppIcon.appiconset/AppIcon-1024.png + 键 Contents.jsonXcode 14+ 单尺寸的应用程序图标. 无 Alpha 频道 ——App Store拒绝一个具有一个的图标,因此PNG被重新编码为RGB,而不只是做不透明.
android/mipmap-anydpi-v26/ic_launcher.xml, (中文(简体) ), ic_launcher_round.xml适应性图标 @color/ic_launcher_background + 键 @mipmap/ic_launcher_foreground
android/mipmap-<dpi>/ic_launcher_foreground.png每个密度108dp画布(108–432 px) 内部 66dp,每个发射器面具唯一保留的部分
android/mipmap-<dpi>/ic_launcher.png, (中文(简体) ), ic_launcher_round.png遗留发射器图标, 48–192 px
android/values/ic_launcher_background.xml背景颜色
desktop/icon.ico, (中文(简体) ), desktop/icon.icnsWindows / macOS (PNG 有效载荷)

--background 实值 所需经费: 透明画布上的白色符号会变成空图标。 将文件夹复制到您的 Xcode/ Gradle 项目中 —— 软件包不会编辑您的本地项目 。 程序设置 : nativeIconSet(svg, { background, platforms? }) 从 @broberg/pwa/raster。网络产出(rasterizeIconSet, (中文(简体) ), pwa-icons 无 --native) 不变.

0.7.0 — 舰队报告的四个修补(F021.11)

  • 初访无相旗. 一个全新的工人是短暂的 registration.waiting 每安装一次( spec's 因此第一次访问显示“Ny版本 klar” (vn-leker) (英语). 最新消息现在需要一名ACTIVE工人来替换. 真正的更新总是有一个, 也在页面上与 没有控制器,所以没有真正的横幅丢失.
  • 默认情况下没有英国人的身体行. labels.body 除非您设置它, 否则是空的; 标题会说它 。 (横幅有: 翻译标题/按钮用来显示“重新装入以获得最新版本”
  • IPhone家用屏幕图标. rasterizeIconSet() 现在也返回 rootFiles:180名巴布亚新几内亚人 /apple-touch-icon.png 财务报告和审定财务报表 /apple-touch-icon-precomposed.pngiOS要求网络ROOT自行提供这些; 没有他们,它又回到了一封信。 把它们写入您的网络根( Q) pwa-icons bin does, into the parent of 中, 输入到 --out 或者说 --root) (中文(简体) ). pwaMetaTags 现在放 sizes="180x180" 在苹果-touch链接.
  • 名单里只有PNG. 打开 rasterizeIconSet().icons ——而别无他法——在表上 icons[]。 。 。 . SVG 设定从 buildIconSet() 是发光器的源材料; SVG 条目在 icons[] 给了一封信 iOS 26 (jam),而每个工作的机队应用只有PNG. 过 rasterizeIconSet().appleTouchIcon 改为 pwaMetaTags({ appleTouchIcon })。 。 。 .
  • 使用 pwaMetaTags 头部,不仅您框架的元数据:它写着 apple-mobile-web-app-capable, (中文(简体) ), 下个16's appleWebApp.capable 没有( 它写 mobile-web-app-capable 页:1.

0.6.0 — 一个典型的服务工作者也可以使用: pwa-sw.global.js (F021.10) (法语)

服务员 public/ 是静态文件,不能 import 这样啊 @broberg/pwa/sw (一个ES模块)是无法到达的。 现在:

cp node_modules/@broberg/pwa/dist/pwa-sw.global.js public/   # e.g. in "prebuild"
// public/sw.js
importScripts('/sw.global.js');      // @broberg/webpush, if you use it
importScripts('/pwa-sw.global.js');  // «Opdatér nu» works — the listener is attached for you

不要打电话 listenForSkipWaiting 在那个工人中. self.BrobergPwa = { listenForSkipWaiting, SKIP_WAITING } 如果你需要的话 常数 文件名为 pwa-sw.global.js 这样它就可以坐在旁边 网络推力 sw.global.js 而不覆盖它。 导出为 @broberg/pwa/sw.global添加——没有其他变化.

0.5.0 — PNG 图标, 因此iPhone上的“ 添加到家用屏幕” 显示标志( F021. 9)

新设 pwa-icons 宾+ @broberg/pwa/raster - 见下文“PNG图标”。 添加内容 : 无已更改的输出, 核心条目仍然没有依赖性 .

0.4.1 - “最新消息”现在总是更新(F054.9)

如果您显示更新按钮, 请使用 0.4.1 . 在0.4.0的媒体 无法做任何事情, 永远:在没有现职服务人员的情况下打开一页(轮班,或 登记后的第一页),当一名新工人等待时,警卫 阻止第一个安装 重新装入新的访客 也吞下 接管媒体造成的。 没有重装,以后的媒体都找工人 这已经是活动。 店主在服务台按了30次后报道.

现在: applyUpdate() 下一次收购总是重新装入 工人已直接激活再装入;和 无 SW clientsClaim 工人到达后重新加载 activated一次重装 两次. reloadOnControllerChange: false 仍然意味着你重新装填自己。 无 API 更改; 第一个安装仍然从未单独重新装入 .

0.4.0 — READ, 不记得了(F054. 8)

带0.4.0. 在此之前, updateReady 只能离开 上来,并且仅来自 事件: registration.waiting 附加,加 updatefound编辑 调用间隔和焦点检查 registration.update() 从不看 registration.waiting 一点也不 因此,旗帜得到了 只有一次机会 看见了 - 放弃一次,或者错过 秒是它起来,没有在 软件包可以再次为那个分页提高。 客户就坐在老包上 无限.

它在令人安心的方向失败了:在新建筑上部署绿色的服务器, 特征活泼——任何人唯一的症状是一个人说 特性缺失。 这张卡片就是这么找到的 模式.

您有什么变化 :

0.3.x (单位:千美元)0.4.0 (中文(简体) )
updateReady升起一次,永远从 registration.waiting 每个间隔/ 焦点/ 可见度勾选
subscribe()最多发射量 一次当答案移动时,即发出, 双向
"待会"你的问题snooze() - 30分钟默认,持续,然后它回来

updateReady 现在可以走了. 如果你的代码假设它只会上升.. useState 你永远不要重置,一个你手举起的横幅 升级。 其他的都是添加剂.

const { updateReady, applyUpdate, snooze } = usePwaUpdate();
// "Update" → applyUpdate()     "Later" → snooze(), NOT a local setState(false)

在您的代码中查找的模式,在读取时由卡片命名 报告反对通过这些建议,这不是假设性的,而是 消费者写道:

// ⚠️ the 0.3.x shape: a local mirror, reset only on dismiss
const [needRefresh, setNeedRefresh] = useState(false);
useEffect(() => { if (updateReady) setNeedRefresh(true); }, [updateReady]);
const onDismiss = () => setNeedRefresh(false);   // ← the only way down

那面镜子不会掉下来的 updateReady 做,而弃绝是永久的 ——这是最初的缺陷,向上复制了一层. 放下镜子 从 updateReady 直接; 接线“ 稍后” 至 snooze()。 。 。 .

所以这里的升级是很小的 移徙,而不是免费的版本起伏。 这是 一个地方0.4.0 问你什么.

如果你被开除了 升职不能自己解决

fd-sundhed通过读取他们自己安装的代码而不是这个找到这个 报告,是其中一半将产生绿色索赔和 用户不变。 他们的旗子上挂着第二次辞退:

const [dismissed] = useState(() => sessionStorage.getItem(KEY) === "1");
if (!updateReady || dismissed) return null;   // "Later" hides it for the whole tab

缺点是 双倍 ——我们的钩子上,他们的部分上——并且只有 我们的去与一个 pnpm up升级,报告固定,这个人仍然 再也见不到旗帜了.

所以在升级之前,用另一种方式 给自己的部件加固 隐藏(单位:千美元) sessionStorage编号 :localStorage 旗帜, a dismissed 状态, a useRef 那节子 不管它被压住,它必须成为snooze,或 斯诺兹是装饰性的.

如果你需要30分钟以上的东西

snoozeMs 是一个普通的数字,所以一个大的数字是可用的,这个软件包将会 别阻止你 因此,诚实的说法比"哑巴是 不可能":没有名为"哑"的OPTION,默认会回来.

如果你真正想要的政策是 "剩下的钱都用完了"表达 作为范围而不是期限 -- -- snoozeStorage: sessionStorage 长的 snoozeMs而不是假装永久的 所以 关闭和重新打开应用程序的人又被问到,没有人需要解释 大约2255年的一个时间戳.

snooze() 故意的不是哑巴,没有办法让它变成哑巴: 上面的缺陷,是官方的。 这个 鼻涕虫一直存在(localStorage 默认, snoozeStorage: null 页:1 重新装入横幅是 请求 不能打败它.

  • @broberg/pwa —— 说 createPwaUpdater(),用于 服务-工人更新生命周期(与Serwist、工作箱或手工滚动的SW合作).
  • @broberg/pwa/react —— 说 usePwaUpdate() 钩子 + a 未设置 <PwaUpdateBanner> 骨架(用你自己的标志来设计).
  • @broberg/pwa/sw —— 说 listenForSkipWaiting()握手的侍从.

网页 推动 通知是一个单独关注的问题——使用 @broberg/webpush这个包裹从不触及推.

更新生命周期

找到新版本的服务员安装后 等待时间 这么说吧 无法从用户的下面删除页面. @broberg/pwa 检测到 等待工人,让用户选择何时取取,然后在活动后重新装入:

new deploy → SW installs → SW waiting → banner → user taps Update
  → applyUpdate() posts SKIP_WAITING → SW skipWaiting() → controllerchange → reload

反应使用

"use client";
import { usePwaUpdate, PwaUpdateBanner } from "@broberg/pwa/react";

export function PwaUpdater() {
  // Guards are YOUR policy — pass `disabled` for native shells / dev.
  const isNative = document.documentElement.classList.contains("native");
  const { updateReady, applyUpdate } = usePwaUpdate({
    disabled: isNative || process.env.NODE_ENV !== "production",
  });

  return (
    <PwaUpdateBanner
      updateReady={updateReady}
      onUpdate={applyUpdate}
      onDismiss={() => {/* hide for this session; it returns on next load */}}
      className="my-banner"                       // ← you own the styling
      labels={{ title: "Ny version klar", update: "Opdatér", dismiss: "Senere" }}
    />
  );
}

更喜欢自己造UI? 单用钩子.. usePwaUpdate() 给你 { updateReady, applyUpdate } 没有别的了。 旗帜只是方便 骨架: 它使 role="status" + 键 aria-live="polite",搭载马厩 睾丸 pwa-update-confirm 编号 : pwa-update-dismiss 编号 : pwa-update-close,以及 船舶 没有 颜色或设计系统类.

预用

与 Stack B (Bun / Hono / Preact) 应用程序的 API 相同 —— /preact 子路径 (单位:千美元)preact 是可选对等点,而不是 react:

import { usePwaUpdate, PwaUpdateBanner } from "@broberg/pwa/preact";

export function PwaUpdater() {
  const { updateReady, applyUpdate } = usePwaUpdate({ disabled: isNative || isDev });
  return <PwaUpdateBanner updateReady={updateReady} onUpdate={applyUpdate} className="my-banner" />;
}

usePwaUpdate() 财务报告和审定财务报表 <PwaUpdateBanner> 表现得和他们的反应一样 对口单位.

框架不可知核心

没有反应? 直接驱动控制器( Preact, Svelte, 香草) :

import { createPwaUpdater } from "@broberg/pwa";

const updater = createPwaUpdater({ swUrl: "/sw.js", disabled: isNative });
updater.subscribe(({ updateReady }) => renderBanner(updateReady));
// on the user's "Update" click:
updater.applyUpdate();
// later: updater.destroy();

createPwaUpdater(options)

选项默认含义
swUrl/sw.js要注册的服务- 工作脚本
pollIntervalMs3_600_000* 检查新战略的频率; 0 禁用
reloadOnControllerChangetrue新 SW 控制后重新加载页面
disabledfalse惰性无-op——通过自己的后卫(内壳,dev)

回返 { subscribe, getState, applyUpdate, destroy }没有服务员 支助(或 disabled),是一种永不放弃的惰性无能.

服务-工人方面

在您的服务人员中回答客户的激活请求:

// sw.ts
import { listenForSkipWaiting } from "@broberg/pwa/sw";
listenForSkipWaiting(); // defaults to the worker's own global scope

与 巫师编号 :工作框,继续激活用户提示 :

new Serwist({ /* … */, skipWaiting: false, clientsClaim: true });

安装设置 — 显示、 图标、 元( M)@broberg/pwa/manifest页:1

这个 其他项目 半个PWA: manifest.webmanifest,图标集,和 苹果点触 <meta> 标记——全部为 纯, 零点 工厂让你停下来 手工滚动 app/manifest.ts页:1 gen-pwa-icons.cjs 脚本和墙壁 <meta> 标签。 图标作为自成一体的发布 特别工作组对巴布亚新几内亚人来说 iPhone需要,见下文“PNG图标”(0.5.0).

import { defineManifest, serializeManifest, buildIconSet, pwaMetaTags } from "@broberg/pwa/manifest";

// 1. Icons from a monogram (or pass `svg: "<svg…>"` for real artwork).
const { files, icons } = buildIconSet({ monogram: "AK", background: "#141969", color: "#fff" });
//    files → [{ path:"/icons/icon-180.svg", content:"<svg…>", … }, …]  (write to public/)
//    icons → manifest icons[] incl. a padded maskable-512

// 2. Manifest — required members defaulted; `extra` merges last.
const manifest = defineManifest({ name: "Aalborg Klinik", shortName: "AK", themeColor: "#141969", icons });
writeFile("public/manifest.webmanifest", serializeManifest(manifest));

// 3. Head tags — typed descriptors you render in Next metadata / a Hono head / plain HTML.
pwaMetaTags({ themeColor: "#141969", title: "AK" });
// → [{tag:"link",attrs:{rel:"manifest",href:"/manifest.webmanifest"}}, {tag:"meta",attrs:{name:"theme-color",…}}, …]
  • buildIconSet 发放苹果(180分)、192分、512分+可伪装-512分(10%的安全区) 默认( inset) ; 覆盖 sizes, (中文(简体) ), basePath, (中文(简体) ), maskable。 。 。 . 180 进入 苹果点触 <link>,不显示 icons[]。 。 。 .
  • 一切都是纯粹的回报价值 - 你拥有文件系统写作和头 调制。 运行在构建脚本,路由处理器或浏览器中.
  • iOS需要PNG (英语). Safari 不使用 SVG 软件 apple-touch-icon: 仅使用 SVG 在 iPhone 上显示页面截图 标志。 (这个README说到0.5.0之前是相反的——这是错的

PNG图标—— pwa-icons 财务报告和审定财务报表 @broberg/pwa/raster (0.5.0,F021.9) (中文(简体) )

一个命令, 在构建时间运行; 每个应用程序没有尖锐的脚本 :

npm i -D @resvg/resvg-js            # the renderer — an optional peer, prebuilt binaries
npx pwa-icons --svg logo.svg --background "#141969" --out public/icons
#   or: --monogram AK --color "#fff"     (also --base-path /icons)

写着 icon-180/192/512.{svg,png} + 键 icon-maskable-512.{svg,png} 和指纹 显示 icons[] (巴布亚新几内亚)和 appleTouchIcon。将头牌指向PNG:

pwaMetaTags({ themeColor: "#141969", appleTouchIcon: "/icons/icon-180.png" });

或用代码 :

import { buildIconSet } from "@broberg/pwa/manifest";
import { rasterizeIconSet } from "@broberg/pwa/raster";
const { files, icons, appleTouchIcon } = await rasterizeIconSet(buildIconSet({ svg, background: "#141969" }));
// files → [{ path: "/icons/icon-180.png", content: Uint8Array, … }] — you write them

@broberg/pwa 财务报告和审定财务报表 /manifest 保持无依赖关系 /raster 图标 需求 @resvg/resvg-js,没有它,安装命令就失效.

抓到他们了(放进这个包里 这样你就不会重新发现他们)

  • 第一个安装被压制. 一个工人到达 installed 没有 控制器为 第一个 安装——没有任何更新,所以没有横幅.
  • 没有重新装入. controllerchange 重装一次.
  • Serwist + Next.js 需要网页包构建器 —— 说 next build 与 涡轮包装 打破农奴制的SW建设. 使用 next build (网络包装).
  • 警卫属于你. 这个包裹不闻 NODE_ENV 或一个 .native 班级——通过 disabled 因此,政策 住在一个地方 在你的应用.

许可证

麻省理工学院的一部分 @broberg/* 共享库存.

版本与发布记录

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

版本发布日期距今
0.9.0latest2026/10/2712 天前
0.8.02026/10/2514 天前
0.7.02026/10/2217 天前
0.6.02026/10/1129 天前
0.5.02026/10/1029 天前
0.4.12026/10/011 个月前

关于 @broberg/pwa 的常见问题

@broberg/pwa 是什么?

Fleet PWA 原始:一个框架-不可知的服务-工人更新-检测控制器(新版-可用生命周期)+一个反应钩和无样式的横幅骨架+一个服务-工人跳等帮助. 零跑道口; 船-暗道口.

如何安装 @broberg/pwa?

在项目目录运行 npm install @broberg/pwa,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 pwa-icons,可以用 npx pwa-icons 直接运行。

@broberg/pwa 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@broberg/pwa 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@broberg/pwa 可以商用吗?

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

@broberg/pwa 的下载量有多少?

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

@broberg/pwa 还在维护吗?

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