dvc890 commited on
Commit
cd87b40
·
verified ·
1 Parent(s): 5c4258e

Upload 67 files

Browse files
Files changed (3) hide show
  1. App.tsx +39 -1
  2. server.js +13 -2
  3. vite.config.ts +1 -0
App.tsx CHANGED
@@ -1,3 +1,4 @@
 
1
  import React, { useState, useEffect, useRef } from 'react';
2
  import { Sidebar } from './components/Sidebar';
3
  import { Header } from './components/Header';
@@ -126,6 +127,43 @@ const AppContent: React.FC = () => {
126
  const [loading, setLoading] = useState(true);
127
  const [sidebarOpen, setSidebarOpen] = useState(false);
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  useEffect(() => {
130
  const initApp = async () => {
131
  api.init();
@@ -237,4 +275,4 @@ const App: React.FC = () => {
237
  );
238
  };
239
 
240
- export default App;
 
1
+
2
  import React, { useState, useEffect, useRef } from 'react';
3
  import { Sidebar } from './components/Sidebar';
4
  import { Header } from './components/Header';
 
127
  const [loading, setLoading] = useState(true);
128
  const [sidebarOpen, setSidebarOpen] = useState(false);
129
 
130
+ // --- Auto-Update Logic ---
131
+ useEffect(() => {
132
+ // 1. Force reload page when Service Worker updates (controller change)
133
+ // This happens automatically due to 'registerType: autoUpdate' in vite config,
134
+ // but the window needs to reload to use the new SW.
135
+ const handleControllerChange = () => {
136
+ console.log("🔄 App updated, reloading...");
137
+ window.location.reload();
138
+ };
139
+
140
+ // 2. Check for updates on visibility change (e.g. user comes back to tab)
141
+ const checkForUpdates = () => {
142
+ if ('serviceWorker' in navigator) {
143
+ navigator.serviceWorker.ready.then(registration => {
144
+ registration.update();
145
+ }).catch(() => {});
146
+ }
147
+ };
148
+
149
+ if ('serviceWorker' in navigator) {
150
+ navigator.serviceWorker.addEventListener('controllerchange', handleControllerChange);
151
+ document.addEventListener('visibilitychange', () => {
152
+ if (document.visibilityState === 'visible') {
153
+ checkForUpdates();
154
+ }
155
+ });
156
+ // Initial check
157
+ checkForUpdates();
158
+ }
159
+
160
+ return () => {
161
+ if ('serviceWorker' in navigator) {
162
+ navigator.serviceWorker.removeEventListener('controllerchange', handleControllerChange);
163
+ }
164
+ };
165
+ }, []);
166
+
167
  useEffect(() => {
168
  const initApp = async () => {
169
  api.init();
 
275
  );
276
  };
277
 
278
+ export default App;
server.js CHANGED
@@ -31,10 +31,21 @@ app.use(compression({
31
 
32
  app.use(cors());
33
  app.use(bodyParser.json({ limit: '50mb' }));
 
 
34
  app.use(express.static(path.join(__dirname, 'dist'), {
35
  setHeaders: (res, filePath) => {
36
- if (filePath.endsWith('.html')) res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
37
- else res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
 
 
 
 
 
 
 
 
 
38
  }
39
  }));
40
 
 
31
 
32
  app.use(cors());
33
  app.use(bodyParser.json({ limit: '50mb' }));
34
+
35
+ // 静态资源托管配置优化
36
  app.use(express.static(path.join(__dirname, 'dist'), {
37
  setHeaders: (res, filePath) => {
38
+ // 关键修复:入口文件、Service Worker Manifest 必须禁止缓存,确保每次都获取最新版本
39
+ if (
40
+ filePath.endsWith('.html') ||
41
+ filePath.endsWith('sw.js') ||
42
+ filePath.endsWith('manifest.webmanifest')
43
+ ) {
44
+ res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
45
+ } else {
46
+ // 其他带 Hash 的静态资源可以强缓存 1 年
47
+ res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
48
+ }
49
  }
50
  }));
51
 
vite.config.ts CHANGED
@@ -38,6 +38,7 @@ export default defineConfig({
38
  ]
39
  },
40
  workbox: {
 
41
  // 缓存策略配置,确保 API 请求不被过度缓存,但静态资源被缓存
42
  globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
43
  runtimeCaching: [
 
38
  ]
39
  },
40
  workbox: {
41
+ cleanupOutdatedCaches: true, // 关键:自动清理过期的缓存文件
42
  // 缓存策略配置,确保 API 请求不被过度缓存,但静态资源被缓存
43
  globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
44
  runtimeCaching: [