Skip to content

Flutter Web 替换 serviceWorkerVersion 模板标记

问题描述

当在 Flutter Web 应用中运行项目时,控制台可能显示以下警告信息:

bash
Warning: In index.html:60: Local variable for "serviceWorkerVersion" is deprecated. 
Use "{{flutter_service_worker_version}}" template token instead.

此问题源于 Flutter 框架升级后,传统的 index.htmlserviceWorkerVersion 变量的使用方式已被弃用。原始 index.html 中通常包含类似的 JavaScript 代码:

js
var serviceWorkerVersion = null;
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;

随着 Flutter 更新(特别是 3.22+ 版本),项目需要使用 {{flutter_service_worker_version}} 模板标记取代变量,否则将导致兼容性问题和警告提示。

解决方法

方法一:直接替换变量(快速修复)

适用于希望最小化改动的项目:

  1. 打开 web/index.html 文件
  2. 找到 serviceWorkerVersion 声明行
  3. 修改为使用模板标记:
diff
- var serviceWorkerVersion = null;
+ var serviceWorkerVersion = '{{flutter_service_worker_version}}';
  1. 在后续使用该变量的地方保持原逻辑不变

注意:此方法只是临时解决方案,未来可能仍需更新初始化逻辑

方法二:更新至 Flutter 3.22+ 推荐方式(推荐)

从 Flutter 3.22 开始引入新的初始化流程:

html
<!DOCTYPE html>
<html>
<head>
  <base href="$FLUTTER_BASE_HREF">
  <!-- 元数据保持不变 -->
  <link rel="manifest" href="manifest.json">
  
  <!-- 关键变更:使用新版加载脚本 -->
  <script>
    window.addEventListener('load', function() {
      _flutter.loader.load({
        onEntrypointLoaded: async function(engineInitializer) {
          const appRunner = await engineInitializer.initializeEngine();
          await appRunner.runApp();
        }
      });
    });
  </script>
</head>
<body>
  <!-- 移除旧版脚本,添加加载指示器(可选) -->
  <div id="loading-indicator"></div>
  
  <!-- 自动注入的Flutter引导脚本 -->
  {% raw %} {{flutter_js}} {% endraw %}
  <script src="flutter_bootstrap.js" async></script>
</body>
</html>

重要变更点

  1. 移除所有手动 Service Worker 逻辑
  2. 使用 _flutter.loader.load() API
  3. 添加 flutter_bootstrap.js 异步加载
  4. 通过 {{flutter_service_worker_version}} 自动注入版本号

方法三:重新生成 web 目录

适用于无自定义配置的项目:

bash
# 备份现有 web 目录
cp -r web web_backup

# 重新生成 web 目录
flutter create . --platforms=web

警告:此操作会覆盖 web 目录下的所有文件,恢复后需:

  1. 从备份恢复自定义文件(如图标、额外脚本等)
  2. 重新配置 manifest.json 等特殊文件

版本升级注意事项

  1. Flutter 3.22+ 要求:新初始化方式需要 Flutter ≥3.22
  2. 渲染引擎选择:可在 initializeEngine() 中指定渲染引擎
js
initializeEngine({renderer: "html"}); // 可选值 html/canvaskit
  1. 构建验证:修改后运行命令检查是否消除警告
bash
flutter build web

项目示例(Flutter 3.22+标准模板)

html
<!DOCTYPE html>
<html>
<head>
  <base href="$FLUTTER_BASE_HREF">
  <meta charset="UTF-8">
  <!-- 其他head内容保持不变 -->
  
  <script>
    window.addEventListener('load', function() {
      let loader = document.getElementById('loading-indicator');
      _flutter.loader.load({
        onEntrypointLoaded: async (engine) => {
          const app = await engine.initializeEngine();
          await app.runApp();
          loader.remove(); // 移除加载指示器
        }
      });
    });
  </script>
</head>
<body>
  <div id="loading-indicator">Loading...</div>
  <script src="flutter_bootstrap.js"></script>
</body>
</html>

总结

方法适用场景升级完整性
变量替换紧急修复旧项目✗ 部分更新
新初始化方式升级Flutter 3.22+✓ 完整适配
重建web目录无自定义配置项目✓ 完整更新

推荐方案:对长期维护的项目,应采用方法二更新至新版初始化流程,这不仅能解决当前警告,也为后续 Flutter Web 功能更新奠定基础。同时建议查看官方最新文档 Flutter Web 初始化指南