从Vite 4.5.0升级到5.0.0后Hot Reload失效求助
Vite 5.0.0升级后React TS项目热重载失效(全页面刷新替代热重载)
升级Vite从4.5.0到5.0.0后,React TS项目出现热重载异常:修改任意文件保存后,触发的是全页面刷新而非热重载。推测问题源于项目中的循环导入,但Vite 4.5.0版本下该问题不影响热重载。以下是恢复热重载功能的解决方案:
复现步骤
- 通过
yarn vite --mode development启动项目 - 修改任意文件并保存
- 预期触发热重载,实际执行全页面刷新
项目配置(vite.config.ts)
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import viteTsconfigPaths from 'vite-tsconfig-paths'; import eslint from 'vite-plugin-eslint'; import * as path from 'path'; import { readFileSync } from 'fs'; import { read, utils } from 'xlsx'; export default defineConfig({ appType: 'spa', base: '/', assetsInclude: ['**/*.xlsx'], plugins: [ react({ include: '**/*.tsx', }), eslint(), viteTsconfigPaths(), { name: 'vite-sheet', transform(code, id) { if (!id.match(/\?sheetjs$/)) return; const wb = read(readFileSync(id.replace(/\?sheetjs$/, ''))); const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); return `export default JSON.parse('${JSON.stringify(data)}')`; }, }, ], server: { open: true, port: 3000, hmr: true, watch: { usePolling: true, }, }, resolve: { alias: [ { find: /^moment$/, replacement: path.resolve(__dirname, './alias.js'), }, { find: /^gc-dv$/, replacement: path.resolve( __dirname, './node_modules/@grapecity/activereports/lib/node_modules/gc-dv.js' ), }, { find: /^@grapecity\/ar-js-pagereport$/, replacement: path.resolve( __dirname, './node_modules/@grapecity/activereports/lib/node_modules/@grapecity/ar-js-pagereport.js' ), }, { find: /^barcodejs$/, replacement: path.resolve( __dirname, './node_modules/@grapecity/activereports/lib/node_modules/barcodejs.js' ), }, ], }, });
系统信息
System: OS: macOS 14.1.1 CPU: (10) arm64 Apple M2 Pro Memory: 249.61 MB / 16.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 20.4.0 - ~/.nvm/versions/node/v20.4.0/bin/node Yarn: 1.22.19 - /usr/local/bin/yarn npm: 9.7.2 - ~/.nvm/versions/node/v20.4.0/bin/npm Watchman: 2023.10.09.00 - /opt/homebrew/bin/watchman Browsers: Chrome: 119.0.6045.159 Edge: 119.0.2151.72 Safari: 17.1 npmPackages: @vitejs/plugin-react: 4.2.0 => 4.2.0 vite: 5.0.0 => 5.0.0
解决方案
1. 排查并修复循环导入
Vite 5对模块依赖的处理更严格,循环导入会导致HMR无法精准更新模块,进而触发全页刷新。
- 启动项目时查看终端日志,HMR失败通常会输出
[vite:hmr] Failed to update modules并标注关联文件 - 用TypeScript编辑器工具(如VS Code)检测循环依赖,或运行
tsc --noEmit查看相关警告 - 重构代码消除循环:提取公共逻辑到独立模块,或用
import()动态导入延迟加载依赖,打破循环链
2. 修复自定义插件的HMR支持
你的vite-sheet自定义插件未处理HMR逻辑,导致xlsx文件更新时触发全页刷新。添加handleHotUpdate钩子:
{ name: 'vite-sheet', transform(code, id) { if (!id.match(/\?sheetjs$/)) return; const wb = read(readFileSync(id.replace(/\?sheetjs$/, ''))); const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); return `export default JSON.parse('${JSON.stringify(data)}')`; }, async handleHotUpdate(ctx) { // 监听xlsx文件变化,更新关联的?sheetjs模块 if (ctx.file.match(/\.xlsx$/)) { const targetModules = ctx.modules.filter(module => module.id?.includes('?sheetjs') ); if (targetModules.length) { ctx.server.ws.send({ type: 'update', updates: targetModules.map(module => ({ type: 'js-update', path: module.url, acceptedPath: module.url, })) }); return []; // 阻止默认全页刷新逻辑 } } } }
3. 调整React插件配置
确保React插件覆盖所有需要热更新的文件,并使用Vite 5推荐的配置:
react({ include: ['**/*.tsx', '**/*.ts'], // 加入.ts文件,避免遗漏逻辑模块 jsxImportSource: 'react', })
4. 关闭不必要的文件轮询
macOS下Watchman已能正常监听文件变化,开启usePolling可能干扰HMR:
server: { watch: { usePolling: false, }, }
5. 清理缓存并重装依赖
- 删除
node_modules、yarn.lock - 运行
yarn install重新安装依赖 - 启动项目时添加
--force参数清理Vite缓存:yarn vite --mode development --force
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

