noteJS-react/vite.config.ts

234 lines
7.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { VitePWA } from "vite-plugin-pwa";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
VitePWA({
injectRegister: "auto",
includeAssets: [
"icon.svg",
"icons/icon-192x192.png",
"icons/icon-512x512.png",
],
manifest: {
name: "NoteJS - Система заметок",
short_name: "NoteJS",
description:
"Современная система заметок с поддержкой Markdown, изображений, тегов и календаря",
theme_color: "#007bff",
background_color: "#ffffff",
display: "standalone",
orientation: "portrait-primary",
scope: "/",
start_url: "/",
icons: [
{
src: "/icons/icon-72x72.png",
sizes: "72x72",
type: "image/png",
purpose: "any",
},
{
src: "/icons/icon-96x96.png",
sizes: "96x96",
type: "image/png",
purpose: "any",
},
{
src: "/icons/icon-128x128.png",
sizes: "128x128",
type: "image/png",
purpose: "any",
},
{
src: "/icons/icon-144x144.png",
sizes: "144x144",
type: "image/png",
purpose: "any",
},
{
src: "/icons/icon-152x152.png",
sizes: "152x152",
type: "image/png",
purpose: "any",
},
{
src: "/icons/icon-192x192.png",
sizes: "192x192",
type: "image/png",
purpose: "any",
},
{
src: "/icons/icon-384x384.png",
sizes: "384x384",
type: "image/png",
purpose: "any",
},
{
src: "/icons/icon-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "any",
},
{
src: "/icons/icon-192x192.png",
sizes: "192x192",
type: "image/png",
purpose: "maskable",
},
{
src: "/icons/icon-512x512.png",
sizes: "512x512",
type: "image/png",
purpose: "maskable",
},
],
},
workbox: {
globPatterns: ["**/*.{js,css,html,ico,png,svg,woff,woff2,ttf,eot}"],
// Игнорируем параметры URL при кешировании
ignoreURLParametersMatching: [/^utm_/, /^fbclid$/],
// Обработка навигации - всегда используем кэшированную версию
navigateFallback: "/index.html",
navigateFallbackDenylist: [/^\/api/, /^\/uploads/],
// Стратегия для навигационных запросов - сначала кэш
navigationPreload: false,
// Обработка ошибок при загрузке файлов для precaching
dontCacheBustURLsMatching: /\.\w{8}\./,
// Фильтруем манифест, чтобы исключить несуществующие файлы и дубликаты
manifestTransforms: [
async (manifestEntries) => {
// Фильтруем дубликаты
const seen = new Set<string>();
const filtered = manifestEntries.filter((entry) => {
// Удаляем дубликаты
if (seen.has(entry.url)) {
return false;
}
seen.add(entry.url);
return true;
});
return { manifest: filtered, warnings: [] };
},
],
runtimeCaching: [
// HTML документы - всегда сначала кэш для оффлайн работы
// Это гарантирует, что при обновлении страницы в оффлайн режиме
// всегда будет загружаться кэшированная версия БЕЗ попыток обращения к сети
{
urlPattern: ({ request }) => request.mode === 'navigate',
handler: "CacheFirst",
options: {
cacheName: "pages-cache",
expiration: {
maxEntries: 10,
maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
},
cacheableResponse: {
statuses: [0, 200],
},
},
},
// Дополнительное правило для HTML файлов
{
urlPattern: /\.html$/,
handler: "CacheFirst",
options: {
cacheName: "html-cache",
expiration: {
maxEntries: 10,
maxAgeSeconds: 7 * 24 * 60 * 60, // 7 days
},
cacheableResponse: {
statuses: [0, 200],
},
},
},
{
urlPattern: /^https:\/\/api\./,
handler: "NetworkFirst",
options: {
cacheName: "api-cache",
expiration: {
maxEntries: 50,
maxAgeSeconds: 60 * 60, // 1 hour
},
},
},
{
urlPattern: /\/api\//,
handler: "NetworkFirst",
options: {
cacheName: "api-cache-local",
expiration: {
maxEntries: 100,
maxAgeSeconds: 24 * 60 * 60, // 24 hours
},
networkTimeoutSeconds: 10,
},
},
{
urlPattern: /\/uploads\//,
handler: "CacheFirst",
options: {
cacheName: "uploads-cache",
expiration: {
maxEntries: 200,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
},
},
},
{
urlPattern: /\.(?:png|jpg|jpeg|svg|gif|webp)$/,
handler: "CacheFirst",
options: {
cacheName: "images-cache",
expiration: {
maxEntries: 100,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
},
},
},
],
cleanupOutdatedCaches: true,
skipWaiting: true,
clientsClaim: true,
// Обработка ошибок при precaching - игнорируем 404 ошибки
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB
},
// Автоматическое обновление SW без запроса пользователя
// для обеспечения стабильной работы в оффлайн режиме
registerType: "autoUpdate",
devOptions: {
enabled: true,
type: "module",
},
}),
],
server: {
port: 5173,
allowedHosts: ["app.notejs.ru", "localhost"],
proxy: {
"/api": {
target: "http://localhost:3001",
changeOrigin: true,
secure: false,
ws: true,
},
"/uploads": {
target: "http://localhost:3001",
changeOrigin: true,
secure: false,
},
"/logout": {
target: "http://localhost:3001",
changeOrigin: true,
secure: false,
},
},
},
});