2023-06-05 00:58:21 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) Contributors to the Suwayomi project
|
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
|
*/
|
|
|
|
|
|
2024-04-17 20:01:17 +02:00
|
|
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
|
|
|
|
2023-08-11 17:30:22 +02:00
|
|
|
import path from 'path';
|
2023-06-05 00:58:21 +02:00
|
|
|
import { defineConfig } from 'vite';
|
2023-08-11 17:30:22 +02:00
|
|
|
import react from '@vitejs/plugin-react-swc';
|
2023-06-05 00:58:21 +02:00
|
|
|
import viteTsconfigPaths from 'vite-tsconfig-paths';
|
2024-03-26 23:39:25 +01:00
|
|
|
import legacy from '@vitejs/plugin-legacy';
|
2025-11-22 16:56:53 +01:00
|
|
|
import { VitePWA } from 'vite-plugin-pwa';
|
2026-01-10 19:45:02 +01:00
|
|
|
import { lingui } from '@lingui/vite-plugin';
|
2025-08-02 23:13:50 +02:00
|
|
|
import 'dotenv/config';
|
2026-01-18 16:57:05 +01:00
|
|
|
import { d } from 'koration';
|
2023-06-05 00:58:21 +02:00
|
|
|
|
2023-11-25 18:13:51 +01:00
|
|
|
// eslint-disable-next-line import/no-default-export
|
2025-09-24 00:23:19 +03:00
|
|
|
export default defineConfig(({ command }) => ({
|
|
|
|
|
base: command === 'serve' ? process.env.VITE_SUBPATH || './' : './',
|
2023-06-05 00:58:21 +02:00
|
|
|
build: {
|
|
|
|
|
outDir: 'build',
|
|
|
|
|
},
|
|
|
|
|
server: {
|
2025-08-02 23:13:50 +02:00
|
|
|
port: Number(process.env.PORT),
|
2025-08-13 00:57:46 +02:00
|
|
|
allowedHosts: process.env.ALLOWED_HOSTS.split(',').map((s) => s.trim()),
|
2023-06-05 00:58:21 +02:00
|
|
|
},
|
2023-06-17 20:53:00 +02:00
|
|
|
resolve: {
|
|
|
|
|
alias: {
|
2024-12-24 03:32:55 +01:00
|
|
|
'@': path.resolve(import.meta.dirname, './src'),
|
2023-06-17 20:53:00 +02:00
|
|
|
},
|
|
|
|
|
},
|
2024-04-14 15:11:13 +02:00
|
|
|
optimizeDeps: {
|
|
|
|
|
include: ['@mui/material/Tooltip'],
|
|
|
|
|
},
|
2024-03-26 23:39:25 +01:00
|
|
|
plugins: [
|
2026-01-10 19:45:02 +01:00
|
|
|
react({
|
|
|
|
|
plugins: [['@lingui/swc-plugin', {}]],
|
|
|
|
|
}),
|
|
|
|
|
lingui(),
|
2024-03-26 23:39:25 +01:00
|
|
|
viteTsconfigPaths(),
|
|
|
|
|
legacy({
|
|
|
|
|
modernPolyfills: [
|
|
|
|
|
'es/array/to-spliced',
|
|
|
|
|
'es/array/to-sorted',
|
|
|
|
|
'es/array/find-last',
|
|
|
|
|
'es/array/find-last-index',
|
2024-04-20 00:58:29 +02:00
|
|
|
'es/object/group-by',
|
2024-03-26 23:39:25 +01:00
|
|
|
],
|
|
|
|
|
}),
|
2025-11-22 16:56:53 +01:00
|
|
|
// Only setup image runtime caching
|
|
|
|
|
VitePWA({
|
|
|
|
|
registerType: 'autoUpdate',
|
|
|
|
|
manifest: false, // Use existing manifest
|
|
|
|
|
devOptions: {
|
|
|
|
|
enabled: true,
|
|
|
|
|
},
|
|
|
|
|
workbox: {
|
|
|
|
|
globPatterns: [],
|
|
|
|
|
runtimeCaching: [
|
|
|
|
|
{
|
2026-01-18 16:34:20 +01:00
|
|
|
urlPattern: ({ url }) => {
|
|
|
|
|
const { pathname } = url;
|
|
|
|
|
return pathname.match(/\/chapter\/[0-9]+\/page\/[0-9]+/g);
|
|
|
|
|
},
|
|
|
|
|
handler: 'CacheFirst',
|
|
|
|
|
options: {
|
|
|
|
|
// !!! IMPORTANT !!! - Update along with ImageCache.ts
|
|
|
|
|
cacheName: 'image-cache-chapter-pages',
|
|
|
|
|
expiration: {
|
2026-01-18 16:57:05 +01:00
|
|
|
// Max age from server
|
|
|
|
|
maxAgeSeconds: d(1).days.inWholeSeconds,
|
2026-01-18 16:34:20 +01:00
|
|
|
maxEntries: 2500,
|
|
|
|
|
purgeOnQuotaError: true,
|
|
|
|
|
},
|
|
|
|
|
cacheableResponse: {
|
|
|
|
|
statuses: [0, 200],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
urlPattern: ({ url }) => {
|
|
|
|
|
const { pathname } = url;
|
|
|
|
|
return pathname.match(/\/manga\/[0-9]+\/thumbnail/g);
|
|
|
|
|
},
|
|
|
|
|
handler: 'CacheFirst',
|
|
|
|
|
options: {
|
|
|
|
|
// !!! IMPORTANT !!! - Update along with ImageCache.ts
|
|
|
|
|
cacheName: 'image-cache-manga-thumbnails',
|
|
|
|
|
expiration: {
|
2026-01-18 16:57:05 +01:00
|
|
|
// Max age from server
|
|
|
|
|
maxAgeSeconds: d(1).days.inWholeSeconds,
|
2026-01-18 16:34:20 +01:00
|
|
|
maxEntries: 5000,
|
|
|
|
|
purgeOnQuotaError: true,
|
|
|
|
|
},
|
|
|
|
|
cacheableResponse: {
|
|
|
|
|
statuses: [0, 200],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
urlPattern: ({ url }) => {
|
2025-11-22 16:56:53 +01:00
|
|
|
const { pathname } = url;
|
2026-01-18 16:34:20 +01:00
|
|
|
return pathname.includes('/extension/icon/');
|
2025-11-22 16:56:53 +01:00
|
|
|
},
|
|
|
|
|
handler: 'CacheFirst',
|
|
|
|
|
options: {
|
2026-01-18 16:34:20 +01:00
|
|
|
// !!! IMPORTANT !!! - Update along with ImageCache.ts
|
|
|
|
|
cacheName: 'image-cache-extension-icons',
|
|
|
|
|
expiration: {
|
2026-01-18 16:57:05 +01:00
|
|
|
// Max age from server
|
|
|
|
|
maxAgeSeconds: d(365).days.inWholeSeconds,
|
2026-01-18 16:34:20 +01:00
|
|
|
maxEntries: 300,
|
|
|
|
|
purgeOnQuotaError: true,
|
|
|
|
|
},
|
|
|
|
|
cacheableResponse: {
|
|
|
|
|
statuses: [0, 200],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
urlPattern: ({ request }) => request.destination === 'image',
|
|
|
|
|
handler: 'CacheFirst',
|
|
|
|
|
options: {
|
|
|
|
|
// !!! IMPORTANT !!! - Update along with ImageCache.ts
|
|
|
|
|
cacheName: 'image-cache-other',
|
2025-11-22 16:56:53 +01:00
|
|
|
expiration: {
|
2026-01-18 16:57:05 +01:00
|
|
|
maxAgeSeconds: d(4).days.inWholeSeconds,
|
2026-01-18 16:34:20 +01:00
|
|
|
maxEntries: 500,
|
2025-11-22 16:56:53 +01:00
|
|
|
purgeOnQuotaError: true,
|
|
|
|
|
},
|
|
|
|
|
cacheableResponse: {
|
|
|
|
|
statuses: [0, 200],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
}),
|
2024-03-26 23:39:25 +01:00
|
|
|
],
|
2023-06-05 00:58:21 +02:00
|
|
|
}));
|