PastePreset
PastePreset 是一个 privacy-first、纯浏览器端的图片处理 Web app。package.json、README.md、docs/pwa-offline-support.md 和 public/manifest.
- Progressive web app
- Storybook accessibility
目录
技术栈
运行与交付
- CI 工作流
- ci.yml
- deploy.yml
- 能力标记
- github_actions
- package_json
依赖与工具
- package.json
- 开发依赖
- @biomejs/biome
- @playwright/test
- @storybook/addon-a11y
- @storybook/addon-docs
- 生产依赖
- @iconify/icons-circle-flags
- @iconify/icons-mdi
- @iconify/react
- exifr
- 项目脚本
- build
- build-storybook
- check
- dev
配置与质量
- 配置文件
- .gitignore
- biome.json
- lefthook.yml
- package.json
- tsconfig.app.json
- tsconfig.json
- tsconfig.node.json
{
"ci_workflows": [
"ci.yml",
"deploy.yml"
],
"configs_root": [
".gitignore",
"biome.json",
"lefthook.yml",
"package.json",
"tsconfig.app.json",
"tsconfig.json",
"tsconfig.node.json"
],
"markers_present": [
"github_actions",
"package_json"
],
"package_json": {
"deps_dev": [
"@biomejs/biome",
"@playwright/test",
"@storybook/addon-a11y",
"@storybook/addon-docs",
"@storybook/addon-links",
"@storybook/jest",
"@storybook/react-vite",
"@storybook/test",
"@storybook/test-runner",
"@storybook/testing-library",
"@tailwindcss/vite",
"@types/bun",
"@types/node",
"@types/react",
"@types/react-dom",
"@vitejs/plugin-react",
"@vitest/coverage-v8",
"@vitest/ui",
"autoprefixer",
"daisyui"
],
"deps_prod": [
"@iconify/icons-circle-flags",
"@iconify/icons-mdi",
"@iconify/react",
"exifr",
"heic2any",
"jszip",
"piexifjs",
"react",
"react-dom"
],
"scripts": [
"build",
"build-storybook",
"check",
"dev",
"format",
"lint",
"preview",
"storybook",
"storybook:ci",
"test",
"test-storybook",
"test-storybook:runner",
"test:e2e",
"test:e2e:pwa",
"test:e2e:ui"
]
}
}Purpose
PastePreset 是一个 privacy-first、纯浏览器端的图片处理 Web app。package.json、README.md、docs/pwa-offline-support.md 和 public/manifest.webmanifest 共同表明,这个项目不只是普通 React/Vite SPA,而是明确把“可安装、可离线启动、图片处理全在本地完成”的 owner-facing 产品面当成长期 contract 维护。
Taxonomy
- Tags: Progressive web app, Storybook accessibility
Repository map
src/是 React 应用本体;src/lib/、src/hooks/和src/components/围绕图片输入、处理、输出与设置构成完整前端 runtime。public/manifest.webmanifest与public/pwa/保存 install-facing metadata、icons、maskable icons 和 screenshots。src/pwa/registerServiceWorker.ts、scripts/build-sw.mjs、scripts/sw-template.js负责 service worker 注册与构建时 precache 注入。tests/e2e-pwa/、playwright.pwa.config.ts和docs/pwa-offline-support.md说明这个 repo 把 PWA 行为单独当作验证面,而不是塞进普通 smoke test。.storybook/与public/storybook/保持组件级 QA 和 a11y surface,但它们不是 PWA 交付面的替身。
Runtime and delivery
package.json 的 build 会先写入版本信息,再执行 vite build,最后运行 node scripts/build-sw.mjs,说明离线 app shell 与 version.json 一样属于正式产物,而不是部署后的临时拼装。index.html 和 public/manifest.webmanifest 把 start_url、scope、display: standalone、maskable icons 和 apple-touch-icon 写成稳定 install metadata;test:e2e:pwa 则通过 playwright.pwa.config.ts 走独立浏览器路径,验证 service worker 就绪、离线启动和核心流程。
Architecture notes
这个项目的关键架构边界是“处理逻辑完全本地执行,但 app shell 仍然需要正式的 PWA 运行时 contract”。docs/pwa-offline-support.md 明确要求:先在线访问并安装,之后离线启动时仍要完整渲染 UI;更新采用 next-launch 语义,不允许 skipWaiting() 或 mid-session 强刷。scripts/build-sw.mjs 用 Workbox injectManifest 维护 precache,src/pwa/registerServiceWorker.ts 负责等待/接管逻辑,说明这里的 PWA 不是营销标签,而是真正影响版本切换、资源缓存和 owner handoff 的 runtime 设计。
Workflow and quality gates
前端质量门禁分三层:vitest 负责单元测试,playwright test 负责常规 e2e,playwright test -c playwright.pwa.config.ts 负责 PWA/offline 专项路径。Storybook 安装了 @storybook/addon-a11y,并通过 test-storybook 保持组件 QA;CI 与 deploy workflow 则让 build + PWA asset + 测试链路一起进入交付面。对于这个仓库,单纯 vite build 通过并不能证明交付完成,PWA 专项验证是必需门禁。
Reusable decisions
- 把 PWA 设计文档单独写进
docs/pwa-offline-support.md,比在 README 里顺带提一句“支持离线”更可靠。 - 为 PWA 保留独立的
playwright.pwa.config.ts和tests/e2e-pwa/,能避免 service worker / offline 逻辑被普通 e2e 稀释掉。 - 让
build显式串联版本写入、静态构建和 service worker 注入,可以防止version.json或其它 UI-critical 资产漏进 precache。 - 对 update lifecycle 采取 next-launch 策略,并在设计文档里明确禁止
skipWaiting()自动接管,是很值得复用的默认习惯。
Risks and open questions
- iOS Safari 的离线缓存与剪贴板能力仍有平台限制,PWA contract 需要把“best effort”边界说清楚。
- HEIC 转换相关动态产物若没有被 precache 完整覆盖,离线成功率会看起来随机。
- 这个仓库是纯前端产品面,后续若引入云同步或外部 API,就必须重新审查当前“离线即完整功能”的假设。
Evidence index
README.mdpackage.jsonindex.htmlpublic/manifest.webmanifestpublic/pwa/scripts/build-sw.mjsscripts/sw-template.jssrc/pwa/registerServiceWorker.tsplaywright.config.tsplaywright.pwa.config.tstests/e2e-pwa/pwa-offline.spec.ts.storybook/main.ts.storybook/preview.tsxdocs/pwa-offline-support.md
相关内容
Progressive web app
主题Progressive web app 在这套 playbook 里不是“网页顺手带个 manifest”的统称,而是“把一个 Web surface 当成可安装应用去维护”的工程模式。
Storybook accessibility
主题Storybook accessibility 表示 Storybook 不只是组件展示,还明确引入 a11y audit 能力,通常是 @storybook/addon-a11y 或等价的 browser-backed Axe sweep。它关注 story-level 可访问性信号,例如对比度、ARIA 基础错误、表单语义和交互状态,而不是泛化的 Storybook 文档能力。