feat: add installable PWA #30 #31

Merged
codex-bot merged 1 commits from codex/pwa into develop 2026-09-20 20:07:51 +03:00
8 changed files with 4640 additions and 2 deletions
+19
View File
@@ -51,6 +51,25 @@ Compose topology принадлежит workspace, эксплуатационн
Проверка публикации требует настроенного registry/runner; локальный build
не доказывает package permissions.
## Установка как приложение (PWA)
Production-сборка поддерживает установку WealthLedger в отдельное окно через
`vite-plugin-pwa`. Нужен HTTPS или localhost. В Chrome/Edge выберите «Установить
WealthLedger» в меню браузера или значок установки в адресной строке; на iPhone
и iPad — Safari → «Поделиться» → «На экран Домой». Доступность установки зависит
от браузера и ОС.
Service worker кеширует только статическую оболочку, включая страницы SPA.
Вход, финансовые данные и сохранение изменений требуют сети: API, токены и
ответы API не сохраняются в Cache Storage. Это не автономный финансовый
клиент. Новая версия загружается в фоне и применяется после закрытия всех
вкладок и окон WealthLedger и повторного открытия; открытые формы автоматически
не перезагружаются.
Локальная проверка: `nvm use --silent`, `npm run build`, `npm run preview`.
В DevTools → Application проверьте Manifest, Service Workers и Cache Storage.
В режиме `npm run dev` и в Storybook service worker не включается.
## Проверка
```bash
+3 -1
View File
@@ -1,8 +1,10 @@
<!doctype html>
<html lang="en">
<html lang="ru">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<meta name="theme-color" content="#ffffff" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WealthLedger</title>
</head>
+4571
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -82,6 +82,7 @@
"storybook": "10.6.0",
"typescript": "5.9.3",
"vite": "8.3.0",
"vite-plugin-pwa": "1.3.0",
"vitest": "5.0.0"
},
"allowScripts": {
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

+46 -1
View File
@@ -2,10 +2,55 @@ import { fileURLToPath, URL } from "node:url";
import babel from "@rolldown/plugin-babel";
import react, { reactCompilerPreset } from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import { VitePWA } from "vite-plugin-pwa";
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), babel({ presets: [reactCompilerPreset()] })],
plugins: [
react(),
babel({ presets: [reactCompilerPreset()] }),
VitePWA({
injectRegister: "script-defer",
// Let the waiting worker activate after all app windows close.
registerType: "prompt",
includeAssets: ["favicon.svg", "icons.svg", "apple-touch-icon.png"],
manifest: {
id: "/",
name: "WealthLedger",
short_name: "WealthLedger",
description: "Личные финансы и инвестиции",
lang: "ru",
start_url: "/",
scope: "/",
display: "standalone",
theme_color: "#ffffff",
background_color: "#ffffff",
icons: [
{ src: "/pwa-192x192.png", sizes: "192x192", type: "image/png" },
{ src: "/pwa-512x512.png", sizes: "512x512", type: "image/png" },
{
src: "/pwa-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "maskable",
},
],
},
workbox: {
globPatterns: ["**/*.{js,css,html,woff2}"],
// Only the static shell is cached; API requests always use the network.
navigateFallbackDenylist: [/^\/api(?:\/|$)/],
},
integration: {
configureOptions(config, options) {
// Storybook loads this Vite config but must not install an app worker.
options.disable = config.plugins.some((plugin) =>
plugin.name.startsWith("storybook:"),
);
},
},
}),
],
resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)) } },
server: {
proxy: {