Vue2+Vite+VitePWA部署Firebase后每次构建出现浏览器模块加载错误
解决Firebase部署Vite应用后出现的MIME类型错误
错误信息
加载模块脚本失败:预期为JavaScript模块脚本,但服务器返回的MIME类型为"text/html"。根据HTML规范,模块脚本强制执行严格的MIME类型检查。
问题场景
每次执行npm run build并firebase deploy后都会触发该错误,清除浏览器缓存后页面恢复正常,直到下一次构建部署。
问题根源
这个错误本质是旧缓存的资源请求被Firebase的重写规则导向了index.html:
- Vite确实会给打包后的静态资源(如
assets/xxx.hash.js)添加哈希实现缓存破击,但它无法控制index.html的浏览器缓存。 - 如果用户浏览器缓存了旧版
index.html,里面引用的是旧的资源路径(无哈希或旧哈希),部署新包后这些旧路径的资源已不存在,Firebase的"source": "**"重写规则会把所有找不到的请求都返回index.html,导致JS模块请求拿到的是HTML文件,触发MIME类型不匹配错误。
解决方案
1. 配置Firebase Hosting缓存规则,控制index.html的缓存行为
修改firebase.json,添加headers配置,确保index.html不被缓存,同时给带哈希的静态资源设置永久缓存:
{ "hosting": { "public": "dist", "ignore": [], "rewrites": [ { "source": "**", "destination": "/index.html" } ], "headers": [ { "source": "/index.html", "headers": [ { "key": "Cache-Control", "value": "no-cache, no-store, must-revalidate" } ] }, { "source": "/assets/**", "headers": [ { "key": "Cache-Control", "value": "public, max-age=31536000, immutable" } ] } ] } }
index.html设置强缓存禁止,确保用户每次访问都能拉取最新版本,从而加载最新的带哈希资源。assets/**下的资源设置永久缓存,因为哈希值变化代表资源更新,不会出现缓存冲突。
2. 确认Vite打包配置的哈希生成正常
Vite默认已开启静态资源哈希,但可以检查vite.config.js确保没有意外修改:
export default defineConfig({ build: { assetsDir: 'assets', rollupOptions: { output: { assetFileNames: 'assets/[name]-[hash].[ext]', chunkFileNames: 'assets/[name]-[hash].js', entryFileNames: 'assets/[name]-[hash].js' } } } })
如果配置被修改导致哈希失效,会让缓存破击机制不起作用。
3. 部署时同步缓存配置
执行部署命令即可让新的缓存规则生效:
firebase deploy --only hosting
配置生效后,无需每次手动刷新Firebase缓存,浏览器会自动遵循缓存规则拉取最新资源。
对疑问的解答
Vite的自动缓存破击只针对带哈希的静态资源,无法控制index.html的缓存。旧的index.html缓存会导致浏览器请求旧的资源路径,触发Firebase的重写规则返回HTML,这就是清缓存能解决问题的原因。通过给index.html配置禁止缓存的规则,就能彻底避免这个问题。
内容的提问来源于stack exchange,提问作者ToniLu
相关产品推荐
相关产品推荐

