vite.config.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { defineConfig } from "vite";
  2. import vue from "@vitejs/plugin-vue";
  3. import { VitePWA } from 'vite-plugin-pwa';
  4. import { fileURLToPath, URL } from "node:url";
  5. // https://vite.dev/config/
  6. export default defineConfig({
  7. plugins: [
  8. vue(),
  9. VitePWA({
  10. registerType: 'autoUpdate',
  11. includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'icons/*.png'],
  12. manifest: {
  13. name: 'Junma Show',
  14. short_name: 'Junma',
  15. description: '在线视频播放平台',
  16. theme_color: '#10b981',
  17. background_color: '#0f172a',
  18. display: 'standalone',
  19. icons: [
  20. {
  21. src: '/vite.svg',
  22. sizes: 'any',
  23. type: 'image/svg+xml',
  24. purpose: 'any maskable'
  25. }
  26. ]
  27. },
  28. workbox: {
  29. globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
  30. runtimeCaching: [
  31. {
  32. urlPattern: /^https:\/\/api\./i,
  33. handler: 'NetworkFirst',
  34. options: {
  35. cacheName: 'api-cache',
  36. expiration: {
  37. maxEntries: 50,
  38. maxAgeSeconds: 60 * 60 * 24 // 24 hours
  39. },
  40. cacheableResponse: {
  41. statuses: [0, 200]
  42. }
  43. }
  44. },
  45. {
  46. urlPattern: /^https:\/\/.*\.(jpg|jpeg|png|gif|webp)$/i,
  47. handler: 'CacheFirst',
  48. options: {
  49. cacheName: 'images-cache',
  50. expiration: {
  51. maxEntries: 100,
  52. maxAgeSeconds: 60 * 60 * 24 * 30 // 30 days
  53. }
  54. }
  55. },
  56. {
  57. urlPattern: /^https:\/\/.*\.m3u8$/i,
  58. handler: 'NetworkOnly',
  59. options: {
  60. cacheName: 'video-cache'
  61. }
  62. }
  63. ],
  64. cleanupOutdatedCaches: true,
  65. skipWaiting: true,
  66. clientsClaim: true
  67. },
  68. devOptions: {
  69. enabled: true,
  70. type: 'module'
  71. }
  72. })
  73. ],
  74. resolve: {
  75. alias: {
  76. "@": fileURLToPath(new URL("./src", import.meta.url)),
  77. },
  78. },
  79. server: {
  80. port: 5100,
  81. host: "0.0.0.0",
  82. open: true,
  83. cors: true,
  84. proxy: {
  85. '/api/proxy/external-vod': {
  86. target: 'https://slapibf.com',
  87. changeOrigin: true,
  88. rewrite: (path) => path.replace(/^\/api\/proxy\/external-vod/, '/api.php/provide/vod'),
  89. configure: (proxy, _options) => {
  90. proxy.on('error', (err, _req, _res) => {
  91. console.log('proxy error', err);
  92. });
  93. proxy.on('proxyReq', (proxyReq, req, _res) => {
  94. console.log('Sending Request to the Target:', req.method, req.url);
  95. });
  96. proxy.on('proxyRes', (proxyRes, req, _res) => {
  97. console.log('Received Response from the Target:', proxyRes.statusCode, req.url);
  98. });
  99. },
  100. },
  101. },
  102. },
  103. build: {
  104. rollupOptions: {
  105. output: {
  106. manualChunks: {
  107. // 将 Vue 相关库分离
  108. "vue-vendor": ["vue", "vue-router"],
  109. // 将大型页面组件分离
  110. "video-player": ["./src/views/VideoPlayer.vue"],
  111. account: ["./src/views/Account.vue"],
  112. purchased: ["./src/views/Purchased.vue"],
  113. favorite: ["./src/views/Favorite.vue"],
  114. // 将布局组件分离
  115. layout: [
  116. "./src/components/layout/MainLayout.vue",
  117. "./src/components/layout/VideoLayout.vue",
  118. ],
  119. },
  120. },
  121. },
  122. // 提高警告阈值
  123. chunkSizeWarningLimit: 1000,
  124. },
  125. });