前端解决浏览器版本延迟问题(webpack)

浏览器延迟

修复bug发布测试环境时,测试同学发出疑问为什么bug没有修改,我们总是说让刷新一下就好了

  • 为什么要刷新

因为浏览器不知道代码有更新

  • 即使打包加了contentHash
  • Nginx设置index.html Cache-Control: no-store

总是无法做到浏览器同步更新

解决问题

  1. 打包注入唯一变量
js 复制代码
// webpack.config.js
const { DefinePlugin } = require('webpack');

module.exports = {
  plugins: [
    new DefinePlugin({
      __BUILD_VERSION__: JSON.stringify(Date.now()), // 或从 CI/CD 注入
    }),
  ],
};
  1. 生成version.json加入到build文件中
js 复制代码
// 保证注入变量及version.json写入值相同

const DEFAULT_BUILD_VERSION = JSON.stringify(Date.now())
module.exports = { plugins: 
[ new DefinePlugin({ __BUILD_VERSION__: DEFAULT_BUILD_VERSION, // 或从 CI/CD 注入 }),
 {
        apply(compiler) {
          // 使用 afterEmit 钩子,这个钩子会在资源输出到output目录后触发
          compiler.hooks.afterEmit.tap('VersionFilePlugin', () => {
            const outputPath = compiler.options.output.path;
            // 修复:生成正确的 JSON 格式
            const versionData = JSON.stringify({ version: DEFAULT_BUILD_VERSION });
            fs.writeFileSync(
              path.join(outputPath, 'version.json'),
              versionData
            );
          });
        }
      }
], };
    
  1. 编写检查版本的hooks
js 复制代码
import { useEffect } from 'react';
import { Modal } from 'antd';

// 加入生产环境才需要,本地开发不需要检查
const isProduction = process.env.NODE_ENV === 'production';

const useCheckVersion = () => {
  useEffect(() => {

    if (!isProduction) {
      return () => {};
    }

    const checkVersion = async () => {
      try {
          
        const res = await fetch(`/version.json?ts=${Date.now()}`, {
          cache: 'no-store', // 禁止缓存该请求
        });

        const { version } = await res.json();

        if (!version || !process.env.__BUILD_VERSION__ ||
          // 保证判断格式统一
          `${version}` !== `${process.env.__BUILD_VERSION__}`) 
          {
           Modal.info({
            title: '发现新版本',
            content: '请刷新页面以获取最新版本',
            onOk: () => {
              window.location.reload();
            },
            okText: '刷新',
          });
        }
      } catch (error) {
        // 添加更详细的错误信息
        if (error instanceof Error) {
          // eslint-disable-next-line no-console
          console.error('Error details:', {
            message: error.message,
            stack: error.stack,
          });
        }
      }
    };

    // 场景1:页面首次加载时检查(即使index.html被缓存也可以解决)
    checkVersion();

    // 场景2:页面从后台切回时检查
    const handleVisibilityChange = () => {
      if (document.visibilityState === 'visible') {
        checkVersion();
      }
    };

    document.addEventListener('visibilitychange', handleVisibilityChange);

    // 场景3(可选):定时轮询(每小时一次)
    const interval = setInterval(checkVersion, 3600000);

    return () => {
      document.removeEventListener('visibilitychange', handleVisibilityChange);
      clearInterval(interval);
    };
  }, []);
};

export default useCheckVersion;

这样在我们发布新版本时就可以解决大部分缓存问题,但是还是做不到实时更新,除非后端介入

相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄4 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端