返回

Vite 中因 `main.js` 脚本加载失败导致白屏如何解决?

vue.js

解决 Vite 中因 main.js 脚本加载失败导致的白屏问题

问题概述

在使用 Vite 或 Rollup 等现代 Web 打包器时,可能会遇到一个令人沮丧的问题:如果 main.js 脚本加载失败,网站将无法加载并停留在空白的 index.html 文档中。直到手动刷新页面,网站才能重新加载并恢复正常。

问题分析

这个白屏问题的根源在于 Vite 在构建过程中为每个 js 块、资源和 main.js 文件添加了一个哈希值。这是为了让客户端知道文件已更改,需要下载新文件。在 Vue 应用的路由器中,有一个处理程序会在加载动态模块时检查哈希值,如果发现哈希值已更改,就会刷新页面。

但是,如果 main.js 文件的哈希值发生更改,网站将无法加载 Vue 路由器,因此也就无法通过这个错误处理程序来刷新页面。导致网站陷入白屏状态,直到手动刷新才能恢复正常。

解决方案

要解决这个问题,一种有效的解决方案是在 HTML 文件中为 main.js 脚本添加一个错误处理程序。具体来说,可以为 <script> 标签添加一个 onerror 属性,并在 onMainScriptLoadingError 函数中根据 localStorage 中存储的值重载页面。这样,既可以重新加载页面并下载新的 index.html(带有新的 main.js 哈希值),又能避免无限刷新循环。

代码示例:

<script src="main.js" onerror="onMainScriptLoadingError()"></script>
function onMainScriptLoadingError() {
  const storedHash = localStorage.getItem("mainScriptHash");
  const newHash = calculateNewHash();

  // 如果新的哈希值与存储的哈希值不同,则重新加载页面
  if (newHash !== storedHash) {
    localStorage.setItem("mainScriptHash", newHash);
    window.location.reload();
  }
}

其他建议

除了使用错误处理程序外,还可以采取其他一些措施来缓解 main.js 加载失败带来的问题:

  • main.js 脚本作为异步模块加载,而不是同步模块。
  • main.js 脚本拆分成更小的模块,这样加载失败时影响范围更小。
  • onMainScriptLoadingError 函数中设置一个计时器,以避免在短时间内重复刷新页面。

结论

虽然在 Vite 或 Rollup 文档中没有明确提及此解决方案,但它是解决 main.js 加载失败导致的白屏问题的有效方法。通过添加一个错误处理程序,网站可以优雅地处理加载错误,并确保在哈希值更改后也能正常加载。

常见问题解答

1. 为什么 main.js 脚本的加载失败会导致白屏?

答:因为 Vue 路由器无法加载,从而导致网站无法正常工作。

2. 如何添加错误处理程序来解决这个问题?

答:可以在 <script> 标签中添加一个 onerror 属性,并在 onMainScriptLoadingError 函数中根据 localStorage 中存储的值重载页面。

3. 还有其他方法可以解决这个问题吗?

答:除了使用错误处理程序外,还可以将 main.js 脚本作为异步模块加载,或者将它拆分成更小的模块。

4. 如果错误处理程序不起作用怎么办?

答:可以检查 onMainScriptLoadingError 函数是否正确执行,并确保新的哈希值与存储的哈希值确实不同。

5. 如何防止这个问题再次发生?

答:可以通过使用可靠的网络连接、避免使用缓存过期的文件以及监控网站的性能来减少 main.js 脚本加载失败的可能性。