Vite中用glob导入组件后热更新不生效怎么办?

上官瑞瑞 阅读 18

大家好,我在用Vite开发Vue组件时遇到个奇怪的问题。按照文档用glob导入所有组件后,修改组件内容保存时页面没变化,只能手动刷新才生效。

代码是这样写的:


import { createApp } from 'vue'
const components = import.meta.glob('../components/*.vue')
createApp(App).use(components => {
  Object.entries(components).forEach(([path, comp]) => {
    app.component(path.split('/').pop(), comp())
  })
})

我试过清除node_modules重装、调整vite.config.js配置,甚至把动态导入改成静态导入就正常了。但项目需要动态注册大量组件,必须用glob方式。控制台没有报错,就是HMR完全失效,求大佬指点!

我来解答 赞 6 收藏
二维码
手机扫码查看
2 条解答
司马玉卿
动态导入的组件需要在回调里处理,直接调用comp()会导致HMR失效。改成这样应该能用:

import { createApp } from 'vue'
const components = import.meta.glob('../components/*.vue')
createApp(App).use(components => {
Object.entries(components).forEach(([path, comp]) => {
comp().then(module => {
app.component(path.split('/').pop(), module.default)
})
})
})


记得把vite.config.js里的hmr配置检查一下,确保没被禁用。昨晚调试到三点才发现是这个坑,累死了。
点赞
2026-02-20 00:19
Top丶玉灿
我之前也碰到过这问题,Vite的HMR在动态注册组件时确实会抽风。问题出在组件注册方式上,你试试这样改:

import { createApp } from 'vue'
const app = createApp(App)

const components = import.meta.glob('../components/*.vue', { eager: true })
Object.entries(components).forEach(([path, comp]) => {
app.component(path.split('/').pop().replace('.vue', ''), comp.default)
})


你少了个eager参数,而且组件注册的时候需要使用.default。另外确保你的组件都正确导出了name属性

如果还是不行,可以试试在vite.config.js里加个配置:
export default defineConfig({
server: {
hmr: {
overlay: false
}
}
})


对了,记得每次修改完组件要保存两次,第一次是触发编译,第二次才会真正更新。这算是Vite的一个小bug吧,动态导入的组件确实不如静态导入响应及时。如果实在解决不了,可以考虑用require.context替代import.meta.glob
点赞 11
2026-02-06 16:06