javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > 前端自动检测代码更新

面试官最喜欢问的题目之前端怎么自动检测代码更新

作者:leopai

在Web应用开发中,版本更新提示是提升用户体验的重要环节,这篇文章主要介绍了面试官最喜欢问的题目之前端怎么自动检测代码更新的相关资料,文中介绍的非常详细,需要的朋友可以参考下

在前端开发中,我们通常会使用打包工具(如 Vite、Webpack)将 JS/CSS 等资源构建上线,并配合 CDN、浏览器缓存来加速访问。但问题也随之而来:

“我已经发布新版本了,怎么用户还看到旧界面?”

“为啥修复的 bug 还在?”

原因很简单:用户浏览器缓存了旧的静态资源,没有感知新版本的变更。

🎯 目标:前端页面如何自动检测打包更新并提示刷新

关键需求是:

思考:为啥不直接加 hash?

其实我们打包时已经使用 [hash] 命名资源了,那为啥还要检测更新?

因为:

所以必须在 运行中的前端代码层面 进行更新感知。

方案一:轮询版本文件(最常用)

实现思路:

  1. 打包时生成一个版本文件(如 version.json 或注入 index.html 里的 __BUILD_VERSION__ 字段);
  2. 页面加载后,定时轮询该文件;
  3. 一旦检测到版本变更(比如哈希不同),提示用户刷新。

示例代码:

const CURRENT_VERSION = __BUILD_VERSION__; // 构建时注入变量

setInterval(() => {
  fetch('/version.json?t=' + Date.now())
    .then(res => res.json())
    .then(({ version }) => {
      if (version !== CURRENT_VERSION) {
        alert('检测到新版本,点击确定刷新页面');
        window.location.reload(true);
      }
    });
}, 10000); // 每 10 秒轮询一次

或者使用文件指纹思路:

  1. 打包后生成一个 manifest 文件(比如 asset-manifest.jsonmeta.json),里面记录资源及其 hash;

  2. 页面运行时轮询这个 manifest 文件;

  3. 如果发现文件名或 hash 有变,提示刷新页面。

在 Vite 中添加如下配置:

// vite.config.ts
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    manifest: true, // 开启 manifest 生成
  }
})

构建后会生成 dist/manifest.json,类似这样:

{
  "index.html": { "file": "index.html", "isEntry": true },
  "src/main.ts": { "file": "assets/main.abc123.js", "isEntry": true },
  "src/style.css": { "file": "assets/style.def456.css" }
}

前端代码(可封装成检测模块):

let currentVersionHash = ''

function getHashFromManifest(manifest: any): string {
  // 自定义 hash 生成方式:可拼接所有文件路径,也可只取主入口
  return Object.values(manifest)
    .map((entry: any) => entry.file)
    .join('|')
}

async function checkForUpdate() {
  try {
    const res = await fetch(`/manifest.json?_t=${Date.now()}`)
    const manifest = await res.json()
    const newHash = getHashFromManifest(manifest)

    if (!currentVersionHash) {
      currentVersionHash = newHash
    } else if (currentVersionHash !== newHash) {
      console.log('🚨 发现新版本,准备刷新页面')
      alert('检测到新版本,点击确认刷新页面')
      window.location.reload(true)
    }
  } catch (err) {
    console.error('版本检查失败', err)
  }
}

setInterval(checkForUpdate, 10000) // 每 5 秒检查一次

💡manifest.json 中的文件路径含 hash,只要内容变,hash 就会变,就能准确识别版本是否更新。

优点:

缺点:

方案二:WebSocket(配合 CI/CD 或打包系统)

✅ 前提:

服务端(nodejs+ws模块):

// ws-server.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

const clients = new Set();

wss.on('connection', (ws) => {
  console.log('🚀 New client connected');
  clients.add(ws);

  ws.on('close', () => {
    clients.delete(ws);
  });
});

// 通知所有客户端刷新页面
function notifyClients() {
  for (let client of clients) {
    if (client.readyState === WebSocket.OPEN) {
      client.send(JSON.stringify({ type: 'update', message: 'new-version' }));
    }
  }
}

// 模拟触发更新(实际应在构建完成后调用)
setTimeout(() => {
  console.log('🎉 New version released, notifying clients...');
  notifyClients();
}, 10000); // 10 秒后触发

如果你有配套的部署平台或打包平台(如 Jenkins、Vercel、Netlify),可以在部署成功后广播一条“版本已更新”的消息。

客户端建立 WebSocket 连接,一旦收到推送,就提示刷新页面。

if ('WebSocket' in window) {
  const ws = new WebSocket('ws://localhost:8080');

  ws.onopen = () => {
    console.log('[WS] Connected to update server');
  };

  ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.type === 'update') {
      console.log('[WS] New version detected');
      // 这里可以是弹窗提醒,或者直接刷新
      if (confirm('检测到新版本,是否立即刷新页面?')) {
        window.location.reload();
      }
    }
  };

  ws.onclose = () => {
    console.log('[WS] Connection closed');
  };

  ws.onerror = (err) => {
    console.error('[WS] Error:', err);
  };
}

可封装为插件或独立模块进行复用,比如 Vue 插件、React Hook、Vite 插件等。

优点:

缺点:

总结

前端页面检测更新并不是“有没有后端通知”,而是我们主动地检测自己的版本是否已经被 CDN 或打包平台更新轮询 version.json 是最稳定、兼容性最强的方案; WebSocket 通知 是顶配方案,适合重型系统。

到此这篇关于面试官最喜欢问的题目之前端怎么自动检测代码更新的文章就介绍到这了,更多相关前端自动检测代码更新内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文