支持 WebAssembly (Wasm)
上次更新时间:2024 年 3 月 13 日
Flutter 和 Dart 团队很高兴在为 Web 构建应用程序时添加 WebAssembly 作为编译目标。
Dart 和 Flutter 的 WebAssembly 支持开发仍在进行中,这可能会导致频繁的更改。请访问此页面以获取最新更新。
背景
要运行已编译为 Wasm 的 Flutter 应用,您需要一个支持 WasmGC 的浏览器。Wasm 标准计划添加 WasmGC,以帮助像 Dart 这样的垃圾回收语言以高效的方式执行代码。
Chromium 和 V8 在 Chromium 119 中发布了对 WasmGC 的稳定支持。请注意,iOS 上的 Chrome 使用 WebKit,它尚未 支持 WasmGC。Firefox 宣布在 Firefox 120 中稳定支持 WasmGC,但目前由于 已知限制 而无法正常工作。
试用
要试用使用 Wasm 的预构建 Flutter Web 应用,请查看 Material 3 WasmGC 预览演示。
要在自己的应用中体验 Wasm,请执行以下步骤。
切换到 Flutter beta
频道并升级
Wasm 编译可在 beta
频道(首选)或 main
的最新版本上使用。
如需详细了解 Flutter 版本发布频道以及如何切换到 beta
频道,请查看 Flutter wiki。
然后,为确保您运行的是最新版本,请运行 flutter upgrade
。
要验证您的 Flutter 安装是否支持 Wasm,请运行 flutter build web --help
。
在输出的底部,您应该会找到实验性 Wasm 选项,例如
Experimental options
--wasm Compile to WebAssembly rather than JavaScript.
See https://fluttercn.cn/wasm for more information.
--[no-]strip-wasm Whether to strip the resulting wasm file of static symbol names.
(defaults to on)
选择一个(简单的)Flutter Web 应用程序
尝试默认模板 示例应用,或选择任何已迁移为 兼容 Wasm 的 Flutter 应用程序。
修改 index.html
在使用 Wasm 构建之前,您需要修改应用的 web/index.html
文件中的引导逻辑。
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Flutter web app</title>
<script src="flutter.js"></script>
</head>
<body>
<script>
{{flutter_build_config}}
_flutter.loader.load();
</script>
</body>
</html>
此功能正在开发中。当前语法 (flutter.js
、{{flutter_build_config}}
、_flutter.loader.load()
) 是 beta
和 main
频道中的临时解决方案,但将在即将发布的稳定版本中替换为实际语法。敬请期待!
运行 flutter build web --wasm
要使用 Wasm 构建 Web 应用程序,请将 --wasm
标志添加到现有的 flutter build web
命令中。
flutter build web --wasm
该命令会将输出发送到相对于包根目录的 build/web
目录。
使用 HTTP 服务器在本地提供输出
如果您尚未安装本地 HTTP 服务器,可以使用 dhttpd
软件包
flutter pub global activate dhttpd
然后切换到 build/web
目录并使用特殊标头运行服务器
$ cd build/web
$ dhttpd '--headers=Cross-Origin-Embedder-Policy=credentialless;Cross-Origin-Opener-Policy=same-origin'
Server started on port 8080
在浏览器中加载
截至 2024 年 3 月 13 日,只有基于 Chromium 的浏览器(版本 119 或更高版本)才能运行 Flutter/Wasm 内容。
如果已配置的浏览器符合要求,请在浏览器中打开 localhost:8080
以查看应用。
如果应用程序未加载
- 查看开发者控制台中的错误。
- 使用典型的 JavaScript 输出验证成功构建。
已知限制
Wasm 支持目前存在一些限制。以下列表涵盖了一些常见问题。
Chrome 119 或更高版本
如 在浏览器中加载中所述,要运行已编译为 Wasm 的 Flutter Web 应用,请使用Chrome 119 或更高版本。
一些早期版本支持启用特定标志的 WasmGC,但一旦该功能稳定,WasmGC 编码就会发生变化。为了确保兼容性,请运行最新版本的 Flutter main
频道和最新版本的 Chrome。
- 为什么不用 Firefox?Firefox 版本 120 及更高版本以前能够运行 Flutter/Wasm,但它们目前遇到一个错误,阻止了与 Wasm 的兼容性。
- 为什么不用 Safari?Safari 还不支持 WasmGC;此错误跟踪了他们的实现工作。
需要 JS 互操作才能访问浏览器和 JS API
为了支持编译为 Wasm,Dart 已改变它启用与浏览器和 JavaScript API 的互操作的方式。这种改变阻止了使用 dart:html
或 package:js
的 Dart 代码编译为 Wasm。
相反,Dart 现在提供了围绕静态 JS 互操作构建的新型轻量级互操作解决方案
-
package:web
,它取代了dart:html
(以及其他 Web 库) -
dart:js_interop
,它取代了package:js
和dart:js
Dart 和 Flutter 团队拥有的大多数软件包已迁移为与 Flutter 中的 Wasm 支持兼容,例如 package:url_launcher
。要了解如何将软件包和应用程序迁移到新解决方案,请查看 JS 互操作文档和 package:web
迁移指南。
要检查 Wasm 构建是否因 API 不兼容而失败,请查看错误输出。这些错误通常在构建调用后立即返回。与 API 相关的错误应类似于以下内容
Target dart2wasm failed: Exception: ../../../../.pub-cache/hosted/pub.dev/url_launcher_web-2.0.16/lib/url_launcher_web.dart:6:8: Error: Dart library 'dart:html' is not available on this platform.
import 'dart:html' as html;
^
Context: The unavailable library 'dart:html' is imported through these packages:
web_plugin_registrant.dart => package:url_launcher_web => dart:html
web_plugin_registrant.dart => package:url_launcher_web => package:flutter_web_plugins => dart:html
web_plugin_registrant.dart => package:flutter_web_plugins => dart:html
仅构建支持
目前,flutter run
和 DevTools 均不支持 Wasm。
了解更多信息
查看 Flutter 的 现有 Web 支持。Flutter 和 Dart Wasm 支持的工作仍在继续。完成后,现有的 Flutter Web 应用程序无需太多工作即可支持 Wasm。
如果您想了解更多信息,请观看我们团队在 Wasm I/O 2023 上的演讲:Flutter、Dart 和 WasmGC:Web 应用程序的新模型。
要关注 Flutter 和 Dart WebAssembly 工作的最新变化,请重新访问 flutter.dev/wasm。