SPA는 새 버전을 스스로 감지해 새로고침을 권한다
배포 뒤에도 열려 있는 탭은 새로고침 전까지 옛 번들로 돈다. 탭으로 돌아오거나 다시 연결될 때 index.html의 번들 이름을 비교해 새로고침 버튼을 보여 준다.
배포를 마쳤는데 며칠째 열려 있던 탭에서 옛 화면과 옛 API 호출이 계속 들어온다. 사용자는 새 기능이 왜 안 보이는지 모른다.
SPA는 처음 받은 자바스크립트 번들로 계속 돈다. 서버가 바뀌어도 탭은 새로고침하기 전까지 그 사실을 모른다.
앱이 스스로 확인한다. 탭으로 돌아올 때(visibilitychange)와 실시간 연결이 다시 붙을 때 index.html을 캐시 없이 받아, 그 안의 번들 파일 이름(빌드 해시)을 지금 실행 중인 것과 비교한다. 다르면 새로고침 버튼을 보여 준다. 쓰던 내용을 잃지 않게 강제 새로고침은 하지 않는다.
const running = [...document.scripts]
.map((s) => s.src)
.find((src) => src.includes('/assets/index-'));
async function hasNewVersion(): Promise<boolean> {
if (!running) return false;
const html = await fetch('/index.html', { cache: 'no-store' }).then((r) => r.text());
return !html.includes(new URL(running).pathname);
}
document.addEventListener('visibilitychange', async () => {
if (document.visibilityState === 'visible' && (await hasNewVersion())) {
showReloadBanner(); // 「새 버전이 있습니다 · 새로고침」
}
});
안내를 해도 바로 새로고침하지 않는 사람은 있다. 서버는 옛 클라이언트의 요청도 한동안 받아 줄 수 있어야 한다.